[Api13] Update ChatLinkHandler functions (#2322)

* Update ChatLinkHandler functions

- Move functions to IChatGui
- Switch CommandId to type Guid and generate them automatically

* Remove unused field
This commit is contained in:
Haselnussbomber 2025-08-04 03:07:21 +02:00 committed by GitHub
parent ecbb4053ce
commit 63e7cb25b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 74 additions and 77 deletions

View file

@ -119,8 +119,6 @@ internal partial class ChatHandlers : IServiceType
if (string.IsNullOrEmpty(this.configuration.LastVersion) || !Util.AssemblyVersion.StartsWith(this.configuration.LastVersion)) if (string.IsNullOrEmpty(this.configuration.LastVersion) || !Util.AssemblyVersion.StartsWith(this.configuration.LastVersion))
{ {
var linkPayload = chatGui.AddChatLinkHandler( var linkPayload = chatGui.AddChatLinkHandler(
"dalamud",
8459324,
(_, _) => dalamudInterface.OpenPluginInstallerTo(PluginInstallerOpenKind.Changelogs)); (_, _) => dalamudInterface.OpenPluginInstallerTo(PluginInstallerOpenKind.Changelogs));
var updateMessage = new SeStringBuilder() var updateMessage = new SeStringBuilder()

View file

@ -12,6 +12,7 @@ using Dalamud.IoC;
using Dalamud.IoC.Internal; using Dalamud.IoC.Internal;
using Dalamud.Logging.Internal; using Dalamud.Logging.Internal;
using Dalamud.Memory; using Dalamud.Memory;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Plugin.Services; using Dalamud.Plugin.Services;
using Dalamud.Utility; using Dalamud.Utility;
@ -40,7 +41,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
private static readonly ModuleLog Log = new("ChatGui"); private static readonly ModuleLog Log = new("ChatGui");
private readonly Queue<XivChatEntry> chatQueue = new(); private readonly Queue<XivChatEntry> chatQueue = new();
private readonly Dictionary<(string PluginName, uint CommandId), Action<uint, SeString>> dalamudLinkHandlers = new(); private readonly Dictionary<(string PluginName, Guid CommandId), Action<Guid, SeString>> dalamudLinkHandlers = new();
private readonly Hook<PrintMessageDelegate> printMessageHook; private readonly Hook<PrintMessageDelegate> printMessageHook;
private readonly Hook<InventoryItem.Delegates.Copy> inventoryItemCopyHook; private readonly Hook<InventoryItem.Delegates.Copy> inventoryItemCopyHook;
@ -49,7 +50,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
[ServiceManager.ServiceDependency] [ServiceManager.ServiceDependency]
private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get(); private readonly DalamudConfiguration configuration = Service<DalamudConfiguration>.Get();
private ImmutableDictionary<(string PluginName, uint CommandId), Action<uint, SeString>>? dalamudLinkHandlersCopy; private ImmutableDictionary<(string PluginName, Guid CommandId), Action<Guid, SeString>>? dalamudLinkHandlersCopy;
[ServiceManager.ServiceConstructor] [ServiceManager.ServiceConstructor]
private ChatGui() private ChatGui()
@ -85,7 +86,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
public byte LastLinkedItemFlags { get; private set; } public byte LastLinkedItemFlags { get; private set; }
/// <inheritdoc/> /// <inheritdoc/>
public IReadOnlyDictionary<(string PluginName, uint CommandId), Action<uint, SeString>> RegisteredLinkHandlers public IReadOnlyDictionary<(string PluginName, Guid CommandId), Action<Guid, SeString>> RegisteredLinkHandlers
{ {
get get
{ {
@ -161,6 +162,28 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
#endregion #endregion
#region Chat Links
/// <inheritdoc/>
public DalamudLinkPayload AddChatLinkHandler(Action<Guid, SeString> commandAction)
{
return this.AddChatLinkHandler("Dalamud", commandAction);
}
/// <inheritdoc/>
public void RemoveChatLinkHandler(Guid commandId)
{
this.RemoveChatLinkHandler("Dalamud", commandId);
}
/// <inheritdoc/>
public void RemoveChatLinkHandler()
{
this.RemoveChatLinkHandler("Dalamud");
}
#endregion
/// <summary> /// <summary>
/// Process a chat queue. /// Process a chat queue.
/// </summary> /// </summary>
@ -217,12 +240,11 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
/// Create a link handler. /// Create a link handler.
/// </summary> /// </summary>
/// <param name="pluginName">The name of the plugin handling the link.</param> /// <param name="pluginName">The name of the plugin handling the link.</param>
/// <param name="commandId">The ID of the command to run.</param>
/// <param name="commandAction">The command action itself.</param> /// <param name="commandAction">The command action itself.</param>
/// <returns>A payload for handling.</returns> /// <returns>A payload for handling.</returns>
[Api13ToDo("Plugins should not specify their own command IDs here. We should assign them ourselves.")] internal DalamudLinkPayload AddChatLinkHandler(string pluginName, Action<Guid, SeString> commandAction)
internal DalamudLinkPayload AddChatLinkHandler(string pluginName, uint commandId, Action<uint, SeString> commandAction)
{ {
var commandId = Guid.CreateVersion7();
var payload = new DalamudLinkPayload { Plugin = pluginName, CommandId = commandId }; var payload = new DalamudLinkPayload { Plugin = pluginName, CommandId = commandId };
lock (this.dalamudLinkHandlers) lock (this.dalamudLinkHandlers)
{ {
@ -255,7 +277,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
/// </summary> /// </summary>
/// <param name="pluginName">The name of the plugin handling the link.</param> /// <param name="pluginName">The name of the plugin handling the link.</param>
/// <param name="commandId">The ID of the command to be removed.</param> /// <param name="commandId">The ID of the command to be removed.</param>
internal void RemoveChatLinkHandler(string pluginName, uint commandId) internal void RemoveChatLinkHandler(string pluginName, Guid commandId)
{ {
lock (this.dalamudLinkHandlers) lock (this.dalamudLinkHandlers)
{ {
@ -478,11 +500,15 @@ internal class ChatGuiPluginScoped : IInternalDisposableService, IChatGui
[ServiceManager.ServiceDependency] [ServiceManager.ServiceDependency]
private readonly ChatGui chatGuiService = Service<ChatGui>.Get(); private readonly ChatGui chatGuiService = Service<ChatGui>.Get();
private readonly LocalPlugin plugin;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ChatGuiPluginScoped"/> class. /// Initializes a new instance of the <see cref="ChatGuiPluginScoped"/> class.
/// </summary> /// </summary>
internal ChatGuiPluginScoped() /// <param name="plugin">The plugin.</param>
internal ChatGuiPluginScoped(LocalPlugin plugin)
{ {
this.plugin = plugin;
this.chatGuiService.ChatMessage += this.OnMessageForward; this.chatGuiService.ChatMessage += this.OnMessageForward;
this.chatGuiService.CheckMessageHandled += this.OnCheckMessageForward; this.chatGuiService.CheckMessageHandled += this.OnCheckMessageForward;
this.chatGuiService.ChatMessageHandled += this.OnMessageHandledForward; this.chatGuiService.ChatMessageHandled += this.OnMessageHandledForward;
@ -508,7 +534,7 @@ internal class ChatGuiPluginScoped : IInternalDisposableService, IChatGui
public byte LastLinkedItemFlags => this.chatGuiService.LastLinkedItemFlags; public byte LastLinkedItemFlags => this.chatGuiService.LastLinkedItemFlags;
/// <inheritdoc/> /// <inheritdoc/>
public IReadOnlyDictionary<(string PluginName, uint CommandId), Action<uint, SeString>> RegisteredLinkHandlers => this.chatGuiService.RegisteredLinkHandlers; public IReadOnlyDictionary<(string PluginName, Guid CommandId), Action<Guid, SeString>> RegisteredLinkHandlers => this.chatGuiService.RegisteredLinkHandlers;
/// <inheritdoc/> /// <inheritdoc/>
void IInternalDisposableService.DisposeService() void IInternalDisposableService.DisposeService()
@ -524,6 +550,18 @@ internal class ChatGuiPluginScoped : IInternalDisposableService, IChatGui
this.ChatMessageUnhandled = null; this.ChatMessageUnhandled = null;
} }
/// <inheritdoc/>
public DalamudLinkPayload AddChatLinkHandler(Action<Guid, SeString> commandAction)
=> this.chatGuiService.AddChatLinkHandler(this.plugin.InternalName, commandAction);
/// <inheritdoc/>
public void RemoveChatLinkHandler(Guid commandId)
=> this.chatGuiService.RemoveChatLinkHandler(this.plugin.InternalName, commandId);
/// <inheritdoc/>
public void RemoveChatLinkHandler()
=> this.chatGuiService.RemoveChatLinkHandler(this.plugin.InternalName);
/// <inheritdoc/> /// <inheritdoc/>
public void Print(XivChatEntry chat) public void Print(XivChatEntry chat)
=> this.chatGuiService.Print(chat); => this.chatGuiService.Print(chat);

View file

@ -16,7 +16,7 @@ public class DalamudLinkPayload : Payload
public override PayloadType Type => PayloadType.DalamudLink; public override PayloadType Type => PayloadType.DalamudLink;
/// <summary>Gets the plugin command ID to be linked.</summary> /// <summary>Gets the plugin command ID to be linked.</summary>
public uint CommandId { get; internal set; } public Guid CommandId { get; internal set; }
/// <summary>Gets an optional extra integer value 1.</summary> /// <summary>Gets an optional extra integer value 1.</summary>
public int Extra1 { get; internal set; } public int Extra1 { get; internal set; }
@ -40,7 +40,7 @@ public class DalamudLinkPayload : Payload
var ssb = Lumina.Text.SeStringBuilder.SharedPool.Get(); var ssb = Lumina.Text.SeStringBuilder.SharedPool.Get();
var res = ssb.BeginMacro(MacroCode.Link) var res = ssb.BeginMacro(MacroCode.Link)
.AppendIntExpression((int)EmbeddedInfoType.DalamudLink - 1) .AppendIntExpression((int)EmbeddedInfoType.DalamudLink - 1)
.AppendUIntExpression(this.CommandId) .AppendStringExpression(this.CommandId.ToString())
.AppendIntExpression(this.Extra1) .AppendIntExpression(this.Extra1)
.AppendIntExpression(this.Extra2) .AppendIntExpression(this.Extra2)
.BeginStringExpression() .BeginStringExpression()
@ -72,15 +72,15 @@ public class DalamudLinkPayload : Payload
if (!pluginExpression.TryGetString(out var pluginString)) if (!pluginExpression.TryGetString(out var pluginString))
return; return;
if (!commandIdExpression.TryGetUInt(out var commandId)) if (!commandIdExpression.TryGetString(out var commandId))
return; return;
this.Plugin = pluginString.ExtractText(); this.Plugin = pluginString.ExtractText();
this.CommandId = commandId; this.CommandId = Guid.Parse(commandId.ExtractText());
} }
else else
{ {
if (!commandIdExpression.TryGetUInt(out var commandId)) if (!commandIdExpression.TryGetString(out var commandId))
return; return;
if (!extra1Expression.TryGetInt(out var extra1)) if (!extra1Expression.TryGetInt(out var extra1))
@ -102,7 +102,7 @@ public class DalamudLinkPayload : Payload
return; return;
} }
this.CommandId = commandId; this.CommandId = Guid.Parse(commandId.ExtractText());
this.Extra1 = extra1; this.Extra1 = extra1;
this.Extra2 = extra2; this.Extra2 = extra2;
this.Plugin = extraData[0]; this.Plugin = extraData[0];

View file

@ -13,8 +13,6 @@ using Dalamud.Data;
using Dalamud.Game.Gui; using Dalamud.Game.Gui;
using Dalamud.Game.Text; using Dalamud.Game.Text;
using Dalamud.Game.Text.Sanitizer; using Dalamud.Game.Text.Sanitizer;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Interface; using Dalamud.Interface;
using Dalamud.Interface.Internal; using Dalamud.Interface.Internal;
using Dalamud.Interface.Internal.Windows.PluginInstaller; using Dalamud.Interface.Internal.Windows.PluginInstaller;
@ -427,39 +425,6 @@ internal sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposa
#endregion #endregion
#region Chat Links
// TODO API9: Move to chatgui, don't allow passing own commandId
/// <summary>
/// Register a chat link handler.
/// </summary>
/// <param name="commandId">The ID of the command.</param>
/// <param name="commandAction">The action to be executed.</param>
/// <returns>Returns an SeString payload for the link.</returns>
public DalamudLinkPayload AddChatLinkHandler(uint commandId, Action<uint, SeString> commandAction)
{
return Service<ChatGui>.Get().AddChatLinkHandler(this.plugin.InternalName, commandId, commandAction);
}
/// <summary>
/// Remove a chat link handler.
/// </summary>
/// <param name="commandId">The ID of the command.</param>
public void RemoveChatLinkHandler(uint commandId)
{
Service<ChatGui>.Get().RemoveChatLinkHandler(this.plugin.InternalName, commandId);
}
/// <summary>
/// Removes all chat link handlers registered by the plugin.
/// </summary>
public void RemoveChatLinkHandler()
{
Service<ChatGui>.Get().RemoveChatLinkHandler(this.plugin.InternalName);
}
#endregion
#region Dependency Injection #region Dependency Injection
/// <inheritdoc/> /// <inheritdoc/>

View file

@ -1,4 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -281,25 +281,6 @@ public interface IDalamudPluginInterface
/// <returns>directory with path of AppData/XIVLauncher/pluginConfig/PluginInternalName/loc.</returns> /// <returns>directory with path of AppData/XIVLauncher/pluginConfig/PluginInternalName/loc.</returns>
string GetPluginLocDirectory(); string GetPluginLocDirectory();
/// <summary>
/// Register a chat link handler.
/// </summary>
/// <param name="commandId">The ID of the command.</param>
/// <param name="commandAction">The action to be executed.</param>
/// <returns>Returns an SeString payload for the link.</returns>
DalamudLinkPayload AddChatLinkHandler(uint commandId, Action<uint, SeString> commandAction);
/// <summary>
/// Remove a chat link handler.
/// </summary>
/// <param name="commandId">The ID of the command.</param>
void RemoveChatLinkHandler(uint commandId);
/// <summary>
/// Removes all chat link handlers registered by the plugin.
/// </summary>
void RemoveChatLinkHandler();
/// <summary> /// <summary>
/// Create a new object of the provided type using its default constructor, then inject objects and properties. /// Create a new object of the provided type using its default constructor, then inject objects and properties.
/// </summary> /// </summary>

View file

@ -102,8 +102,6 @@ internal class AutoUpdateManager : IServiceType
this.openInstallerWindowLinkTask = this.openInstallerWindowLinkTask =
Service<ChatGui>.GetAsync().ContinueWith( Service<ChatGui>.GetAsync().ContinueWith(
chatGuiTask => chatGuiTask.Result.AddChatLinkHandler( chatGuiTask => chatGuiTask.Result.AddChatLinkHandler(
"Dalamud",
1001,
(_, _) => (_, _) =>
{ {
Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerTo(PluginInstallerOpenKind.InstalledPlugins); Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerTo(PluginInstallerOpenKind.InstalledPlugins);

View file

@ -125,8 +125,6 @@ internal class PluginManager : IInternalDisposableService
this.openInstallerWindowPluginChangelogsLink = this.openInstallerWindowPluginChangelogsLink =
Service<ChatGui>.GetAsync().ContinueWith( Service<ChatGui>.GetAsync().ContinueWith(
chatGuiTask => chatGuiTask.Result.AddChatLinkHandler( chatGuiTask => chatGuiTask.Result.AddChatLinkHandler(
"Dalamud",
1003,
(_, _) => (_, _) =>
{ {
Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerTo( Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerTo(

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using Dalamud.Game.Gui; using Dalamud.Game.Gui;
using Dalamud.Game.Text; using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling; using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
namespace Dalamud.Plugin.Services; namespace Dalamud.Plugin.Services;
@ -82,7 +83,25 @@ public interface IChatGui
/// <summary> /// <summary>
/// Gets the dictionary of Dalamud Link Handlers. /// Gets the dictionary of Dalamud Link Handlers.
/// </summary> /// </summary>
public IReadOnlyDictionary<(string PluginName, uint CommandId), Action<uint, SeString>> RegisteredLinkHandlers { get; } public IReadOnlyDictionary<(string PluginName, Guid CommandId), Action<Guid, SeString>> RegisteredLinkHandlers { get; }
/// <summary>
/// Register a chat link handler.
/// </summary>
/// <param name="commandAction">The action to be executed.</param>
/// <returns>Returns an SeString payload for the link.</returns>
public DalamudLinkPayload AddChatLinkHandler(Action<Guid, SeString> commandAction);
/// <summary>
/// Remove a chat link handler.
/// </summary>
/// <param name="commandId">The ID of the command.</param>
public void RemoveChatLinkHandler(Guid commandId);
/// <summary>
/// Removes all chat link handlers registered by the plugin.
/// </summary>
public void RemoveChatLinkHandler();
/// <summary> /// <summary>
/// Queue a chat message. Dalamud will send queued messages on the next framework event. /// Queue a chat message. Dalamud will send queued messages on the next framework event.