More cleanup

This commit is contained in:
Infi
2024-05-02 15:02:42 +02:00
parent 477290ce7e
commit 5b30e54f65
7 changed files with 108 additions and 150 deletions
+28 -20
View File
@@ -8,7 +8,8 @@ namespace ChatTwo;
[Union(0, typeof(TextChunk))] [Union(0, typeof(TextChunk))]
[Union(1, typeof(IconChunk))] [Union(1, typeof(IconChunk))]
[MessagePackObject] [MessagePackObject]
public abstract class Chunk { public abstract class Chunk
{
[IgnoreMember] [IgnoreMember]
[BsonIgnore] // used by LegacyMessageImporter [BsonIgnore] // used by LegacyMessageImporter
internal Message? Message { get; set; } internal Message? Message { get; set; }
@@ -20,12 +21,14 @@ public abstract class Chunk {
[MessagePackFormatter(typeof(PayloadMessagePackFormatter))] [MessagePackFormatter(typeof(PayloadMessagePackFormatter))]
public Payload? Link { get; set; } public Payload? Link { get; set; }
protected Chunk(ChunkSource source, Payload? link) { protected Chunk(ChunkSource source, Payload? link)
{
Source = source; Source = source;
Link = link; Link = link;
} }
internal SeString? GetSeString() => Source switch { internal SeString? GetSeString() => Source switch
{
ChunkSource.None => null, ChunkSource.None => null,
ChunkSource.Sender => Message?.SenderSource, ChunkSource.Sender => Message?.SenderSource,
ChunkSource.Content => Message?.ContentSource, ChunkSource.Content => Message?.ContentSource,
@@ -35,26 +38,27 @@ public abstract class Chunk {
/// <summary> /// <summary>
/// Get some basic text for use in generating hashes. /// Get some basic text for use in generating hashes.
/// </summary> /// </summary>
internal string StringValue() { internal string StringValue()
switch (this) { {
case TextChunk text: return this switch
return text.Content; {
case IconChunk icon: TextChunk text => text.Content,
return icon.Icon.ToString(); IconChunk icon => icon.Icon.ToString(),
default: _ => ""
return ""; };
}
} }
} }
public enum ChunkSource { public enum ChunkSource
{
None, None,
Sender, Sender,
Content, Content,
} }
[MessagePackObject] [MessagePackObject]
public class TextChunk : Chunk { public class TextChunk : Chunk
{
[Key(2)] [Key(2)]
public ChatType? FallbackColour { get; set; } public ChatType? FallbackColour { get; set; }
[Key(3)] [Key(3)]
@@ -66,13 +70,14 @@ public class TextChunk : Chunk {
[Key(6)] [Key(6)]
public string Content { get; set; } public string Content { get; set; }
internal TextChunk(ChunkSource source, Payload? link, string content) : base(source, link) { internal TextChunk(ChunkSource source, Payload? link, string content) : base(source, link)
{
Content = content; Content = content;
} }
// ReSharper disable once UnusedMember.Global // Used by MessagePack // ReSharper disable once UnusedMember.Global // Used by MessagePack
public TextChunk(ChunkSource source, Payload? link, ChatType? fallbackColour, uint? foreground, uint? glow, public TextChunk(ChunkSource source, Payload? link, ChatType? fallbackColour, uint? foreground, uint? glow, bool italic, string content) : base(source, link)
bool italic, string content) : base(source, link) { {
FallbackColour = fallbackColour; FallbackColour = fallbackColour;
Foreground = foreground; Foreground = foreground;
Glow = glow; Glow = glow;
@@ -85,7 +90,8 @@ public class TextChunk : Chunk {
/// </summary> /// </summary>
public TextChunk NewWithStyle(ChunkSource source, Payload? link, string content) public TextChunk NewWithStyle(ChunkSource source, Payload? link, string content)
{ {
return new TextChunk(source, link, content) { return new TextChunk(source, link, content)
{
FallbackColour = FallbackColour, FallbackColour = FallbackColour,
Foreground = Foreground, Foreground = Foreground,
Glow = Glow, Glow = Glow,
@@ -95,11 +101,13 @@ public class TextChunk : Chunk {
} }
[MessagePackObject] [MessagePackObject]
public class IconChunk : Chunk { public class IconChunk : Chunk
{
[Key(2)] [Key(2)]
public BitmapFontIcon Icon { get; set; } public BitmapFontIcon Icon { get; set; }
public IconChunk(ChunkSource source, Payload? link, BitmapFontIcon icon) : base(source, link) { public IconChunk(ChunkSource source, Payload? link, BitmapFontIcon icon) : base(source, link)
{
Icon = icon; Icon = icon;
} }
} }
+32 -20
View File
@@ -2,38 +2,43 @@ using Dalamud.Game.Command;
namespace ChatTwo; namespace ChatTwo;
internal sealed class Commands : IDisposable { internal sealed class Commands : IDisposable
{
private Plugin Plugin { get; } private Plugin Plugin { get; }
private Dictionary<string, CommandWrapper> Registered { get; } = new(); private Dictionary<string, CommandWrapper> Registered { get; } = new();
internal Commands(Plugin plugin) { internal Commands(Plugin plugin)
{
Plugin = plugin; Plugin = plugin;
} }
public void Dispose() { public void Dispose()
foreach (var name in Registered.Keys) { {
foreach (var name in Registered.Keys)
Plugin.CommandManager.RemoveHandler(name); Plugin.CommandManager.RemoveHandler(name);
}
} }
internal void Initialise() { internal void Initialise()
foreach (var wrapper in Registered.Values) { {
Plugin.CommandManager.AddHandler(wrapper.Name, new CommandInfo(Invoke) { foreach (var wrapper in Registered.Values)
{
Plugin.CommandManager.AddHandler(wrapper.Name, new CommandInfo(Invoke)
{
HelpMessage = wrapper.Description ?? string.Empty, HelpMessage = wrapper.Description ?? string.Empty,
ShowInHelp = wrapper.ShowInHelp, ShowInHelp = wrapper.ShowInHelp,
}); });
} }
} }
internal CommandWrapper Register(string name, string? description = null, bool? showInHelp = null) { internal CommandWrapper Register(string name, string? description = null, bool? showInHelp = null)
if (Registered.TryGetValue(name, out var wrapper)) { {
if (description != null) { if (Registered.TryGetValue(name, out var wrapper))
{
if (description != null)
wrapper.Description = description; wrapper.Description = description;
}
if (showInHelp != null) { if (showInHelp != null)
wrapper.ShowInHelp = showInHelp.Value; wrapper.ShowInHelp = showInHelp.Value;
}
return wrapper; return wrapper;
} }
@@ -43,33 +48,40 @@ internal sealed class Commands : IDisposable {
} }
private void Invoke(string command, string arguments) { private void Invoke(string command, string arguments) {
if (!Registered.TryGetValue(command, out var wrapper)) { if (!Registered.TryGetValue(command, out var wrapper))
{
Plugin.Log.Warning($"Missing registration for command {command}"); Plugin.Log.Warning($"Missing registration for command {command}");
return; return;
} }
try { try
{
wrapper.Invoke(command, arguments); wrapper.Invoke(command, arguments);
} catch (Exception ex) { }
catch (Exception ex)
{
Plugin.Log.Error(ex, $"Error while executing command {command}"); Plugin.Log.Error(ex, $"Error while executing command {command}");
} }
} }
} }
internal sealed class CommandWrapper { internal sealed class CommandWrapper
{
internal string Name { get; } internal string Name { get; }
internal string? Description { get; set; } internal string? Description { get; set; }
internal bool ShowInHelp { get; set; } internal bool ShowInHelp { get; set; }
internal event Action<string, string>? Execute; internal event Action<string, string>? Execute;
internal CommandWrapper(string name, string? description, bool showInHelp) { internal CommandWrapper(string name, string? description, bool showInHelp)
{
Name = name; Name = name;
Description = description; Description = description;
ShowInHelp = showInHelp; ShowInHelp = showInHelp;
} }
internal void Invoke(string command, string arguments) { internal void Invoke(string command, string arguments)
{
Execute?.Invoke(command, arguments); Execute?.Invoke(command, arguments);
} }
} }
-50
View File
@@ -10,7 +10,6 @@ namespace ChatTwo;
internal class Configuration : IPluginConfiguration internal class Configuration : IPluginConfiguration
{ {
private const int LatestVersion = 5; private const int LatestVersion = 5;
internal const int LatestDbVersion = 1;
public int Version { get; set; } = LatestVersion; public int Version { get; set; } = LatestVersion;
@@ -101,49 +100,6 @@ internal class Configuration : IPluginConfiguration
OverrideStyle = other.OverrideStyle; OverrideStyle = other.OverrideStyle;
ChosenStyle = other.ChosenStyle; ChosenStyle = other.ChosenStyle;
} }
public void Migrate()
{
var loop = true;
while (loop && Version < LatestVersion)
{
switch (Version) {
case 1: {
Version = 2;
foreach (var tab in Tabs)
{
#pragma warning disable CS0618
tab.UnreadMode = tab.DisplayUnread ? UnreadMode.Unseen : UnreadMode.None;
#pragma warning restore CS0618
}
break;
}
case 2:
Version = 3;
JapaneseFontSize = FontSize;
SymbolsFontSize = FontSize;
break;
case 3:
Version = 4;
WindowAlpha *= 100f;
break;
case 4:
Version = 5;
foreach (var tab in Tabs)
tab.ExtraChatAll = true;
break;
default:
Plugin.Log.Warning($"Couldn't migrate config version {Version}");
loop = false;
break;
}
}
}
} }
[Serializable] [Serializable]
@@ -181,9 +137,6 @@ internal class Tab
public bool ExtraChatAll; public bool ExtraChatAll;
public HashSet<Guid> ExtraChatChannels = []; public HashSet<Guid> ExtraChatChannels = [];
[Obsolete("Use UnreadMode instead")]
public bool DisplayUnread = true;
public UnreadMode UnreadMode = UnreadMode.Unseen; public UnreadMode UnreadMode = UnreadMode.Unseen;
public bool DisplayTimestamp = true; public bool DisplayTimestamp = true;
public InputChannel? Channel; public InputChannel? Channel;
@@ -264,9 +217,6 @@ internal class Tab
ChatCodes = ChatCodes.ToDictionary(entry => entry.Key, entry => entry.Value), ChatCodes = ChatCodes.ToDictionary(entry => entry.Key, entry => entry.Value),
ExtraChatAll = ExtraChatAll, ExtraChatAll = ExtraChatAll,
ExtraChatChannels = ExtraChatChannels.ToHashSet(), ExtraChatChannels = ExtraChatChannels.ToHashSet(),
#pragma warning disable CS0618
DisplayUnread = DisplayUnread,
#pragma warning restore CS0618
UnreadMode = UnreadMode, UnreadMode = UnreadMode,
DisplayTimestamp = DisplayTimestamp, DisplayTimestamp = DisplayTimestamp,
Channel = Channel, Channel = Channel,
+16 -13
View File
@@ -49,7 +49,8 @@ internal class SortCode {
} }
} }
internal class Message { internal class Message
{
internal Guid Id { get; } = Guid.NewGuid(); internal Guid Id { get; } = Guid.NewGuid();
internal ulong Receiver { get; } internal ulong Receiver { get; }
internal ulong ContentId { get; set; } internal ulong ContentId { get; set; }
@@ -83,12 +84,12 @@ internal class Message {
ExtraChatChannel = ExtractExtraChatChannel(); ExtraChatChannel = ExtractExtraChatChannel();
Hash = GenerateHash(); Hash = GenerateHash();
foreach (var chunk in sender.Concat(content)) { foreach (var chunk in sender.Concat(content))
chunk.Message = this; chunk.Message = this;
}
} }
internal Message(Guid id, ulong receiver, ulong contentId, DateTimeOffset date, ChatCode code, List<Chunk> sender, List<Chunk> content, SeString senderSource, SeString contentSource, SortCode sortCode, Guid extraChatChannel) { internal Message(Guid id, ulong receiver, ulong contentId, DateTimeOffset date, ChatCode code, List<Chunk> sender, List<Chunk> content, SeString senderSource, SeString contentSource, SortCode sortCode, Guid extraChatChannel)
{
Id = id; Id = id;
Receiver = receiver; Receiver = receiver;
ContentId = contentId; ContentId = contentId;
@@ -96,7 +97,7 @@ internal class Message {
Code = code; Code = code;
Sender = sender; Sender = sender;
// Don't call ReplaceContentURLs here since we're loading the message // Don't call ReplaceContentURLs here since we're loading the message
// from the database and it should already have parsed URL data. // from the database, and it should already have parsed URL data.
Content = content; Content = content;
SenderSource = senderSource; SenderSource = senderSource;
ContentSource = contentSource; ContentSource = contentSource;
@@ -104,25 +105,26 @@ internal class Message {
ExtraChatChannel = extraChatChannel; ExtraChatChannel = extraChatChannel;
Hash = GenerateHash(); Hash = GenerateHash();
foreach (var chunk in sender.Concat(content)) { foreach (var chunk in sender.Concat(content))
chunk.Message = this; chunk.Message = this;
}
} }
private int GenerateHash() { private int GenerateHash()
{
return SortCode.GetHashCode() return SortCode.GetHashCode()
^ ExtraChatChannel.GetHashCode() ^ ExtraChatChannel.GetHashCode()
^ string.Join("", Sender.Select(c => c.StringValue())).GetHashCode() ^ string.Join("", Sender.Select(c => c.StringValue())).GetHashCode()
^ string.Join("", Content.Select(c => c.StringValue())).GetHashCode(); ^ string.Join("", Content.Select(c => c.StringValue())).GetHashCode();
} }
private Guid ExtractExtraChatChannel() { private Guid ExtractExtraChatChannel()
if (ContentSource.Payloads.Count > 0 && ContentSource.Payloads[0] is RawPayload raw) { {
if (ContentSource.Payloads.Count > 0 && ContentSource.Payloads[0] is RawPayload raw)
{
// this does an encode and clone every time it's accessed, so cache // this does an encode and clone every time it's accessed, so cache
var data = raw.Data; var data = raw.Data;
if (data[1] == 0x27 && data[2] == 18 && data[3] == 0x20) { if (data[1] == 0x27 && data[2] == 18 && data[3] == 0x20)
return new Guid(data[4..^1]); return new Guid(data[4..^1]);
}
} }
return Guid.Empty; return Guid.Empty;
@@ -152,7 +154,8 @@ internal class Message {
private List<Chunk> ReplaceContentURLs(List<Chunk> content) private List<Chunk> ReplaceContentURLs(List<Chunk> content)
{ {
var newChunks = new List<Chunk>(); var newChunks = new List<Chunk>();
void AddChunkWithMessage(Chunk chunk) { void AddChunkWithMessage(Chunk chunk)
{
chunk.Message = this; chunk.Message = this;
newChunks.Add(chunk); newChunks.Add(chunk);
} }
+1 -5
View File
@@ -274,11 +274,7 @@ internal class MessageManager : IAsyncDisposable
.Cast<ITextProvider>() .Cast<ITextProvider>()
.Select(text => text.Text); .Select(text => text.Text);
var nameFormatting = NameFormatting.Of( var nameFormatting = NameFormatting.Of(string.Join("", before), string.Join("", after));
string.Join("", before),
string.Join("", after)
);
Formats[type] = nameFormatting; Formats[type] = nameFormatting;
return nameFormatting; return nameFormatting;
+7 -14
View File
@@ -70,18 +70,16 @@ public sealed class Plugin : IDalamudPlugin
GameStarted = Process.GetCurrentProcess().StartTime.ToUniversalTime(); GameStarted = Process.GetCurrentProcess().StartTime.ToUniversalTime();
Config = Interface.GetPluginConfig() as Configuration ?? new Configuration(); Config = Interface.GetPluginConfig() as Configuration ?? new Configuration();
Config.Migrate();
if (Config.Tabs.Count == 0) { if (Config.Tabs.Count == 0)
Config.Tabs.Add(TabsUtil.VanillaGeneral); Config.Tabs.Add(TabsUtil.VanillaGeneral);
}
LanguageChanged(Interface.UiLanguage); LanguageChanged(Interface.UiLanguage);
ImGuiUtil.Initialize(this); ImGuiUtil.Initialize(this);
Commands = new Commands(this); Commands = new Commands(this);
Common = new XivCommonBase(Interface); Common = new XivCommonBase(Interface);
TextureCache = new TextureCache(TextureProvider); TextureCache = new TextureCache();
Functions = new GameFunctions.GameFunctions(this); Functions = new GameFunctions.GameFunctions(this);
Ipc = new IpcManager(Interface); Ipc = new IpcManager(Interface);
ExtraChat = new ExtraChat(this); ExtraChat = new ExtraChat(this);
@@ -112,9 +110,8 @@ public sealed class Plugin : IDalamudPlugin
// let all the other components register, then initialise commands // let all the other components register, then initialise commands
Commands.Initialise(); Commands.Initialise();
if (Interface.Reason is not PluginLoadReason.Boot) { if (Interface.Reason is not PluginLoadReason.Boot)
MessageManager.FilterAllTabsAsync(false); MessageManager.FilterAllTabsAsync(false);
}
Framework.Update += FrameworkUpdate; Framework.Update += FrameworkUpdate;
Interface.UiBuilder.Draw += Draw; Interface.UiBuilder.Draw += Draw;
@@ -203,18 +200,14 @@ public sealed class Plugin : IDalamudPlugin
private void FrameworkUpdate(IFramework framework) private void FrameworkUpdate(IFramework framework)
{ {
if (DeferredSaveFrames >= 0 && DeferredSaveFrames-- == 0) { if (DeferredSaveFrames >= 0 && DeferredSaveFrames-- == 0)
SaveConfig(); SaveConfig();
}
if (!Config.HideChat) { if (!Config.HideChat)
return; return;
}
foreach (var name in ChatAddonNames) { foreach (var name in ChatAddonNames)
if (GameFunctions.GameFunctions.IsAddonInteractable(name)) { if (GameFunctions.GameFunctions.IsAddonInteractable(name))
GameFunctions.GameFunctions.SetAddonInteractable(name, false); GameFunctions.GameFunctions.SetAddonInteractable(name, false);
}
}
} }
} }
+24 -28
View File
@@ -4,68 +4,64 @@ using Lumina.Excel.GeneratedSheets;
namespace ChatTwo; namespace ChatTwo;
internal class TextureCache : IDisposable { internal class TextureCache : IDisposable
private ITextureProvider TextureProvider { get; } {
private readonly Dictionary<(uint, bool), IDalamudTextureWrap> _itemIcons = new(); private readonly Dictionary<(uint, bool), IDalamudTextureWrap> _itemIcons = new();
private readonly Dictionary<(uint, bool), IDalamudTextureWrap> _statusIcons = new(); private readonly Dictionary<(uint, bool), IDalamudTextureWrap> _statusIcons = new();
private readonly Dictionary<(uint, bool), IDalamudTextureWrap> _eventItemIcons = new(); private readonly Dictionary<(uint, bool), IDalamudTextureWrap> _eventItemIcons = new();
internal IReadOnlyDictionary<(uint, bool), IDalamudTextureWrap> ItemIcons => _itemIcons; private IReadOnlyDictionary<(uint, bool), IDalamudTextureWrap> ItemIcons => _itemIcons;
internal IReadOnlyDictionary<(uint, bool), IDalamudTextureWrap> StatusIcons => _statusIcons; private IReadOnlyDictionary<(uint, bool), IDalamudTextureWrap> StatusIcons => _statusIcons;
internal IReadOnlyDictionary<(uint, bool), IDalamudTextureWrap> EventItemIcons => _eventItemIcons; private IReadOnlyDictionary<(uint, bool), IDalamudTextureWrap> EventItemIcons => _eventItemIcons;
internal TextureCache(ITextureProvider textureProvider) { public void Dispose()
TextureProvider = textureProvider; {
} foreach (var tex in ItemIcons.Values.Concat(StatusIcons.Values))
public void Dispose() {
var allIcons = ItemIcons.Values
.Concat(StatusIcons.Values);
foreach (var tex in allIcons) {
tex.Dispose(); tex.Dispose();
}
} }
private void AddIcon(IDictionary<(uint, bool), IDalamudTextureWrap> dict, uint icon, bool hq = false) { private void AddIcon(IDictionary<(uint, bool), IDalamudTextureWrap> dict, uint icon, bool hq = false) {
if (dict.ContainsKey((icon, hq))) { if (dict.ContainsKey((icon, hq)))
return; return;
}
var tex = hq var tex = hq
? TextureProvider.GetIcon(icon, ITextureProvider.IconFlags.ItemHighQuality) ? Plugin.TextureProvider.GetIcon(icon, ITextureProvider.IconFlags.ItemHighQuality)
: TextureProvider.GetIcon(icon); : Plugin.TextureProvider.GetIcon(icon);
if (tex != null) { if (tex != null)
dict[(icon, hq)] = tex; dict[(icon, hq)] = tex;
}
} }
internal void AddItem(Item item, bool hq) { private void AddItem(Item item, bool hq)
{
AddIcon(_itemIcons, item.Icon, hq); AddIcon(_itemIcons, item.Icon, hq);
} }
internal void AddStatus(Status status) { private void AddStatus(Status status)
{
AddIcon(_statusIcons, status.Icon); AddIcon(_statusIcons, status.Icon);
} }
internal void AddEventItem(EventItem item) { private void AddEventItem(EventItem item)
{
AddIcon(_eventItemIcons, item.Icon); AddIcon(_eventItemIcons, item.Icon);
} }
internal IDalamudTextureWrap? GetItem(Item item, bool hq = false) { internal IDalamudTextureWrap? GetItem(Item item, bool hq = false)
{
AddItem(item, hq); AddItem(item, hq);
ItemIcons.TryGetValue((item.Icon, hq), out var icon); ItemIcons.TryGetValue((item.Icon, hq), out var icon);
return icon; return icon;
} }
internal IDalamudTextureWrap? GetStatus(Status status) { internal IDalamudTextureWrap? GetStatus(Status status)
{
AddStatus(status); AddStatus(status);
StatusIcons.TryGetValue((status.Icon, false), out var icon); StatusIcons.TryGetValue((status.Icon, false), out var icon);
return icon; return icon;
} }
internal IDalamudTextureWrap? GetEventItem(EventItem item) { internal IDalamudTextureWrap? GetEventItem(EventItem item)
{
AddEventItem(item); AddEventItem(item);
EventItemIcons.TryGetValue((item.Icon, false), out var icon); EventItemIcons.TryGetValue((item.Icon, false), out var icon);
return icon; return icon;