feat: use configured colours for chunks
This commit is contained in:
parent
6007f09167
commit
1c3eb05621
|
@ -101,6 +101,222 @@ namespace XIVChatCommon {
|
|||
this.code = code;
|
||||
}
|
||||
|
||||
public ChatType Parent() {
|
||||
switch (this.Type) {
|
||||
case ChatType.Say:
|
||||
case ChatType.GmSay:
|
||||
return ChatType.Say;
|
||||
case ChatType.Shout:
|
||||
case ChatType.GmShout:
|
||||
return ChatType.Shout;
|
||||
case ChatType.TellOutgoing:
|
||||
case ChatType.TellIncoming:
|
||||
case ChatType.GmTell:
|
||||
return ChatType.TellOutgoing;
|
||||
case ChatType.Party:
|
||||
case ChatType.CrossParty:
|
||||
case ChatType.GmParty:
|
||||
return ChatType.Party;
|
||||
case ChatType.Linkshell1:
|
||||
case ChatType.GmLinkshell1:
|
||||
return ChatType.Linkshell1;
|
||||
case ChatType.Linkshell2:
|
||||
case ChatType.GmLinkshell2:
|
||||
return ChatType.Linkshell2;
|
||||
case ChatType.Linkshell3:
|
||||
case ChatType.GmLinkshell3:
|
||||
return ChatType.Linkshell3;
|
||||
case ChatType.Linkshell4:
|
||||
case ChatType.GmLinkshell4:
|
||||
return ChatType.Linkshell4;
|
||||
case ChatType.Linkshell5:
|
||||
case ChatType.GmLinkshell5:
|
||||
return ChatType.Linkshell5;
|
||||
case ChatType.Linkshell6:
|
||||
case ChatType.GmLinkshell6:
|
||||
return ChatType.Linkshell6;
|
||||
case ChatType.Linkshell7:
|
||||
case ChatType.GmLinkshell7:
|
||||
return ChatType.Linkshell7;
|
||||
case ChatType.Linkshell8:
|
||||
case ChatType.GmLinkshell8:
|
||||
return ChatType.Linkshell8;
|
||||
case ChatType.FreeCompany:
|
||||
case ChatType.GmFreeCompany:
|
||||
return ChatType.FreeCompany;
|
||||
case ChatType.NoviceNetwork:
|
||||
case ChatType.GmNoviceNetwork:
|
||||
return ChatType.NoviceNetwork;
|
||||
case ChatType.CustomEmote:
|
||||
return ChatType.CustomEmote;
|
||||
case ChatType.StandardEmote:
|
||||
return ChatType.StandardEmote;
|
||||
case ChatType.Yell:
|
||||
case ChatType.GmYell:
|
||||
return ChatType.Yell;
|
||||
case ChatType.GainBuff:
|
||||
case ChatType.LoseBuff:
|
||||
return ChatType.GainBuff;
|
||||
case ChatType.GainDebuff:
|
||||
case ChatType.LoseDebuff:
|
||||
return ChatType.GainDebuff;
|
||||
case ChatType.System:
|
||||
case ChatType.Alarm:
|
||||
case ChatType.RetainerSale:
|
||||
case ChatType.PeriodicRecruitmentNotification:
|
||||
case ChatType.Sign:
|
||||
case ChatType.Orchestrion:
|
||||
case ChatType.MessageBook:
|
||||
return ChatType.System;
|
||||
case ChatType.NpcDialogue:
|
||||
case ChatType.NpcAnnouncement:
|
||||
return ChatType.NpcDialogue;
|
||||
case ChatType.LootRoll:
|
||||
case ChatType.RandomNumber:
|
||||
return ChatType.LootRoll;
|
||||
case ChatType.FreeCompanyAnnouncement:
|
||||
case ChatType.FreeCompanyLoginLogout:
|
||||
return ChatType.FreeCompanyAnnouncement;
|
||||
case ChatType.PvpTeamAnnouncement:
|
||||
case ChatType.PvpTeamLoginLogout:
|
||||
return ChatType.PvpTeamAnnouncement;
|
||||
default:
|
||||
return this.Type;
|
||||
}
|
||||
}
|
||||
|
||||
//public string ConfigKey() {
|
||||
// switch (this.Type) {
|
||||
// case ChatType.Say:
|
||||
// case ChatType.GmSay:
|
||||
// return "ColorSay";
|
||||
// case ChatType.Shout:
|
||||
// case ChatType.GmShout:
|
||||
// return "ColorShout";
|
||||
// case ChatType.TellOutgoing:
|
||||
// case ChatType.TellIncoming:
|
||||
// case ChatType.GmTell:
|
||||
// return "ColorTell";
|
||||
// case ChatType.Party:
|
||||
// case ChatType.CrossParty:
|
||||
// case ChatType.GmParty:
|
||||
// return "ColorParty";
|
||||
// case ChatType.Alliance:
|
||||
// return "ColorAlliance";
|
||||
// case ChatType.Linkshell1:
|
||||
// case ChatType.GmLinkshell1:
|
||||
// return "ColorLS1";
|
||||
// case ChatType.Linkshell2:
|
||||
// case ChatType.GmLinkshell2:
|
||||
// return "ColorLS2";
|
||||
// case ChatType.Linkshell3:
|
||||
// case ChatType.GmLinkshell3:
|
||||
// return "ColorLS3";
|
||||
// case ChatType.Linkshell4:
|
||||
// case ChatType.GmLinkshell4:
|
||||
// return "ColorLS4";
|
||||
// case ChatType.Linkshell5:
|
||||
// case ChatType.GmLinkshell5:
|
||||
// return "ColorLS5";
|
||||
// case ChatType.Linkshell6:
|
||||
// case ChatType.GmLinkshell6:
|
||||
// return "ColorLS6";
|
||||
// case ChatType.Linkshell7:
|
||||
// case ChatType.GmLinkshell7:
|
||||
// return "ColorLS7";
|
||||
// case ChatType.Linkshell8:
|
||||
// case ChatType.GmLinkshell8:
|
||||
// return "ColorLS8";
|
||||
// case ChatType.FreeCompany:
|
||||
// case ChatType.GmFreeCompany:
|
||||
// return "ColorFCompany";
|
||||
// case ChatType.NoviceNetwork:
|
||||
// case ChatType.GmNoviceNetwork:
|
||||
// return "ColorBeginner";
|
||||
// case ChatType.CustomEmote:
|
||||
// return "ColorEmoteUser";
|
||||
// case ChatType.StandardEmote:
|
||||
// return "ColorEmote";
|
||||
// case ChatType.Yell:
|
||||
// case ChatType.GmYell:
|
||||
// return "ColorYell";
|
||||
// case ChatType.PvpTeam:
|
||||
// return "ColorPvPGroup";
|
||||
// case ChatType.CrossLinkshell1:
|
||||
// return "ColorCWLS";
|
||||
// case ChatType.Damage:
|
||||
// return "ColorAttackSuccess";
|
||||
// case ChatType.Miss:
|
||||
// return "ColorAttackFailure";
|
||||
// case ChatType.Action:
|
||||
// return "ColorAction";
|
||||
// case ChatType.Item:
|
||||
// return "ColorItem";
|
||||
// case ChatType.Healing:
|
||||
// return "ColorCureGive";
|
||||
// case ChatType.GainBuff:
|
||||
// case ChatType.GainDebuff:
|
||||
// return "ColorBuffGive";
|
||||
// case ChatType.LoseBuff:
|
||||
// case ChatType.LoseDebuff:
|
||||
// return "ColorDebuffGive";
|
||||
// case ChatType.Echo:
|
||||
// return "ColorEcho";
|
||||
// case ChatType.System:
|
||||
// case ChatType.Alarm:
|
||||
// case ChatType.RetainerSale:
|
||||
// case ChatType.PeriodicRecruitmentNotification:
|
||||
// case ChatType.Sign:
|
||||
// case ChatType.Orchestrion:
|
||||
// case ChatType.MessageBook:
|
||||
// return "ColorSysMsg";
|
||||
// case ChatType.BattleSystem:
|
||||
// return "ColorSysBattle";
|
||||
// case ChatType.GatheringSystem:
|
||||
// return "ColorSysGathering";
|
||||
// case ChatType.Error:
|
||||
// return "ColorSysError";
|
||||
// case ChatType.NpcDialogue:
|
||||
// case ChatType.NpcAnnouncement:
|
||||
// return "ColorNpcSay";
|
||||
// case ChatType.LootNotice:
|
||||
// return "ColorItemNotice";
|
||||
// case ChatType.Progress:
|
||||
// return "ColorGrowup";
|
||||
// case ChatType.LootRoll:
|
||||
// case ChatType.RandomNumber:
|
||||
// return "ColorLoot";
|
||||
// case ChatType.Crafting:
|
||||
// return "ColorCraft";
|
||||
// case ChatType.Gathering:
|
||||
// return "ColorGathering";
|
||||
// case ChatType.FreeCompanyAnnouncement:
|
||||
// case ChatType.FreeCompanyLoginLogout:
|
||||
// return "ColorFCAnnounce";
|
||||
// case ChatType.NoviceNetworkSystem:
|
||||
// return "ColorBeginnerAnnounce";
|
||||
// case ChatType.PvpTeamAnnouncement:
|
||||
// case ChatType.PvpTeamLoginLogout:
|
||||
// return "ColorPvPGroupAnnounce";
|
||||
// case ChatType.CrossLinkshell2:
|
||||
// return "ColorCWLS2";
|
||||
// case ChatType.CrossLinkshell3:
|
||||
// return "ColorCWLS3";
|
||||
// case ChatType.CrossLinkshell4:
|
||||
// return "ColorCWLS4";
|
||||
// case ChatType.CrossLinkshell5:
|
||||
// return "ColorCWLS5";
|
||||
// case ChatType.CrossLinkshell6:
|
||||
// return "ColorCWLS6";
|
||||
// case ChatType.CrossLinkshell7:
|
||||
// return "ColorCWLS7";
|
||||
// case ChatType.CrossLinkshell8:
|
||||
// return "ColorCWLS8";
|
||||
// default:
|
||||
// return null;
|
||||
// }
|
||||
//}
|
||||
|
||||
public NameFormatting NameFormat() {
|
||||
switch (this.Type) {
|
||||
case ChatType.Say:
|
||||
|
|
|
@ -17,6 +17,7 @@ namespace XIVChatPlugin {
|
|||
private delegate byte RequestFriendListDelegate(IntPtr manager);
|
||||
private delegate int FormatFriendListNameDelegate(long a1, long a2, long a3, int a4, IntPtr data, long a6);
|
||||
private delegate IntPtr OnReceiveFriendListChunkDelegate(IntPtr a1, IntPtr data);
|
||||
private delegate IntPtr GetColourInfoDelegate(IntPtr handler, uint lookupResult);
|
||||
|
||||
private readonly Hook<RequestFriendListDelegate> friendListHook;
|
||||
private readonly Hook<FormatFriendListNameDelegate> formatHook;
|
||||
|
@ -24,8 +25,11 @@ namespace XIVChatPlugin {
|
|||
|
||||
private readonly GetUIModuleDelegate GetUIModule;
|
||||
private readonly EasierProcessChatBoxDelegate _EasierProcessChatBox;
|
||||
private readonly GetColourInfoDelegate GetColourInfo;
|
||||
|
||||
private readonly IntPtr uiModulePtr;
|
||||
private readonly IntPtr colourHandler;
|
||||
private readonly IntPtr colourLookup;
|
||||
private IntPtr friendListManager = IntPtr.Zero;
|
||||
|
||||
private bool requestingFriendList = false;
|
||||
|
@ -43,10 +47,15 @@ namespace XIVChatPlugin {
|
|||
var friendListPtr = this.plugin.Interface.TargetModuleScanner.ScanText("40 53 48 81 EC 80 0F 00 00 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 48 8B D9 48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 C0 0F 84 ?? ?? ?? ?? 44 0F B6 43 ?? 33 C9");
|
||||
var formatPtr = this.plugin.Interface.TargetModuleScanner.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 41 56 48 83 EC 30 48 8B 6C 24 ??");
|
||||
var recvChunkPtr = this.plugin.Interface.TargetModuleScanner.ScanText("48 89 5C 24 ?? 56 48 83 EC 20 48 8B 0D ?? ?? ?? ?? 48 8B F2");
|
||||
var getColourPtr = this.plugin.Interface.TargetModuleScanner.ScanText("48 89 5C 24 ?? 48 89 6C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 8B F2 48 8D B9 ?? ?? ?? ??");
|
||||
|
||||
this.uiModulePtr = this.plugin.Interface.TargetModuleScanner.GetStaticAddressFromSig("48 8B 0D ?? ?? ?? ?? 48 8D 54 24 ?? 48 83 C1 10 E8 ?? ?? ?? ??");
|
||||
this.colourHandler = this.plugin.Interface.TargetModuleScanner.GetStaticAddressFromSig("48 8B 05 ?? ?? ?? ?? 48 8B A8 ?? ?? ?? ?? 48 85 ED 0F 84 ?? ?? ?? ??");
|
||||
this.colourLookup = this.plugin.Interface.TargetModuleScanner.GetStaticAddressFromSig("48 8D 0D ?? ?? ?? ?? 8B 14 ?? 85 D2 7E ?? 48 8B 0D ?? ?? ?? ?? 48 83 C1 10 E8 ?? ?? ?? ?? 8B 70 ?? 41 8D 4D ??");
|
||||
|
||||
this.GetUIModule = Marshal.GetDelegateForFunctionPointer<GetUIModuleDelegate>(getUIModulePtr);
|
||||
this._EasierProcessChatBox = Marshal.GetDelegateForFunctionPointer<EasierProcessChatBoxDelegate>(easierProcessChatBoxPtr);
|
||||
this.GetColourInfo = Marshal.GetDelegateForFunctionPointer<GetColourInfoDelegate>(getColourPtr);
|
||||
|
||||
this.friendListHook = new Hook<RequestFriendListDelegate>(friendListPtr, new RequestFriendListDelegate(this.OnRequestFriendList));
|
||||
this.formatHook = new Hook<FormatFriendListNameDelegate>(formatPtr, new FormatFriendListNameDelegate(this.OnFormatFriendList));
|
||||
|
@ -57,6 +66,35 @@ namespace XIVChatPlugin {
|
|||
this.receiveChunkHook.Enable();
|
||||
}
|
||||
|
||||
// This function looks up a channel's user-defined colour.
|
||||
//
|
||||
// If this function would ever return 0, it returns null instead.
|
||||
public uint? GetChannelColour(ChatCode channel) {
|
||||
// Colours are retrieved by looking up their code in a lookup table. Some codes share a colour, so they're lumped into a parent code here.
|
||||
// Only codes >= 10 (say) have configurable colours.
|
||||
// After getting the lookup value for the code, it is passed into a function with a handler which returns a pointer.
|
||||
// This pointer + 32 is the RGB value. This functions returns RGBA with A always max.
|
||||
|
||||
var parent = channel.Parent();
|
||||
|
||||
switch (parent) {
|
||||
case ChatType.Debug:
|
||||
case ChatType.Urgent:
|
||||
case ChatType.Notice:
|
||||
return channel.DefaultColour();
|
||||
}
|
||||
|
||||
var lookupResult = (uint)Marshal.ReadInt32(this.colourLookup, (int)parent * 4);
|
||||
var info = this.GetColourInfo(Marshal.ReadIntPtr(this.colourHandler) + 16, lookupResult);
|
||||
var rgb = (uint)Marshal.ReadInt32(info, 32) & 0xFFFFFF;
|
||||
|
||||
if (rgb == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return 0xFF | (rgb << 8);
|
||||
}
|
||||
|
||||
public void ProcessChatBox(string message) {
|
||||
IntPtr uiModule = this.GetUIModule(Marshal.ReadIntPtr(this.uiModulePtr));
|
||||
|
||||
|
|
|
@ -190,24 +190,26 @@ namespace XIVChatPlugin {
|
|||
|
||||
var chunks = new List<Chunk>();
|
||||
|
||||
var colour = this.plugin.Functions.GetChannelColour(chatCode) ?? chatCode.DefaultColour();
|
||||
|
||||
if (sender.Payloads.Count > 0) {
|
||||
// FIXME: can't get format straight from game until Lumina stops returning LogKind.Format as a string (it's an SeString)
|
||||
// var format = this.FormatFor(chatCode.Type);
|
||||
var format = chatCode.NameFormat();
|
||||
if (format != null && format.IsPresent) {
|
||||
chunks.Add(new TextChunk {
|
||||
FallbackColour = chatCode.DefaultColour(),
|
||||
FallbackColour = colour,
|
||||
Content = format.Before,
|
||||
});
|
||||
chunks.AddRange(ToChunks(sender, chatCode.DefaultColour()));
|
||||
chunks.AddRange(ToChunks(sender, colour));
|
||||
chunks.Add(new TextChunk {
|
||||
FallbackColour = chatCode.DefaultColour(),
|
||||
FallbackColour = colour,
|
||||
Content = format.After,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
chunks.AddRange(ToChunks(message, chatCode.DefaultColour()));
|
||||
chunks.AddRange(ToChunks(message, colour));
|
||||
|
||||
var msg = new ServerMessage {
|
||||
Timestamp = DateTime.UtcNow,
|
||||
|
|
Loading…
Reference in New Issue