refactor: massively improve nameplate performance

This commit is contained in:
Anna 2021-09-24 14:23:50 -04:00
parent 6158effc5d
commit b6e027113e
1 changed files with 74 additions and 2 deletions

View File

@ -61,8 +61,65 @@ namespace NominaOcculta {
}
private void OnNamePlateUpdate(NamePlateUpdateEventArgs args) {
this.ChangeNames(args.Name);
this.ChangeNames(args.Title); // for minions
// only replace nameplates that have objects in the table
if (!this.Plugin.Config.Enabled || args.ObjectId == 0xE0000000) {
return;
}
// find the object this nameplate references
var obj = this.Plugin.ObjectTable.FirstOrDefault(o => o.ObjectId == args.ObjectId);
if (obj == null) {
return;
}
// handle owners
if (obj.OwnerId != 0xE0000000) {
if (this.Plugin.ObjectTable.FirstOrDefault(o => o.ObjectId == obj.OwnerId) is not { } owner) {
return;
}
obj = owner;
}
// only work for characters
if (obj.ObjectKind != ObjectKind.Player || obj is not Character chara) {
return;
}
var info = GetInfo(chara);
void Change(string name) {
this.ChangeName(args.Name, name, info);
this.ChangeName(args.Title, name, info);
}
var name = chara.Name.TextValue;
var playerId = this.Plugin.ClientState.LocalPlayer?.ObjectId;
var party = this.Plugin.PartyList.Select(member => member.ObjectId).ToArray();
if ((this.Plugin.Config.SelfFull || this.Plugin.Config.SelfFirst || this.Plugin.Config.SelfLast) && chara.ObjectId == playerId) {
if (this.Plugin.Config.SelfFull) {
Change(name);
}
if ((this.Plugin.Config.SelfFirst || this.Plugin.Config.SelfLast) && this.Plugin.NameRepository.GetReplacement(name, info) is { } replacement) {
var parts = name.Split(' ', 2);
var replacementParts = replacement.Split(' ', 2);
if (this.Plugin.Config.SelfFirst) {
args.Name.ReplacePlayerName(parts[0], replacementParts[0]);
args.Title.ReplacePlayerName(parts[0], replacementParts[0]);
}
if (this.Plugin.Config.SelfLast) {
args.Name.ReplacePlayerName(parts[1], replacementParts[1]);
args.Title.ReplacePlayerName(parts[1], replacementParts[1]);
}
}
} else if (this.Plugin.Config.Party && party.Contains(chara.ObjectId) && (!this.Plugin.Config.ExcludeFriends || !this.Friends.Contains(name))) {
Change(name);
} else if (this.Plugin.Config.Others && chara.ObjectId != playerId && !party.Contains(chara.ObjectId) && (!this.Plugin.Config.ExcludeFriends || !this.Friends.Contains(name))) {
Change(chara.Name.TextValue);
}
}
private void OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled) {
@ -70,6 +127,21 @@ namespace NominaOcculta {
this.ChangeNames(message);
}
private void ChangeName(SeString text, string name, (byte, byte, byte) info) {
if (this.Plugin.NameRepository.GetReplacement(name, info) is not { } replacement) {
return;
}
if (!text.ContainsPlayerName(name)) {
return;
}
text.ReplacePlayerName(name, replacement);
}
// PERFORMANCE NOTE: This potentially loops over the party list twice and the object
// table once entirely. Should be avoided if being used in a
// position where the player to replace is known.
private bool ChangeNames(SeString text) {
if (!this.Plugin.Config.Enabled || !this.Plugin.NameRepository.Initialised) {
return false;