Fix ChatService dispose + Add chat configuration

This commit is contained in:
Loporrit
2024-11-26 01:03:58 +00:00
parent a4f78e7835
commit dc9a7f4363
10 changed files with 432 additions and 47 deletions

View File

@@ -5,9 +5,11 @@ using Dalamud.Plugin.Services;
using MareSynchronos.API.Data;
using MareSynchronos.Interop;
using MareSynchronos.MareConfiguration;
using MareSynchronos.MareConfiguration.Models;
using MareSynchronos.PlayerData.Pairs;
using MareSynchronos.Services.Mediator;
using MareSynchronos.Services.ServerConfiguration;
using MareSynchronos.Utils;
using MareSynchronos.WebAPI;
using Microsoft.Extensions.Logging;
@@ -15,6 +17,9 @@ namespace MareSynchronos.Services;
public class ChatService : DisposableMediatorSubscriberBase
{
public const int DefaultColor = 710;
public const int CommandMaxNumber = 50;
private readonly ILogger<ChatService> _logger;
private readonly IChatGui _chatGui;
private readonly DalamudUtilService _dalamudUtil;
@@ -45,6 +50,7 @@ public class ChatService : DisposableMediatorSubscriberBase
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (_gameChatHooks.IsValueCreated)
_gameChatHooks.Value!.Dispose();
}
@@ -61,28 +67,81 @@ public class ChatService : DisposableMediatorSubscriberBase
});
}
private ushort ResolveShellColor(int shellColor)
{
if (shellColor != 0)
return (ushort)shellColor;
var globalColor = _mareConfig.Current.ChatColor;
if (globalColor != 0)
return (ushort)globalColor;
return (ushort)DefaultColor;
}
private XivChatType ResolveShellLogKind(int shellLogKind)
{
if (shellLogKind != 0)
return (XivChatType)shellLogKind;
return (XivChatType)_mareConfig.Current.ChatLogKind;
}
private void HandleGroupChat(GroupChatMsgMessage message)
{
if (_mareConfig.Current.DisableSyncshellChat)
return;
var chatMsg = message.ChatMsg;
var shellNumber = _serverConfigurationManager.GetShellNumberForGid(message.GroupInfo.GID);
var shellConfig = _serverConfigurationManager.GetShellConfigForGid(message.GroupInfo.GID);
var shellNumber = shellConfig.ShellNumber;
if (!shellConfig.Enabled)
return;
ushort color = ResolveShellColor(shellConfig.Color);
var extraChatTags = _mareConfig.Current.ExtraChatTags;
var logKind = ResolveShellLogKind(shellConfig.LogKind);
var msg = new SeStringBuilder();
// TODO: Configure colors and appearance
msg.AddUiForeground(710);
if (extraChatTags)
{
msg.Add(ChatUtils.CreateExtraChatTagPayload(message.GroupInfo.GID));
msg.Add(RawPayload.LinkTerminator);
}
if (color != 0)
msg.AddUiForeground((ushort)color);
msg.AddText($"[SS{shellNumber}]<");
// TODO: Don't link to the local player because it lets you do invalid things
msg.Add(new PlayerPayload(chatMsg.SenderName, (uint)chatMsg.SenderHomeWorldId));
msg.Add(new PlayerPayload(chatMsg.SenderName, chatMsg.SenderHomeWorldId));
msg.AddText("> ");
msg.Append(SeString.Parse(message.ChatMsg.PayloadContent));
msg.AddUiForegroundOff();
if (color != 0)
msg.AddUiForegroundOff();
_chatGui.Print(new XivChatEntry{
Message = msg.Build(),
Name = chatMsg.SenderName,
Type = XivChatType.StandardEmote
Type = logKind
});
}
// Print an example message to the configured global chat channel
public void PrintChannelExample(string message, string gid = "")
{
int chatType = _mareConfig.Current.ChatLogKind;
foreach (var group in _pairManager.Groups)
{
if (group.Key.GID == gid)
{
int shellChatType = _serverConfigurationManager.GetShellConfigForGid(gid).LogKind;
if (shellChatType != 0)
chatType = shellChatType;
}
}
_chatGui.Print(new XivChatEntry{
Message = message,
Name = "",
Type = (XivChatType)chatType
});
}
@@ -94,7 +153,8 @@ public class ChatService : DisposableMediatorSubscriberBase
foreach (var group in _pairManager.Groups)
{
if (_serverConfigurationManager.GetShellNumberForGid(group.Key.GID) == shellNumber)
var shellConfig = _serverConfigurationManager.GetShellConfigForGid(group.Key.GID);
if (shellConfig.Enabled && shellConfig.ShellNumber == shellNumber)
{
if (_gameChatHooks.IsValueCreated && _gameChatHooks.Value.ChatChannelOverride != null)
{
@@ -113,7 +173,8 @@ public class ChatService : DisposableMediatorSubscriberBase
foreach (var group in _pairManager.Groups)
{
if (_serverConfigurationManager.GetShellNumberForGid(group.Key.GID) == shellNumber)
var shellConfig = _serverConfigurationManager.GetShellConfigForGid(group.Key.GID);
if (shellConfig.Enabled && shellConfig.ShellNumber == shellNumber)
{
var name = _serverConfigurationManager.GetNoteForGid(group.Key.GID) ?? group.Key.AliasOrGID;
// BUG: This doesn't always update the chat window e.g. when renaming a group
@@ -136,7 +197,8 @@ public class ChatService : DisposableMediatorSubscriberBase
foreach (var group in _pairManager.Groups)
{
if (_serverConfigurationManager.GetShellNumberForGid(group.Key.GID) == shellNumber)
var shellConfig = _serverConfigurationManager.GetShellConfigForGid(group.Key.GID);
if (shellConfig.Enabled && shellConfig.ShellNumber == shellNumber)
{
Task.Run(async () => {
// TODO: Cache the name and home world instead of fetching it every time

View File

@@ -19,7 +19,6 @@ public sealed class CommandManagerService : IDisposable
private const string _commandName2 = "/loporrit";
private const string _ssCommandPrefix = "/ss";
private const int _ssCommandMaxNumber = 50;
private readonly ApiController _apiController;
private readonly ICommandManager _commandManager;
@@ -52,7 +51,7 @@ public sealed class CommandManagerService : IDisposable
});
// Lazy registration of all possible /ss# commands which tbf is what the game does for linkshells anyway
for (int i = 1; i <= _ssCommandMaxNumber; ++i)
for (int i = 1; i <= ChatService.CommandMaxNumber; ++i)
{
_commandManager.AddHandler($"{_ssCommandPrefix}{i}", new CommandInfo(OnChatCommand)
{
@@ -66,7 +65,7 @@ public sealed class CommandManagerService : IDisposable
_commandManager.RemoveHandler(_commandName);
_commandManager.RemoveHandler(_commandName2);
for (int i = 1; i <= _ssCommandMaxNumber; ++i)
for (int i = 1; i <= ChatService.CommandMaxNumber; ++i)
_commandManager.RemoveHandler($"{_ssCommandPrefix}{i}");
}

View File

@@ -70,6 +70,12 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
.Where(w => w.Name.ByteLength > 0 && w.DataCenter.RowId != 0 && (w.IsPublic || char.IsUpper((char)w.Name.Data.Span[0])))
.ToDictionary(w => (ushort)w.RowId, w => w.Name.ToString());
});
UiColors = new(() =>
{
return gameData.GetExcelSheet<Lumina.Excel.Sheets.UIColor>(Dalamud.Game.ClientLanguage.English)!
.Where(x => x.RowId != 0 && !(x.RowId >= 500 && (x.UIForeground & 0xFFFFFF00) == 0))
.ToDictionary(x => (int)x.RowId);
});
mediator.Subscribe<TargetPairMessage>(this, async (msg) =>
{
if (clientState.IsPvP) return;
@@ -99,6 +105,7 @@ public class DalamudUtilService : IHostedService, IMediatorSubscriber
public bool IsInCombat { get; private set; } = false;
public Lazy<Dictionary<ushort, string>> WorldData { get; private set; }
public Lazy<Dictionary<int, Lumina.Excel.Sheets.UIColor>> UiColors { get; private set; }
public MareMediator Mediator { get; }

View File

@@ -1,6 +1,7 @@
using MareSynchronos.MareConfiguration;
using MareSynchronos.MareConfiguration.Models;
using MareSynchronos.Services.Mediator;
using MareSynchronos.Utils;
using MareSynchronos.WebAPI;
using Microsoft.Extensions.Logging;
using System.Diagnostics;
@@ -246,16 +247,27 @@ public class ServerConfigurationManager
return CurrentServerTagStorage().ServerAvailablePairTags;
}
internal int GetShellNumberForGid(string gid)
internal ShellConfig GetShellConfigForGid(string gid)
{
if (CurrentSyncshellStorage().GidShellConfig.TryGetValue(gid, out var config))
{
return config.ShellNumber;
}
return config;
int newNumber = CurrentSyncshellStorage().GidShellConfig.Count > 0 ? CurrentSyncshellStorage().GidShellConfig.Select(x => x.Value.ShellNumber).Max() + 1 : 1;
SetShellNumberForGid(gid, newNumber, false);
return newNumber;
// Pick the next higher syncshell number that is available
int newShellNumber = CurrentSyncshellStorage().GidShellConfig.Count > 0 ? CurrentSyncshellStorage().GidShellConfig.Select(x => x.Value.ShellNumber).Max() + 1 : 1;
var shellConfig = new ShellConfig{
ShellNumber = newShellNumber
};
// Save config to avoid auto-generated numbers shuffling around
SaveShellConfigForGid(gid, shellConfig);
return CurrentSyncshellStorage().GidShellConfig[gid];
}
internal int GetShellNumberForGid(string gid)
{
return GetShellConfigForGid(gid).ShellNumber;
}
internal Dictionary<string, List<string>> GetUidServerPairedUserTags()
@@ -359,23 +371,14 @@ public class ServerConfigurationManager
_notesConfig.Save();
}
internal void SetShellNumberForGid(string gid, int number, bool save = true)
internal void SaveShellConfigForGid(string gid, ShellConfig config)
{
if (string.IsNullOrEmpty(gid)) return;
if (CurrentSyncshellStorage().GidShellConfig.TryGetValue(gid, out var config))
{
config.ShellNumber = number;
}
else
{
CurrentSyncshellStorage().GidShellConfig.Add(gid, new(){
ShellNumber = number
});
}
// This is somewhat pointless because ShellConfig is a ref type we returned to the caller anyway...
CurrentSyncshellStorage().GidShellConfig[gid] = config;
if (save)
_syncshellConfig.Save();
_syncshellConfig.Save();
}
private ServerNotesStorage CurrentNotesStorage()