This commit is contained in:
Haselnussbomber 2026-02-23 21:05:28 +00:00 committed by GitHub
commit 9597d819c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 82 additions and 29 deletions

View file

@ -49,7 +49,7 @@ internal partial class ChatHandlers : IServiceType
[GeneratedRegex(@"(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?", RegexOptions.Compiled)]
private static partial Regex CompiledUrlRegex();
private void OnCheckMessageHandled(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
private void OnCheckMessageHandled(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
{
var textVal = message.TextValue;
@ -63,7 +63,7 @@ internal partial class ChatHandlers : IServiceType
}
}
private void OnChatMessage(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
private void OnChatMessage(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
{
var clientState = Service<ClientState.ClientState>.GetNullable();
if (clientState == null)

View file

@ -44,7 +44,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
private readonly Dictionary<(string PluginName, uint CommandId), Action<uint, SeString>> dalamudLinkHandlers = [];
private readonly List<nint> seenLogMessageObjects = [];
private readonly Hook<PrintMessageDelegate> printMessageHook;
private readonly Hook<RaptureLogModule.Delegates.PrintMessage> printMessageHook;
private readonly Hook<InventoryItem.Delegates.Copy> inventoryItemCopyHook;
private readonly Hook<LogViewer.Delegates.HandleLinkClick> handleLinkClickHook;
private readonly Hook<RaptureLogModule.Delegates.Update> handleLogModuleUpdate;
@ -58,7 +58,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
[ServiceManager.ServiceConstructor]
private ChatGui()
{
this.printMessageHook = Hook<PrintMessageDelegate>.FromAddress(RaptureLogModule.Addresses.PrintMessage.Value, this.HandlePrintMessageDetour);
this.printMessageHook = Hook<RaptureLogModule.Delegates.PrintMessage>.FromAddress(RaptureLogModule.Addresses.PrintMessage.Value, this.HandlePrintMessageDetour);
this.inventoryItemCopyHook = Hook<InventoryItem.Delegates.Copy>.FromAddress((nint)InventoryItem.StaticVirtualTablePointer->Copy, this.InventoryItemCopyDetour);
this.handleLinkClickHook = Hook<LogViewer.Delegates.HandleLinkClick>.FromAddress(LogViewer.Addresses.HandleLinkClick.Value, this.HandleLinkClickDetour);
this.handleLogModuleUpdate = Hook<RaptureLogModule.Delegates.Update>.FromAddress(RaptureLogModule.Addresses.Update.Value, this.UpdateDetour);
@ -69,9 +69,6 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
this.handleLogModuleUpdate.Enable();
}
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
private delegate uint PrintMessageDelegate(RaptureLogModule* manager, XivChatType chatType, Utf8String* sender, Utf8String* message, int timestamp, byte silent);
/// <inheritdoc/>
public event IChatGui.OnMessageDelegate? ChatMessage;
@ -249,11 +246,11 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
this.HandlePrintMessageDetour(
RaptureLogModule.Instance(),
targetChannel,
(ushort)targetChannel,
&sender,
&message,
chat.Timestamp,
(byte)(chat.Silent ? 1 : 0));
chat.Silent);
}
}
@ -373,7 +370,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
}
}
private uint HandlePrintMessageDetour(RaptureLogModule* manager, XivChatType chatType, Utf8String* sender, Utf8String* message, int timestamp, byte silent)
private uint HandlePrintMessageDetour(RaptureLogModule* manager, ushort logInfo, Utf8String* sender, Utf8String* message, int timestamp, bool silent)
{
var messageId = 0u;
@ -385,6 +382,10 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
var terminatedSender = parsedSender.EncodeWithNullTerminator();
var terminatedMessage = parsedMessage.EncodeWithNullTerminator();
var logKind = (XivChatType)(logInfo & 0x7F);
var sourceKind = (XivChatRelationKind)((logInfo >> 11) & 0xF);
var targetKind = (XivChatRelationKind)((logInfo >> 7) & 0xF);
// Call events
var isHandled = false;
@ -392,7 +393,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
{
try
{
action(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
action(logKind, sourceKind, targetKind, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
}
catch (Exception e)
{
@ -406,7 +407,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
{
try
{
action(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
action(logKind, sourceKind, targetKind, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
}
catch (Exception e)
{
@ -434,19 +435,19 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
if (isHandled)
{
foreach (var d in Delegate.EnumerateInvocationList(this.ChatMessageHandled))
d(chatType, timestamp, parsedSender, parsedMessage);
d(logKind, sourceKind, targetKind, timestamp, parsedSender, parsedMessage);
}
else
{
messageId = this.printMessageHook.Original(manager, chatType, sender, message, timestamp, silent);
messageId = this.printMessageHook.Original(manager, logInfo, sender, message, timestamp, silent);
foreach (var d in Delegate.EnumerateInvocationList(this.ChatMessageUnhandled))
d(chatType, timestamp, parsedSender, parsedMessage);
d(logKind, sourceKind, targetKind, timestamp, parsedSender, parsedMessage);
}
}
catch (Exception ex)
{
Log.Error(ex, "Exception on OnChatMessage hook.");
messageId = this.printMessageHook.Original(manager, chatType, sender, message, timestamp, silent);
messageId = this.printMessageHook.Original(manager, logInfo, sender, message, timestamp, silent);
}
return messageId;
@ -653,17 +654,17 @@ internal class ChatGuiPluginScoped : IInternalDisposableService, IChatGui
public void PrintError(ReadOnlySpan<byte> message, string? messageTag = null, ushort? tagColor = null)
=> this.chatGuiService.PrintError(message, messageTag, tagColor);
private void OnMessageForward(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
=> this.ChatMessage?.Invoke(type, timestamp, ref sender, ref message, ref isHandled);
private void OnMessageForward(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
=> this.ChatMessage?.Invoke(type, sourceKind, targetKind, timestamp, ref sender, ref message, ref isHandled);
private void OnCheckMessageForward(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
=> this.CheckMessageHandled?.Invoke(type, timestamp, ref sender, ref message, ref isHandled);
private void OnCheckMessageForward(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
=> this.CheckMessageHandled?.Invoke(type, sourceKind, targetKind, timestamp, ref sender, ref message, ref isHandled);
private void OnMessageHandledForward(XivChatType type, int timestamp, SeString sender, SeString message)
=> this.ChatMessageHandled?.Invoke(type, timestamp, sender, message);
private void OnMessageHandledForward(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, SeString sender, SeString message)
=> this.ChatMessageHandled?.Invoke(type, sourceKind, targetKind, timestamp, sender, message);
private void OnMessageUnhandledForward(XivChatType type, int timestamp, SeString sender, SeString message)
=> this.ChatMessageUnhandled?.Invoke(type, timestamp, sender, message);
private void OnMessageUnhandledForward(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, SeString sender, SeString message)
=> this.ChatMessageUnhandled?.Invoke(type, sourceKind, targetKind, timestamp, sender, message);
private void OnLogMessageForward(Chat.ILogMessage message)
=> this.LogMessage?.Invoke(message);

View file

@ -0,0 +1,44 @@
namespace Dalamud.Game.Text;
/// <summary>
/// Specifies the relationship for entities involved in a chat log event (e.g., Source or Target).<br/>
/// Used primarily for parsing and coloring chat log messages.
/// </summary>
public enum XivChatRelationKind : byte
{
/// <summary>No specific relation or unknown entity.</summary>
None = 0,
/// <summary>The player currently controlled by the local client.</summary>
LocalPlayer = 1,
/// <summary>A player in the same 4-man or 8-man party as the local player.</summary>
PartyMember = 2,
/// <summary>A player in the same alliance raid.</summary>
AllianceMember = 3,
/// <summary>A player not in the local player's party or alliance.</summary>
OtherPlayer = 4,
/// <summary>An enemy entity that is currently in combat with the player or party.</summary>
EngagedEnemy = 5,
/// <summary>An enemy entity that is not yet in combat or claimed.</summary>
UnengagedEnemy = 6,
/// <summary>An NPC that is friendly or neutral to the player (e.g., EventNPCs).</summary>
FriendlyNpc = 7,
/// <summary>A pet (Summoner/Scholar) or companion (Chocobo) belonging to the local player.</summary>
PetOrCompanion = 8,
/// <summary>A pet or companion belonging to a member of the local player's party.</summary>
PetOrCompanionParty = 9,
/// <summary>A pet or companion belonging to a member of the alliance.</summary>
PetOrCompanionAlliance = 10,
/// <summary>A pet or companion belonging to a player not in the party or alliance.</summary>
PetOrCompanionOther = 11,
}

View file

@ -105,7 +105,7 @@ internal class ChatSelfTestStep : ISelfTestStep
}
private void ChatOnOnChatMessage(
XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool ishandled)
XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, ref SeString sender, ref SeString message, ref bool ishandled)
{
if (type == XivChatType.Echo && message.TextValue == "DALAMUD")
{

View file

@ -17,39 +17,47 @@ public interface IChatGui : IDalamudService
/// A delegate type used with the <see cref="ChatGui.ChatMessage"/> event.
/// </summary>
/// <param name="type">The type of chat.</param>
/// <param name="sourceKind">The relationship of the entity sending the message or performing the action.</param>
/// <param name="targetKind">The relationship of the entity receiving the message or being targeted by the action.</param>
/// <param name="timestamp">The timestamp of when the message was sent.</param>
/// <param name="sender">The sender name.</param>
/// <param name="message">The message sent.</param>
/// <param name="isHandled">A value indicating whether the message was handled or should be propagated.</param>
public delegate void OnMessageDelegate(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled);
public delegate void OnMessageDelegate(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled);
/// <summary>
/// A delegate type used with the <see cref="ChatGui.CheckMessageHandled"/> event.
/// </summary>
/// <param name="type">The type of chat.</param>
/// <param name="sourceKind">The relationship of the entity sending the message or performing the action.</param>
/// <param name="targetKind">The relationship of the entity receiving the message or being targeted by the action.</param>
/// <param name="timestamp">The timestamp of when the message was sent.</param>
/// <param name="sender">The sender name.</param>
/// <param name="message">The message sent.</param>
/// <param name="isHandled">A value indicating whether the message was handled or should be propagated.</param>
public delegate void OnCheckMessageHandledDelegate(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled);
public delegate void OnCheckMessageHandledDelegate(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled);
/// <summary>
/// A delegate type used with the <see cref="ChatGui.ChatMessageHandled"/> event.
/// </summary>
/// <param name="type">The type of chat.</param>
/// <param name="sourceKind">The relationship of the entity sending the message or performing the action.</param>
/// <param name="targetKind">The relationship of the entity receiving the message or being targeted by the action.</param>
/// <param name="timestamp">The timestamp of when the message was sent.</param>
/// <param name="sender">The sender name.</param>
/// <param name="message">The message sent.</param>
public delegate void OnMessageHandledDelegate(XivChatType type, int timestamp, SeString sender, SeString message);
public delegate void OnMessageHandledDelegate(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, SeString sender, SeString message);
/// <summary>
/// A delegate type used with the <see cref="ChatGui.ChatMessageUnhandled"/> event.
/// </summary>
/// <param name="type">The type of chat.</param>
/// <param name="sourceKind">The relationship of the entity sending the message or performing the action.</param>
/// <param name="targetKind">The relationship of the entity receiving the message or being targeted by the action.</param>
/// <param name="timestamp">The timestamp of when the message was sent.</param>
/// <param name="sender">The sender name.</param>
/// <param name="message">The message sent.</param>
public delegate void OnMessageUnhandledDelegate(XivChatType type, int timestamp, SeString sender, SeString message);
public delegate void OnMessageUnhandledDelegate(XivChatType type, XivChatRelationKind sourceKind, XivChatRelationKind targetKind, int timestamp, SeString sender, SeString message);
/// <summary>
/// A delegate type used with the <see cref="IChatGui.LogMessage"/> event.