- net8
- Switch to new font api, - Fix null ref on login - Fix game freeze from chat link handler
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>1.18.10</Version>
|
||||
<TargetFramework>net7.0-windows</TargetFramework>
|
||||
<Version>1.19.0</Version>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Chat 2
|
||||
author: Anna
|
||||
author: Infi, Anna
|
||||
punchline: Electric Boogaloo - ♪ A whole new chat, a new fantastic chat window ♪
|
||||
description: |-
|
||||
Chat 2 is a complete rewrite of the in-game chat window as a plugin. It
|
||||
@@ -14,5 +14,4 @@ description: |-
|
||||
- Unread counts
|
||||
- Screenshot mode (obfuscate names)
|
||||
repo_url: https://git.anna.lgbt/anna/ChatTwo
|
||||
accepts_feedback: false
|
||||
feedback_message: Submit only bugs to https://github.com/anna/plugin-issues
|
||||
accepts_feedback: true
|
||||
|
||||
+2
-2
@@ -12,13 +12,13 @@ internal sealed class Commands : IDisposable {
|
||||
|
||||
public void Dispose() {
|
||||
foreach (var name in this.Registered.Keys) {
|
||||
this.Plugin.CommandManager.RemoveHandler(name);
|
||||
Plugin.CommandManager.RemoveHandler(name);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Initialise() {
|
||||
foreach (var wrapper in this.Registered.Values) {
|
||||
this.Plugin.CommandManager.AddHandler(wrapper.Name, new CommandInfo(this.Invoke) {
|
||||
Plugin.CommandManager.AddHandler(wrapper.Name, new CommandInfo(this.Invoke) {
|
||||
HelpMessage = wrapper.Description ?? string.Empty,
|
||||
ShowInHelp = wrapper.ShowInHelp,
|
||||
});
|
||||
|
||||
@@ -143,21 +143,21 @@ internal sealed unsafe class Chat : IDisposable {
|
||||
|
||||
internal Chat(Plugin plugin) {
|
||||
this.Plugin = plugin;
|
||||
this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
|
||||
this.ChatLogRefreshHook?.Enable();
|
||||
this.ChangeChannelNameHook?.Enable();
|
||||
this.ReplyInSelectedChatModeHook?.Enable();
|
||||
this.SetChatLogTellTargetHook?.Enable();
|
||||
|
||||
this.Plugin.Framework.Update += this.InterceptKeybinds;
|
||||
this.Plugin.ClientState.Login += this.Login;
|
||||
Plugin.Framework.Update += this.InterceptKeybinds;
|
||||
Plugin.ClientState.Login += this.Login;
|
||||
this.Login();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
this.Plugin.ClientState.Login -= this.Login;
|
||||
this.Plugin.Framework.Update -= this.InterceptKeybinds;
|
||||
Plugin.ClientState.Login -= this.Login;
|
||||
Plugin.Framework.Update -= this.InterceptKeybinds;
|
||||
|
||||
this.SetChatLogTellTargetHook?.Dispose();
|
||||
this.ReplyInSelectedChatModeHook?.Dispose();
|
||||
@@ -380,7 +380,7 @@ internal sealed unsafe class Chat : IDisposable {
|
||||
var modifierState = (ModifierFlag) 0;
|
||||
foreach (var modifier in Enum.GetValues<ModifierFlag>()) {
|
||||
var modifierKey = GetKeyForModifier(modifier);
|
||||
if (modifierKey != VirtualKey.NO_KEY && this.Plugin.KeyState[modifierKey]) {
|
||||
if (modifierKey != VirtualKey.NO_KEY && Plugin.KeyState[modifierKey]) {
|
||||
modifierState |= modifier;
|
||||
}
|
||||
}
|
||||
@@ -392,7 +392,7 @@ internal sealed unsafe class Chat : IDisposable {
|
||||
}
|
||||
|
||||
void Intercept(VirtualKey key, ModifierFlag modifier) {
|
||||
if (!this.Plugin.KeyState.IsVirtualKeyValid(key)) {
|
||||
if (!Plugin.KeyState.IsVirtualKeyValid(key)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ internal sealed unsafe class Chat : IDisposable {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.Plugin.KeyState[key]) {
|
||||
if (!Plugin.KeyState[key]) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -420,7 +420,7 @@ internal sealed unsafe class Chat : IDisposable {
|
||||
}
|
||||
|
||||
foreach (var (key, (_, keybind)) in turnedOff) {
|
||||
this.Plugin.KeyState[key] = false;
|
||||
Plugin.KeyState[key] = false;
|
||||
|
||||
if (!KeybindsToIntercept.TryGetValue(keybind, out var info)) {
|
||||
continue;
|
||||
@@ -455,7 +455,7 @@ internal sealed unsafe class Chat : IDisposable {
|
||||
}
|
||||
|
||||
string? input = null;
|
||||
if (this.Plugin.GameConfig.TryGet(UiControlOption.DirectChat, out bool option) && option) {
|
||||
if (Plugin.GameConfig.TryGet(UiControlOption.DirectChat, out bool option) && option) {
|
||||
if (this._currentCharacter != null) {
|
||||
// FIXME: this whole system sucks
|
||||
var c = *this._currentCharacter;
|
||||
|
||||
@@ -40,7 +40,7 @@ internal sealed unsafe class Context {
|
||||
|
||||
internal Context(Plugin plugin) {
|
||||
this.Plugin = plugin;
|
||||
this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
}
|
||||
|
||||
internal void InviteToNoviceNetwork(string name, ushort world) {
|
||||
|
||||
@@ -71,7 +71,7 @@ internal unsafe class GameFunctions : IDisposable {
|
||||
this.Chat = new Chat(this.Plugin);
|
||||
this.Context = new Context(this.Plugin);
|
||||
|
||||
this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
|
||||
this.ResolveTextCommandPlaceholderHook?.Enable();
|
||||
}
|
||||
@@ -117,7 +117,7 @@ internal unsafe class GameFunctions : IDisposable {
|
||||
}
|
||||
|
||||
private void ListCommand(string name, ushort world, string commandName) {
|
||||
var row = this.Plugin.DataManager.GetExcelSheet<World>()!.GetRow(world);
|
||||
var row = Plugin.DataManager.GetExcelSheet<World>()!.GetRow(world);
|
||||
if (row == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ internal sealed unsafe class Party {
|
||||
|
||||
internal Party(Plugin plugin) {
|
||||
this.Plugin = plugin;
|
||||
this.Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
Plugin.GameInteropProvider.InitializeFromAttributes(this);
|
||||
}
|
||||
|
||||
internal void InviteSameWorld(string name, ushort world, ulong contentId) {
|
||||
|
||||
@@ -27,9 +27,9 @@ internal sealed class ExtraChat : IDisposable {
|
||||
internal ExtraChat(Plugin plugin) {
|
||||
this.Plugin = plugin;
|
||||
|
||||
this.OverrideChannelGate = this.Plugin.Interface.GetIpcSubscriber<OverrideInfo, object>("ExtraChat.OverrideChannelColour");
|
||||
this.ChannelCommandColoursGate = this.Plugin.Interface.GetIpcSubscriber<Dictionary<string, uint>, Dictionary<string, uint>>("ExtraChat.ChannelCommandColours");
|
||||
this.ChannelNamesGate = this.Plugin.Interface.GetIpcSubscriber<Dictionary<Guid, string>, Dictionary<Guid, string>>("ExtraChat.ChannelNames");
|
||||
this.OverrideChannelGate = Plugin.Interface.GetIpcSubscriber<OverrideInfo, object>("ExtraChat.OverrideChannelColour");
|
||||
this.ChannelCommandColoursGate = Plugin.Interface.GetIpcSubscriber<Dictionary<string, uint>, Dictionary<string, uint>>("ExtraChat.ChannelCommandColours");
|
||||
this.ChannelNamesGate = Plugin.Interface.GetIpcSubscriber<Dictionary<Guid, string>, Dictionary<Guid, string>>("ExtraChat.ChannelNames");
|
||||
|
||||
this.OverrideChannelGate.Subscribe(this.OnOverrideChannel);
|
||||
this.ChannelCommandColoursGate.Subscribe(this.OnChannelCommandColours);
|
||||
|
||||
+24
-28
@@ -1,5 +1,4 @@
|
||||
using System.Numerics;
|
||||
using System.Reflection;
|
||||
using ChatTwo.Code;
|
||||
using ChatTwo.Resources;
|
||||
using ChatTwo.Ui;
|
||||
@@ -119,7 +118,7 @@ internal sealed class PayloadHandler {
|
||||
ImGui.Separator();
|
||||
}
|
||||
|
||||
if (!ImGui.BeginMenu(Plugin.Name)) {
|
||||
if (!ImGui.BeginMenu(Plugin.PluginName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -261,7 +260,7 @@ internal sealed class PayloadHandler {
|
||||
}
|
||||
|
||||
private void HoverEventItem(ItemPayload payload) {
|
||||
var item = this.Ui.Plugin.DataManager.GetExcelSheet<EventItem>()?.GetRow(payload.RawItemId);
|
||||
var item = Plugin.DataManager.GetExcelSheet<EventItem>()?.GetRow(payload.RawItemId);
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
@@ -274,7 +273,7 @@ internal sealed class PayloadHandler {
|
||||
this.Log.DrawChunks(name.ToList());
|
||||
ImGui.Separator();
|
||||
|
||||
var help = this.Ui.Plugin.DataManager.GetExcelSheet<EventItemHelp>()?.GetRow(payload.RawItemId);
|
||||
var help = Plugin.DataManager.GetExcelSheet<EventItemHelp>()?.GetRow(payload.RawItemId);
|
||||
if (help != null) {
|
||||
var desc = ChunkUtil.ToChunks(help.Description.ToDalamudString(), ChunkSource.None, null);
|
||||
this.Log.DrawChunks(desc.ToList());
|
||||
@@ -284,7 +283,7 @@ internal sealed class PayloadHandler {
|
||||
private void LeftClickPayload(Chunk chunk, Payload? payload) {
|
||||
switch (payload) {
|
||||
case MapLinkPayload map: {
|
||||
this.Ui.Plugin.GameGui.OpenMapWithMapLink(map);
|
||||
Plugin.GameGui.OpenMapWithMapLink(map);
|
||||
break;
|
||||
}
|
||||
case QuestPayload quest: {
|
||||
@@ -334,24 +333,16 @@ internal sealed class PayloadHandler {
|
||||
}
|
||||
|
||||
var payloads = source.Payloads.Skip(start).Take(end - start + 1).ToList();
|
||||
|
||||
var chatGuiScoped = this.Ui.Plugin.ChatGui;
|
||||
var chatGuiService = chatGuiScoped.GetType()
|
||||
.GetField("chatGuiService", BindingFlags.Instance | BindingFlags.NonPublic)!
|
||||
.GetValue(chatGuiScoped);
|
||||
if (chatGuiService == null) {
|
||||
Plugin.Log.Warning("could not find chatGuiService");
|
||||
return;
|
||||
}
|
||||
|
||||
var field = chatGuiService.GetType().GetField("dalamudLinkHandlers", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (field == null || field.GetValue(chatGuiService) is not Dictionary<(string PluginName, uint CommandId), Action<uint, SeString>> dict || !dict.TryGetValue((link.Plugin, link.CommandId), out var action)) {
|
||||
if (!Plugin.ChatGui.RegisteredLinkHandlers.TryGetValue((link.Plugin, link.CommandId), out var value))
|
||||
{
|
||||
Plugin.Log.Warning("could not find dalamudLinkHandlers");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
action(link.CommandId, new SeString(payloads));
|
||||
try
|
||||
{
|
||||
// Running XivCommon SendChat instantly leads to a game freeze, for whatever reason
|
||||
Plugin.Framework.RunOnTick(() => value.Invoke(link.CommandId, new SeString(payloads)));
|
||||
} catch (Exception ex) {
|
||||
Plugin.Log.Error(ex, "Error executing DalamudLinkPayload handler");
|
||||
}
|
||||
@@ -368,7 +359,7 @@ internal sealed class PayloadHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
var item = this.Ui.Plugin.DataManager.GetExcelSheet<Item>()?.GetRow(payload.ItemId);
|
||||
var item = Plugin.DataManager.GetExcelSheet<Item>()?.GetRow(payload.ItemId);
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
@@ -426,7 +417,7 @@ internal sealed class PayloadHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
var item = this.Ui.Plugin.DataManager.GetExcelSheet<EventItem>()?.GetRow(payload.ItemId);
|
||||
var item = Plugin.DataManager.GetExcelSheet<EventItem>()?.GetRow(payload.ItemId);
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
@@ -450,11 +441,16 @@ internal sealed class PayloadHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawPlayerPopup(Chunk chunk, PlayerPayload player) {
|
||||
private void DrawPlayerPopup(Chunk chunk, PlayerPayload player)
|
||||
{
|
||||
// Possible that GMs return a null payload
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
var world = player.World;
|
||||
|
||||
if (chunk.Message?.Code.Type == ChatType.FreeCompanyLoginLogout) {
|
||||
if (this.Ui.Plugin.ClientState.LocalPlayer?.HomeWorld.GameData is { } homeWorld) {
|
||||
if (Plugin.ClientState.LocalPlayer?.HomeWorld.GameData is { } homeWorld) {
|
||||
world = homeWorld;
|
||||
}
|
||||
}
|
||||
@@ -481,13 +477,13 @@ internal sealed class PayloadHandler {
|
||||
}
|
||||
|
||||
if (world.IsPublic) {
|
||||
var party = this.Ui.Plugin.PartyList;
|
||||
var party = Plugin.PartyList;
|
||||
var leader = (ulong?) party[(int) party.PartyLeaderIndex]?.ContentId;
|
||||
var isLeader = party.Length == 0 || this.Ui.Plugin.ClientState.LocalContentId == leader;
|
||||
var isLeader = party.Length == 0 || Plugin.ClientState.LocalContentId == leader;
|
||||
var member = party.FirstOrDefault(member => member.Name.TextValue == player.PlayerName && member.World.Id == world.RowId);
|
||||
var isInParty = member != default;
|
||||
var inInstance = this.Ui.Plugin.Functions.IsInInstance();
|
||||
var inPartyInstance = this.Ui.Plugin.DataManager.GetExcelSheet<TerritoryType>()!.GetRow(this.Ui.Plugin.ClientState.TerritoryType)?.TerritoryIntendedUse is (41 or 47 or 48 or 52 or 53);
|
||||
var inPartyInstance = Plugin.DataManager.GetExcelSheet<TerritoryType>()!.GetRow(Plugin.ClientState.TerritoryType)?.TerritoryIntendedUse is (41 or 47 or 48 or 52 or 53);
|
||||
if (isLeader) {
|
||||
if (!isInParty) {
|
||||
if (inInstance && inPartyInstance) {
|
||||
@@ -539,14 +535,14 @@ internal sealed class PayloadHandler {
|
||||
}
|
||||
|
||||
if (ImGui.Selectable(Language.Context_Target) && this.FindCharacterForPayload(player) is { } obj) {
|
||||
this.Ui.Plugin.TargetManager.Target = obj;
|
||||
Plugin.TargetManager.Target = obj;
|
||||
}
|
||||
|
||||
// View Party Finder 0x2E
|
||||
}
|
||||
|
||||
private PlayerCharacter? FindCharacterForPayload(PlayerPayload payload) {
|
||||
foreach (var obj in this.Ui.Plugin.ObjectTable) {
|
||||
foreach (var obj in Plugin.ObjectTable) {
|
||||
if (obj is not PlayerCharacter character) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+35
-64
@@ -15,55 +15,22 @@ namespace ChatTwo;
|
||||
public sealed class Plugin : IDalamudPlugin {
|
||||
internal const string PluginName = "Chat 2";
|
||||
|
||||
internal static string Name => PluginName;
|
||||
|
||||
[PluginService]
|
||||
internal static IPluginLog Log { get; private set; }
|
||||
|
||||
[PluginService]
|
||||
internal DalamudPluginInterface Interface { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IChatGui ChatGui { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IClientState ClientState { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal ICommandManager CommandManager { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal ICondition Condition { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IDataManager DataManager { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IFramework Framework { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IGameGui GameGui { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IKeyState KeyState { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IObjectTable ObjectTable { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IPartyList PartyList { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal ITargetManager TargetManager { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal ITextureProvider TextureProvider { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IGameInteropProvider GameInteropProvider { get; init; }
|
||||
|
||||
[PluginService]
|
||||
internal IGameConfig GameConfig { get; init; }
|
||||
[PluginService] internal static IPluginLog Log { get; private set; } = null!;
|
||||
[PluginService] internal static DalamudPluginInterface Interface { get; private set; } = null!;
|
||||
[PluginService] internal static IChatGui ChatGui { get; private set; } = null!;
|
||||
[PluginService] internal static IClientState ClientState { get; private set; } = null!;
|
||||
[PluginService] internal static ICommandManager CommandManager { get; private set; } = null!;
|
||||
[PluginService] internal static ICondition Condition { get; private set; } = null!;
|
||||
[PluginService] internal static IDataManager DataManager { get; private set; } = null!;
|
||||
[PluginService] internal static IFramework Framework { get; set; } = null!;
|
||||
[PluginService] internal static IGameGui GameGui { get; private set; } = null!;
|
||||
[PluginService] internal static IKeyState KeyState { get; private set; } = null!;
|
||||
[PluginService] internal static IObjectTable ObjectTable { get; private set; } = null!;
|
||||
[PluginService] internal static IPartyList PartyList { get; private set; } = null!;
|
||||
[PluginService] internal static ITargetManager TargetManager { get; private set; } = null!;
|
||||
[PluginService] internal static ITextureProvider TextureProvider { get; private set; } = null!;
|
||||
[PluginService] internal static IGameInteropProvider GameInteropProvider { get; private set; } = null!;
|
||||
[PluginService] internal static IGameConfig GameConfig { get; private set; } = null!;
|
||||
|
||||
internal Configuration Config { get; }
|
||||
internal Commands Commands { get; }
|
||||
@@ -83,39 +50,43 @@ public sealed class Plugin : IDalamudPlugin {
|
||||
public Plugin() {
|
||||
this.GameStarted = Process.GetCurrentProcess().StartTime.ToUniversalTime();
|
||||
|
||||
this.Config = this.Interface!.GetPluginConfig() as Configuration ?? new Configuration();
|
||||
this.Config = Interface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||
this.Config.Migrate();
|
||||
|
||||
if (this.Config.Tabs.Count == 0) {
|
||||
this.Config.Tabs.Add(TabsUtil.VanillaGeneral);
|
||||
}
|
||||
|
||||
this.LanguageChanged(this.Interface.UiLanguage);
|
||||
this.LanguageChanged(Interface.UiLanguage);
|
||||
|
||||
this.Commands = new Commands(this);
|
||||
this.Common = new XivCommonBase(this.Interface);
|
||||
this.TextureCache = new TextureCache(this.TextureProvider!);
|
||||
this.Common = new XivCommonBase(Interface);
|
||||
this.TextureCache = new TextureCache(TextureProvider);
|
||||
this.Functions = new GameFunctions.GameFunctions(this);
|
||||
this.Store = new Store(this);
|
||||
this.Ipc = new IpcManager(this.Interface);
|
||||
this.Ipc = new IpcManager(Interface);
|
||||
this.ExtraChat = new ExtraChat(this);
|
||||
this.Ui = new PluginUi(this);
|
||||
Ui.BuildFonts();
|
||||
|
||||
this.Store = new Store(this); // requires Ui
|
||||
|
||||
// let all the other components register, then initialise commands
|
||||
this.Commands.Initialise();
|
||||
|
||||
if (this.Interface.Reason is not PluginLoadReason.Boot) {
|
||||
if (Interface.Reason is not PluginLoadReason.Boot) {
|
||||
this.Store.FilterAllTabs(false);
|
||||
}
|
||||
|
||||
this.Framework!.Update += this.FrameworkUpdate;
|
||||
this.Interface.LanguageChanged += this.LanguageChanged;
|
||||
Framework.Update += FrameworkUpdate;
|
||||
Interface.UiBuilder.Draw += Ui.Draw;
|
||||
Interface.LanguageChanged += LanguageChanged;
|
||||
}
|
||||
#pragma warning restore CS8618
|
||||
|
||||
public void Dispose() {
|
||||
this.Interface.LanguageChanged -= this.LanguageChanged;
|
||||
this.Framework.Update -= this.FrameworkUpdate;
|
||||
Interface.LanguageChanged -= LanguageChanged;
|
||||
Interface.UiBuilder.Draw -= Ui.Draw;
|
||||
Framework.Update -= FrameworkUpdate;
|
||||
GameFunctions.GameFunctions.SetChatInteractable(true);
|
||||
|
||||
this.Ui.Dispose();
|
||||
@@ -129,7 +100,7 @@ public sealed class Plugin : IDalamudPlugin {
|
||||
}
|
||||
|
||||
internal void SaveConfig() {
|
||||
this.Interface.SavePluginConfig(this.Config);
|
||||
Interface.SavePluginConfig(this.Config);
|
||||
}
|
||||
|
||||
internal void LanguageChanged(string langCode) {
|
||||
@@ -149,11 +120,11 @@ public sealed class Plugin : IDalamudPlugin {
|
||||
};
|
||||
|
||||
private void FrameworkUpdate(IFramework framework) {
|
||||
if (this.DeferredSaveFrames >= 0 && this.DeferredSaveFrames-- == 0) {
|
||||
this.SaveConfig();
|
||||
if (DeferredSaveFrames >= 0 && DeferredSaveFrames-- == 0) {
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
if (!this.Config.HideChat) {
|
||||
if (!Config.HideChat) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
+106
-211
@@ -1,8 +1,9 @@
|
||||
using System.Numerics;
|
||||
using System.Runtime.InteropServices;
|
||||
using ChatTwo.Ui;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.Interface.GameFonts;
|
||||
using Dalamud.Interface.ManagedFontAtlas;
|
||||
using Dalamud.Interface.Utility;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace ChatTwo;
|
||||
@@ -14,18 +15,18 @@ internal sealed class PluginUi : IDisposable {
|
||||
internal bool ScreenshotMode;
|
||||
internal string Salt { get; }
|
||||
|
||||
internal GameFontHandle? Axis { get; private set; }
|
||||
internal GameFontHandle? AxisItalic { get; private set; }
|
||||
internal IFontHandle Axis { get; private set; }
|
||||
internal IFontHandle AxisItalic { get; private set; }
|
||||
|
||||
internal ImFontPtr? RegularFont { get; private set; }
|
||||
internal ImFontPtr? ItalicFont { get; private set; }
|
||||
internal IFontHandle RegularFont { get; private set; }
|
||||
internal IFontHandle? ItalicFont { get; private set; }
|
||||
internal Vector4 DefaultText { get; private set; }
|
||||
|
||||
internal Tab? CurrentTab {
|
||||
get {
|
||||
var i = this._chatLog.LastTab;
|
||||
if (i > -1 && i < this.Plugin.Config.Tabs.Count) {
|
||||
return this.Plugin.Config.Tabs[i];
|
||||
var i = _chatLog.LastTab;
|
||||
if (i > -1 && i < Plugin.Config.Tabs.Count) {
|
||||
return Plugin.Config.Tabs[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -33,141 +34,74 @@ internal sealed class PluginUi : IDisposable {
|
||||
}
|
||||
|
||||
private List<IUiComponent> Components { get; }
|
||||
private ImFontConfigPtr _fontCfg;
|
||||
private ImFontConfigPtr _fontCfgMerge;
|
||||
private (GCHandle, int, float) _regularFont;
|
||||
private (GCHandle, int, float) _italicFont;
|
||||
private (GCHandle, int, float) _jpFont;
|
||||
private (GCHandle, int) _gameSymFont;
|
||||
|
||||
private ImVector _ranges;
|
||||
private ImVector _jpRange;
|
||||
private FaceData _regularFont;
|
||||
private FaceData? _italicFont;
|
||||
private FaceData _jpFont;
|
||||
private FaceData _gameSymFont;
|
||||
|
||||
private GCHandle _symRange = GCHandle.Alloc(
|
||||
new ushort[] {
|
||||
0xE020,
|
||||
0xE0DB,
|
||||
0,
|
||||
},
|
||||
GCHandleType.Pinned
|
||||
);
|
||||
private ushort[] _ranges;
|
||||
private ushort[] _jpRange;
|
||||
private ushort[] _symRange = [0xE020, 0xE0DB, 0];
|
||||
|
||||
private readonly ChatLog _chatLog;
|
||||
|
||||
internal unsafe PluginUi(Plugin plugin) {
|
||||
this.Plugin = plugin;
|
||||
this.Salt = new Random().Next().ToString();
|
||||
internal PluginUi(Plugin plugin) {
|
||||
Plugin = plugin;
|
||||
Salt = new Random().Next().ToString();
|
||||
|
||||
this._chatLog = new ChatLog(this);
|
||||
this.Components = new List<IUiComponent> {
|
||||
_chatLog = new ChatLog(this);
|
||||
Components = new List<IUiComponent> {
|
||||
new Settings(this),
|
||||
this._chatLog,
|
||||
_chatLog,
|
||||
};
|
||||
|
||||
this._fontCfg = new ImFontConfigPtr(ImGuiNative.ImFontConfig_ImFontConfig()) {
|
||||
FontDataOwnedByAtlas = false,
|
||||
};
|
||||
|
||||
this._fontCfgMerge = new ImFontConfigPtr(ImGuiNative.ImFontConfig_ImFontConfig()) {
|
||||
FontDataOwnedByAtlas = false,
|
||||
MergeMode = true,
|
||||
};
|
||||
|
||||
this.SetUpRanges();
|
||||
this.SetUpUserFonts();
|
||||
|
||||
var gameSym = new HttpClient().GetAsync("https://img.finalfantasyxiv.com/lds/pc/global/fonts/FFXIV_Lodestone_SSF.ttf")
|
||||
.Result
|
||||
.Content
|
||||
.ReadAsByteArrayAsync()
|
||||
.Result;
|
||||
this._gameSymFont = (
|
||||
GCHandle.Alloc(gameSym, GCHandleType.Pinned),
|
||||
gameSym.Length
|
||||
);
|
||||
_gameSymFont = new FaceData(gameSym);
|
||||
|
||||
var uiBuilder = this.Plugin.Interface.UiBuilder;
|
||||
uiBuilder.DisableCutsceneUiHide = true;
|
||||
uiBuilder.DisableGposeUiHide = true;
|
||||
|
||||
uiBuilder.BuildFonts += this.BuildFonts;
|
||||
uiBuilder.Draw += this.Draw;
|
||||
|
||||
uiBuilder.RebuildFonts();
|
||||
Plugin.Interface.UiBuilder.DisableCutsceneUiHide = true;
|
||||
Plugin.Interface.UiBuilder.DisableGposeUiHide = true;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
this.Plugin.Interface.UiBuilder.Draw -= this.Draw;
|
||||
this.Plugin.Interface.UiBuilder.BuildFonts -= this.BuildFonts;
|
||||
|
||||
foreach (var component in this.Components) {
|
||||
foreach (var component in Components) {
|
||||
component.Dispose();
|
||||
}
|
||||
|
||||
if (this._regularFont.Item1.IsAllocated) {
|
||||
this._regularFont.Item1.Free();
|
||||
}
|
||||
|
||||
if (this._italicFont.Item1.IsAllocated) {
|
||||
this._italicFont.Item1.Free();
|
||||
}
|
||||
|
||||
if (this._jpFont.Item1.IsAllocated) {
|
||||
this._jpFont.Item1.Free();
|
||||
}
|
||||
|
||||
if (this._gameSymFont.Item1.IsAllocated) {
|
||||
this._gameSymFont.Item1.Free();
|
||||
}
|
||||
|
||||
if (this._symRange.IsAllocated) {
|
||||
this._symRange.Free();
|
||||
}
|
||||
|
||||
this._fontCfg.Destroy();
|
||||
this._fontCfgMerge.Destroy();
|
||||
}
|
||||
|
||||
private void Draw() {
|
||||
if (this.Plugin.Config.DatabaseMigration != Configuration.LatestDbVersion) {
|
||||
public void Draw() {
|
||||
if (Plugin.Config.DatabaseMigration != Configuration.LatestDbVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.Plugin.Interface.UiBuilder.DisableUserUiHide = !this.Plugin.Config.HideWhenUiHidden;
|
||||
this.DefaultText = ImGui.GetStyle().Colors[(int) ImGuiCol.Text];
|
||||
Plugin.Interface.UiBuilder.DisableUserUiHide = !Plugin.Config.HideWhenUiHidden;
|
||||
DefaultText = ImGui.GetStyle().Colors[(int) ImGuiCol.Text];
|
||||
|
||||
var font = this.RegularFont.HasValue;
|
||||
var pushed = font && this.Plugin.Config.FontsEnabled;
|
||||
var axis = !this.Plugin.Config.FontsEnabled && (this.Axis?.Available ?? false);
|
||||
|
||||
if (pushed) {
|
||||
ImGui.PushFont(this.RegularFont!.Value);
|
||||
} else if (axis) {
|
||||
ImGui.PushFont(this.Axis!.ImFont);
|
||||
}
|
||||
|
||||
foreach (var component in this.Components) {
|
||||
try {
|
||||
component.Draw();
|
||||
} catch (Exception ex) {
|
||||
Plugin.Log.Error(ex, "Error drawing component");
|
||||
using ((Plugin.Config.FontsEnabled ? RegularFont : Axis).Push())
|
||||
{
|
||||
foreach (var component in Components) {
|
||||
try {
|
||||
component.Draw();
|
||||
} catch (Exception ex) {
|
||||
Plugin.Log.Error(ex, "Error drawing component");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pushed || axis) {
|
||||
ImGui.PopFont();
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] GetResource(string name) {
|
||||
var stream = this.GetType().Assembly.GetManifestResourceStream(name)!;
|
||||
var stream = GetType().Assembly.GetManifestResourceStream(name)!;
|
||||
var memory = new MemoryStream();
|
||||
stream.CopyTo(memory);
|
||||
return memory.ToArray();
|
||||
}
|
||||
|
||||
private unsafe void SetUpRanges() {
|
||||
ImVector BuildRange(IReadOnlyList<ushort>? chars, params IntPtr[] ranges) {
|
||||
ushort[] BuildRange(IReadOnlyList<ushort>? chars, params IntPtr[] ranges) {
|
||||
var builder = new ImFontGlyphRangesBuilderPtr(ImGuiNative.ImFontGlyphRangesBuilder_ImFontGlyphRangesBuilder());
|
||||
// text
|
||||
foreach (var range in ranges) {
|
||||
@@ -200,12 +134,7 @@ internal sealed class PluginUi : IDisposable {
|
||||
}
|
||||
|
||||
builder.AddChar('⓪');
|
||||
|
||||
var result = new ImVector();
|
||||
builder.BuildRanges(out result);
|
||||
builder.Destroy();
|
||||
|
||||
return result;
|
||||
return builder.BuildRangesToArray();
|
||||
}
|
||||
|
||||
var ranges = new List<IntPtr> {
|
||||
@@ -213,153 +142,119 @@ internal sealed class PluginUi : IDisposable {
|
||||
};
|
||||
|
||||
foreach (var extraRange in Enum.GetValues<ExtraGlyphRanges>()) {
|
||||
if (this.Plugin.Config.ExtraGlyphRanges.HasFlag(extraRange)) {
|
||||
if (Plugin.Config.ExtraGlyphRanges.HasFlag(extraRange)) {
|
||||
ranges.Add(extraRange.Range());
|
||||
}
|
||||
}
|
||||
|
||||
this._ranges = BuildRange(null, ranges.ToArray());
|
||||
this._jpRange = BuildRange(GlyphRangesJapanese.GlyphRanges);
|
||||
_ranges = BuildRange(null, ranges.ToArray());
|
||||
_jpRange = BuildRange(GlyphRangesJapanese.GlyphRanges);
|
||||
}
|
||||
|
||||
private void SetUpUserFonts() {
|
||||
FontData? fontData = null;
|
||||
if (this.Plugin.Config.GlobalFont.StartsWith(Fonts.IncludedIndicator)) {
|
||||
var globalFont = Fonts.GlobalFonts.FirstOrDefault(font => font.Name == this.Plugin.Config.GlobalFont);
|
||||
if (Plugin.Config.GlobalFont.StartsWith(Fonts.IncludedIndicator)) {
|
||||
var globalFont = Fonts.GlobalFonts.FirstOrDefault(font => font.Name == Plugin.Config.GlobalFont);
|
||||
if (globalFont != null) {
|
||||
var regular = new FaceData(this.GetResource(globalFont.ResourcePath), 1f);
|
||||
var italic = new FaceData(this.GetResource(globalFont.ResourcePathItalic), 1f);
|
||||
var regular = new FaceData(GetResource(globalFont.ResourcePath));
|
||||
var italic = new FaceData(GetResource(globalFont.ResourcePathItalic));
|
||||
fontData = new FontData(regular, italic);
|
||||
}
|
||||
} else {
|
||||
fontData = Fonts.GetFont(this.Plugin.Config.GlobalFont, true);
|
||||
fontData = Fonts.GetFont(Plugin.Config.GlobalFont, true);
|
||||
}
|
||||
|
||||
if (fontData == null) {
|
||||
this.Plugin.Config.GlobalFont = Fonts.GlobalFonts[0].Name;
|
||||
this.Plugin.SaveConfig();
|
||||
Plugin.Config.GlobalFont = Fonts.GlobalFonts[0].Name;
|
||||
Plugin.SaveConfig();
|
||||
|
||||
var globalFont = Fonts.GlobalFonts[0];
|
||||
var regular = new FaceData(this.GetResource(globalFont.ResourcePath), 1f);
|
||||
var italic = new FaceData(this.GetResource(globalFont.ResourcePathItalic), 1f);
|
||||
var regular = new FaceData(GetResource(globalFont.ResourcePath));
|
||||
var italic = new FaceData(GetResource(globalFont.ResourcePathItalic));
|
||||
fontData = new FontData(regular, italic);
|
||||
}
|
||||
|
||||
if (this._regularFont.Item1.IsAllocated) {
|
||||
this._regularFont.Item1.Free();
|
||||
}
|
||||
|
||||
if (this._italicFont.Item1.IsAllocated) {
|
||||
this._italicFont.Item1.Free();
|
||||
}
|
||||
|
||||
this._regularFont = (
|
||||
GCHandle.Alloc(fontData.Regular.Data, GCHandleType.Pinned),
|
||||
fontData.Regular.Data.Length,
|
||||
fontData.Regular.Ratio
|
||||
);
|
||||
|
||||
this._italicFont = (
|
||||
GCHandle.Alloc(fontData.Italic!.Data, GCHandleType.Pinned),
|
||||
fontData.Italic.Data.Length,
|
||||
fontData.Italic.Ratio
|
||||
);
|
||||
_regularFont = fontData.Regular;
|
||||
_italicFont = fontData.Italic ?? null;
|
||||
|
||||
FontData? jpFontData = null;
|
||||
if (this.Plugin.Config.JapaneseFont.StartsWith(Fonts.IncludedIndicator)) {
|
||||
var jpFont = Fonts.JapaneseFonts.FirstOrDefault(item => item.Item1 == this.Plugin.Config.JapaneseFont);
|
||||
if (Plugin.Config.JapaneseFont.StartsWith(Fonts.IncludedIndicator)) {
|
||||
var jpFont = Fonts.JapaneseFonts.FirstOrDefault(item => item.Item1 == Plugin.Config.JapaneseFont);
|
||||
if (jpFont != default) {
|
||||
jpFontData = new FontData(
|
||||
new FaceData(this.GetResource(jpFont.Item2), 1f),
|
||||
new FaceData(GetResource(jpFont.Item2)),
|
||||
null
|
||||
);
|
||||
}
|
||||
} else {
|
||||
jpFontData = Fonts.GetFont(this.Plugin.Config.JapaneseFont, false);
|
||||
jpFontData = Fonts.GetFont(Plugin.Config.JapaneseFont, false);
|
||||
}
|
||||
|
||||
if (jpFontData == null) {
|
||||
this.Plugin.Config.JapaneseFont = Fonts.JapaneseFonts[0].Item1;
|
||||
this.Plugin.SaveConfig();
|
||||
Plugin.Config.JapaneseFont = Fonts.JapaneseFonts[0].Item1;
|
||||
Plugin.SaveConfig();
|
||||
|
||||
var jpFont = Fonts.JapaneseFonts[0];
|
||||
jpFontData = new FontData(
|
||||
new FaceData(this.GetResource(jpFont.Item2), 1f),
|
||||
new FaceData(GetResource(jpFont.Item2)),
|
||||
null
|
||||
);
|
||||
}
|
||||
|
||||
if (this._jpFont.Item1.IsAllocated) {
|
||||
this._jpFont.Item1.Free();
|
||||
}
|
||||
|
||||
this._jpFont = (
|
||||
GCHandle.Alloc(jpFontData.Regular.Data, GCHandleType.Pinned),
|
||||
jpFontData.Regular.Data.Length,
|
||||
jpFontData.Regular.Ratio
|
||||
);
|
||||
_jpFont = jpFontData.Regular;
|
||||
}
|
||||
|
||||
private void BuildFonts() {
|
||||
this.RegularFont = null;
|
||||
this.ItalicFont = null;
|
||||
public void BuildFonts() {
|
||||
SetUpRanges();
|
||||
SetUpUserFonts();
|
||||
|
||||
this.SetUpRanges();
|
||||
this.SetUpUserFonts();
|
||||
|
||||
this.Axis = this.Plugin.Interface.UiBuilder.GetGameFontHandle(new GameFontStyle(GameFontFamily.Axis, this.Plugin.Config.FontSize));
|
||||
this.AxisItalic = this.Plugin.Interface.UiBuilder.GetGameFontHandle(new GameFontStyle(GameFontFamily.Axis, this.Plugin.Config.FontSize) {
|
||||
SkewStrength = this.Plugin.Config.FontSize / 6,
|
||||
Axis = Plugin.Interface.UiBuilder.FontAtlas.NewGameFontHandle(new GameFontStyle(GameFontFamily.Axis, Plugin.Config.FontSize));
|
||||
AxisItalic = Plugin.Interface.UiBuilder.FontAtlas.NewGameFontHandle(new GameFontStyle(GameFontFamily.Axis, Plugin.Config.FontSize)
|
||||
{
|
||||
SkewStrength = Plugin.Config.FontSize / 6
|
||||
});
|
||||
|
||||
// load regular noto sans and merge in jp + game icons
|
||||
this.RegularFont = ImGui.GetIO().Fonts.AddFontFromMemoryTTF(
|
||||
this._regularFont.Item1.AddrOfPinnedObject(),
|
||||
this._regularFont.Item2,
|
||||
this.Plugin.Config.FontSize,
|
||||
this._fontCfg,
|
||||
this._ranges.Data
|
||||
);
|
||||
RegularFont = Plugin.Interface.UiBuilder.FontAtlas.NewDelegateFontHandle(
|
||||
e => e.OnPreBuild(
|
||||
tk =>
|
||||
{
|
||||
var config = new SafeFontConfig { SizePx = Plugin.Config.FontSize, GlyphRanges = _ranges };
|
||||
config.MergeFont = tk.AddFontFromMemory(_regularFont.Data, config, "ChatTwo2 RegularFont");
|
||||
|
||||
ImGui.GetIO().Fonts.AddFontFromMemoryTTF(
|
||||
this._jpFont.Item1.AddrOfPinnedObject(),
|
||||
this._jpFont.Item2,
|
||||
this.Plugin.Config.JapaneseFontSize,
|
||||
this._fontCfgMerge,
|
||||
this._jpRange.Data
|
||||
);
|
||||
config.SizePx = Plugin.Config.JapaneseFontSize;
|
||||
config.GlyphRanges = _jpRange;
|
||||
tk.AddFontFromMemory(_jpFont.Data, config, "ChatTwo2 JP Regular");
|
||||
|
||||
ImGui.GetIO().Fonts.AddFontFromMemoryTTF(
|
||||
this._gameSymFont.Item1.AddrOfPinnedObject(),
|
||||
this._gameSymFont.Item2,
|
||||
this.Plugin.Config.SymbolsFontSize,
|
||||
this._fontCfgMerge,
|
||||
this._symRange.AddrOfPinnedObject()
|
||||
);
|
||||
config.SizePx = Plugin.Config.SymbolsFontSize;
|
||||
config.GlyphRanges = _symRange;
|
||||
tk.AddFontFromMemory(_gameSymFont.Data, config, "ChatTwo2 Sym Font");
|
||||
|
||||
tk.Font = config.MergeFont;
|
||||
}
|
||||
));
|
||||
|
||||
// load italic noto sans and merge in jp + game icons
|
||||
this.ItalicFont = ImGui.GetIO().Fonts.AddFontFromMemoryTTF(
|
||||
this._italicFont.Item1.AddrOfPinnedObject(),
|
||||
this._italicFont.Item2,
|
||||
this.Plugin.Config.FontSize,
|
||||
this._fontCfg,
|
||||
this._ranges.Data
|
||||
);
|
||||
ItalicFont = null;
|
||||
if (_italicFont != null)
|
||||
{
|
||||
ItalicFont = Plugin.Interface.UiBuilder.FontAtlas.NewDelegateFontHandle(
|
||||
e => e.OnPreBuild(
|
||||
tk =>
|
||||
{
|
||||
var config = new SafeFontConfig { SizePx = Plugin.Config.FontSize, GlyphRanges = _ranges };
|
||||
config.MergeFont = tk.AddFontFromMemory(_italicFont.Data, config, "ChatTwo2 ItalicFont");
|
||||
|
||||
ImGui.GetIO().Fonts.AddFontFromMemoryTTF(
|
||||
this._jpFont.Item1.AddrOfPinnedObject(),
|
||||
this._jpFont.Item2,
|
||||
this.Plugin.Config.JapaneseFontSize,
|
||||
this._fontCfgMerge,
|
||||
this._jpRange.Data
|
||||
);
|
||||
config.SizePx = Plugin.Config.JapaneseFontSize;
|
||||
config.GlyphRanges = _jpRange;
|
||||
tk.AddFontFromMemory(_jpFont.Data, config, "ChatTwo2 JP Regular");
|
||||
|
||||
ImGui.GetIO().Fonts.AddFontFromMemoryTTF(
|
||||
this._gameSymFont.Item1.AddrOfPinnedObject(),
|
||||
this._gameSymFont.Item2,
|
||||
this.Plugin.Config.SymbolsFontSize,
|
||||
this._fontCfgMerge,
|
||||
this._symRange.AddrOfPinnedObject()
|
||||
);
|
||||
config.SizePx = Plugin.Config.SymbolsFontSize;
|
||||
config.GlyphRanges = _symRange;
|
||||
tk.AddFontFromMemory(_gameSymFont.Data, config, "ChatTwo2 Sym Font");
|
||||
|
||||
tk.Font = config.MergeFont;
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+16
-16
@@ -28,7 +28,7 @@ internal class Store : IDisposable {
|
||||
|
||||
private ulong CurrentContentId {
|
||||
get {
|
||||
var contentId = this.Plugin.ClientState.LocalContentId;
|
||||
var contentId = Plugin.ClientState.LocalContentId;
|
||||
return contentId == 0 ? this.LastContentId : contentId;
|
||||
}
|
||||
}
|
||||
@@ -143,23 +143,23 @@ internal class Store : IDisposable {
|
||||
|
||||
this.MigrateWrapper();
|
||||
|
||||
this.Plugin.ChatGui.ChatMessageUnhandled += this.ChatMessage;
|
||||
this.Plugin.Framework.Update += this.GetMessageInfo;
|
||||
this.Plugin.Framework.Update += this.UpdateReceiver;
|
||||
this.Plugin.ClientState.Logout += this.Logout;
|
||||
Plugin.ChatGui.ChatMessageUnhandled += this.ChatMessage;
|
||||
Plugin.Framework.Update += this.GetMessageInfo;
|
||||
Plugin.Framework.Update += this.UpdateReceiver;
|
||||
Plugin.ClientState.Logout += this.Logout;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
this.Plugin.ClientState.Logout -= this.Logout;
|
||||
this.Plugin.Framework.Update -= this.UpdateReceiver;
|
||||
this.Plugin.Framework.Update -= this.GetMessageInfo;
|
||||
this.Plugin.ChatGui.ChatMessageUnhandled -= this.ChatMessage;
|
||||
Plugin.ClientState.Logout -= this.Logout;
|
||||
Plugin.Framework.Update -= this.UpdateReceiver;
|
||||
Plugin.Framework.Update -= this.GetMessageInfo;
|
||||
Plugin.ChatGui.ChatMessageUnhandled -= this.ChatMessage;
|
||||
|
||||
this.Database.Dispose();
|
||||
}
|
||||
|
||||
private ILiteDatabase Connect() {
|
||||
var dir = this.Plugin.Interface.ConfigDirectory;
|
||||
var dir = Plugin.Interface.ConfigDirectory;
|
||||
dir.Create();
|
||||
|
||||
var dbPath = Path.Join(dir.FullName, "chat.db");
|
||||
@@ -181,7 +181,7 @@ internal class Store : IDisposable {
|
||||
}
|
||||
|
||||
private void UpdateReceiver(IFramework framework) {
|
||||
var contentId = this.Plugin.ClientState.LocalContentId;
|
||||
var contentId = Plugin.ClientState.LocalContentId;
|
||||
if (contentId != 0) {
|
||||
this.LastContentId = contentId;
|
||||
}
|
||||
@@ -209,7 +209,7 @@ internal class Store : IDisposable {
|
||||
|
||||
private void MigrateDraw() {
|
||||
ImGui.SetNextWindowSizeConstraints(new Vector2(450, 0), new Vector2(450, float.MaxValue));
|
||||
if (!ImGui.Begin($"{Plugin.Name}##migration-window", ImGuiWindowFlags.AlwaysAutoResize)) {
|
||||
if (!ImGui.Begin($"{Plugin.PluginName}##migration-window", ImGuiWindowFlags.AlwaysAutoResize)) {
|
||||
ImGui.End();
|
||||
return;
|
||||
}
|
||||
@@ -229,13 +229,13 @@ internal class Store : IDisposable {
|
||||
|
||||
internal void MigrateWrapper() {
|
||||
if (this.Plugin.Config.DatabaseMigration < Configuration.LatestDbVersion) {
|
||||
this.Plugin.Interface.UiBuilder.Draw += this.MigrateDraw;
|
||||
Plugin.Interface.UiBuilder.Draw += this.MigrateDraw;
|
||||
}
|
||||
|
||||
try {
|
||||
this.Migrate();
|
||||
} finally {
|
||||
this.Plugin.Interface.UiBuilder.Draw -= this.MigrateDraw;
|
||||
Plugin.Interface.UiBuilder.Draw -= this.MigrateDraw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -365,7 +365,7 @@ internal class Store : IDisposable {
|
||||
var messageChunks = ChunkUtil.ToChunks(message, ChunkSource.Content, chatCode.Type).ToList();
|
||||
|
||||
var msg = new Message(this.CurrentContentId, chatCode, senderChunks, messageChunks, sender, message);
|
||||
this.AddMessage(msg, this.Plugin.Ui.CurrentTab);
|
||||
this.AddMessage(msg, this.Plugin.Ui.CurrentTab ?? null);
|
||||
|
||||
var idx = this.Plugin.Functions.GetCurrentChatLogEntryIndex();
|
||||
if (idx != null) {
|
||||
@@ -397,7 +397,7 @@ internal class Store : IDisposable {
|
||||
return cached;
|
||||
}
|
||||
|
||||
var logKind = this.Plugin.DataManager.GetExcelSheet<LogKind>()!.GetRow((ushort) type);
|
||||
var logKind = Plugin.DataManager.GetExcelSheet<LogKind>()!.GetRow((ushort) type);
|
||||
|
||||
if (logKind == null) {
|
||||
return null;
|
||||
|
||||
+28
-37
@@ -62,16 +62,16 @@ internal sealed class ChatLog : IUiComponent {
|
||||
this.Ui.Plugin.Commands.Register("/clearlog2", "Clear the Chat 2 chat log").Execute += this.ClearLog;
|
||||
this.Ui.Plugin.Commands.Register("/chat2").Execute += this.ToggleChat;
|
||||
|
||||
this._fontIcon = this.Ui.Plugin.TextureProvider.GetTextureFromGame("common/font/fonticon_ps5.tex");
|
||||
this._fontIcon = Plugin.TextureProvider.GetTextureFromGame("common/font/fonticon_ps5.tex");
|
||||
|
||||
this.Ui.Plugin.Functions.Chat.Activated += this.Activated;
|
||||
this.Ui.Plugin.ClientState.Login += this.Login;
|
||||
this.Ui.Plugin.ClientState.Logout += this.Logout;
|
||||
Plugin.ClientState.Login += this.Login;
|
||||
Plugin.ClientState.Logout += this.Logout;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
this.Ui.Plugin.ClientState.Logout -= this.Logout;
|
||||
this.Ui.Plugin.ClientState.Login -= this.Login;
|
||||
Plugin.ClientState.Logout -= this.Logout;
|
||||
Plugin.ClientState.Login -= this.Login;
|
||||
this.Ui.Plugin.Functions.Chat.Activated -= this.Activated;
|
||||
this._fontIcon?.Dispose();
|
||||
this.Ui.Plugin.Commands.Register("/chat2").Execute -= this.ToggleChat;
|
||||
@@ -151,7 +151,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
}
|
||||
|
||||
private bool IsValidCommand(string command) {
|
||||
return this.Ui.Plugin.CommandManager.Commands.ContainsKey(command)
|
||||
return Plugin.CommandManager.Commands.ContainsKey(command)
|
||||
|| this.AllCommands.Contains(command);
|
||||
}
|
||||
|
||||
@@ -164,9 +164,9 @@ internal sealed class ChatLog : IUiComponent {
|
||||
|
||||
break;
|
||||
case "help":
|
||||
this.Ui.Plugin.ChatGui.Print("- /clearlog2: clears the active tab's log");
|
||||
this.Ui.Plugin.ChatGui.Print("- /clearlog2 all: clears all tabs' logs and the global history");
|
||||
this.Ui.Plugin.ChatGui.Print("- /clearlog2 help: shows this help");
|
||||
Plugin.ChatGui.Print("- /clearlog2: clears the active tab's log");
|
||||
Plugin.ChatGui.Print("- /clearlog2 all: clears all tabs' logs and the global history");
|
||||
Plugin.ChatGui.Print("- /clearlog2 help: shows this help");
|
||||
|
||||
break;
|
||||
default:
|
||||
@@ -207,7 +207,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
this.TextCommandChannels.Clear();
|
||||
|
||||
foreach (var input in Enum.GetValues<InputChannel>()) {
|
||||
var commands = input.TextCommands(this.Ui.Plugin.DataManager);
|
||||
var commands = input.TextCommands(Plugin.DataManager);
|
||||
if (commands == null) {
|
||||
continue;
|
||||
}
|
||||
@@ -218,7 +218,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
}
|
||||
}
|
||||
|
||||
var echo = this.Ui.Plugin.DataManager.GetExcelSheet<TextCommand>()?.GetRow(116);
|
||||
var echo = Plugin.DataManager.GetExcelSheet<TextCommand>()?.GetRow(116);
|
||||
if (echo != null) {
|
||||
this.AddTextCommandChannel(echo, ChatType.Echo);
|
||||
}
|
||||
@@ -232,7 +232,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
}
|
||||
|
||||
private void SetUpAllCommands() {
|
||||
if (this.Ui.Plugin.DataManager.GetExcelSheet<TextCommand>() is not { } commands) {
|
||||
if (Plugin.DataManager.GetExcelSheet<TextCommand>() is not { } commands) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -334,16 +334,14 @@ internal sealed class ChatLog : IUiComponent {
|
||||
|
||||
private bool CutsceneActive {
|
||||
get {
|
||||
var condition = this.Ui.Plugin.Condition;
|
||||
return condition[ConditionFlag.OccupiedInCutSceneEvent]
|
||||
|| condition[ConditionFlag.WatchingCutscene78];
|
||||
return Plugin.Condition[ConditionFlag.OccupiedInCutSceneEvent]
|
||||
|| Plugin.Condition[ConditionFlag.WatchingCutscene78];
|
||||
}
|
||||
}
|
||||
|
||||
private bool GposeActive {
|
||||
get {
|
||||
var condition = this.Ui.Plugin.Condition;
|
||||
return condition[ConditionFlag.WatchingCutscene];
|
||||
return Plugin.Condition[ConditionFlag.WatchingCutscene];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,7 +390,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.Ui.Plugin.Config.HideWhenNotLoggedIn && !this.Ui.Plugin.ClientState.IsLoggedIn) {
|
||||
if (this.Ui.Plugin.Config.HideWhenNotLoggedIn && !Plugin.ClientState.IsLoggedIn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -415,7 +413,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
|
||||
ImGui.SetNextWindowSize(new Vector2(500, 250) * ImGuiHelpers.GlobalScale, ImGuiCond.FirstUseEver);
|
||||
|
||||
if (!ImGui.Begin($"{Plugin.Name}###chat2", flags)) {
|
||||
if (!ImGui.Begin($"{Plugin.PluginName}###chat2", flags)) {
|
||||
this._lastViewport = ImGui.GetWindowViewport().NativePtr;
|
||||
this._wasDocked = ImGui.IsWindowDocked();
|
||||
ImGui.End();
|
||||
@@ -445,7 +443,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, Vector2.Zero);
|
||||
try {
|
||||
if (this._tellTarget != null) {
|
||||
var world = this.Ui.Plugin.DataManager.GetExcelSheet<World>()
|
||||
var world = Plugin.DataManager.GetExcelSheet<World>()
|
||||
?.GetRow(this._tellTarget.World)
|
||||
?.Name
|
||||
?.RawString ?? "???";
|
||||
@@ -493,7 +491,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
|
||||
if (ImGui.BeginPopup(ChatChannelPicker)) {
|
||||
foreach (var channel in Enum.GetValues<InputChannel>()) {
|
||||
var name = this.Ui.Plugin.DataManager.GetExcelSheet<LogFilter>()!
|
||||
var name = Plugin.DataManager.GetExcelSheet<LogFilter>()!
|
||||
.FirstOrDefault(row => row.LogKind == (byte) channel.ToChatType())
|
||||
?.Name
|
||||
?.RawString ?? channel.ToString();
|
||||
@@ -646,7 +644,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
if (this._tellTarget != null) {
|
||||
var target = this._tellTarget;
|
||||
var reason = target.Reason;
|
||||
var world = this.Ui.Plugin.DataManager.GetExcelSheet<World>()?.GetRow(target.World);
|
||||
var world = Plugin.DataManager.GetExcelSheet<World>()?.GetRow(target.World);
|
||||
if (world is { IsPublic: true }) {
|
||||
if (reason == TellReason.Reply && this.Ui.Plugin.Common.Functions.FriendList.List.Any(friend => friend.ContentId == target.ContentId)) {
|
||||
reason = TellReason.Friend;
|
||||
@@ -671,7 +669,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
}
|
||||
|
||||
var bytes = Encoding.UTF8.GetBytes(trimmed);
|
||||
AutoTranslate.ReplaceWithPayload(this.Ui.Plugin.DataManager, ref bytes);
|
||||
AutoTranslate.ReplaceWithPayload(Plugin.DataManager, ref bytes);
|
||||
|
||||
this.Ui.Plugin.Common.Functions.Chat.SendMessageUnsafe(bytes);
|
||||
}
|
||||
@@ -1067,7 +1065,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
return;
|
||||
}
|
||||
|
||||
this._autoCompleteList ??= AutoTranslate.Matching(this.Ui.Plugin.DataManager, this._autoCompleteInfo.ToComplete, this.Ui.Plugin.Config.SortAutoTranslate);
|
||||
this._autoCompleteList ??= AutoTranslate.Matching(Plugin.DataManager, this._autoCompleteInfo.ToComplete, this.Ui.Plugin.Config.SortAutoTranslate);
|
||||
|
||||
if (this._autoCompleteOpen) {
|
||||
ImGui.OpenPopup(AutoCompleteId);
|
||||
@@ -1088,7 +1086,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
|
||||
ImGui.SetNextItemWidth(-1);
|
||||
if (ImGui.InputTextWithHint("##auto-complete-filter", Language.AutoTranslate_Search_Hint, ref this._autoCompleteInfo.ToComplete, 256, ImGuiInputTextFlags.CallbackAlways | ImGuiInputTextFlags.CallbackHistory, this.AutoCompleteCallback)) {
|
||||
this._autoCompleteList = AutoTranslate.Matching(this.Ui.Plugin.DataManager, this._autoCompleteInfo.ToComplete, this.Ui.Plugin.Config.SortAutoTranslate);
|
||||
this._autoCompleteList = AutoTranslate.Matching(Plugin.DataManager, this._autoCompleteInfo.ToComplete, this.Ui.Plugin.Config.SortAutoTranslate);
|
||||
this._autoCompleteSelection = 0;
|
||||
this._autoCompleteShouldScroll = true;
|
||||
}
|
||||
@@ -1260,7 +1258,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
var text = MemoryHelper.ReadString((IntPtr) data->Buf, data->BufTextLen);
|
||||
if (text.StartsWith('/')) {
|
||||
var command = text.Split(' ')[0];
|
||||
var cmd = this.Ui.Plugin.DataManager.GetExcelSheet<TextCommand>()?.FirstOrDefault(cmd => cmd.Command.RawString == command
|
||||
var cmd = Plugin.DataManager.GetExcelSheet<TextCommand>()?.FirstOrDefault(cmd => cmd.Command.RawString == command
|
||||
|| cmd.Alias.RawString == command
|
||||
|| cmd.ShortCommand.RawString == command
|
||||
|| cmd.ShortAlias.RawString == command);
|
||||
@@ -1377,15 +1375,8 @@ internal sealed class ChatLog : IUiComponent {
|
||||
|
||||
var pushed = false;
|
||||
if (text.Italic) {
|
||||
if (this.Ui.ItalicFont.HasValue && this.Ui.Plugin.Config.FontsEnabled) {
|
||||
ImGui.PushFont(this.Ui.ItalicFont.Value);
|
||||
pushed = true;
|
||||
}
|
||||
|
||||
if (!this.Ui.Plugin.Config.FontsEnabled && (this.Ui.AxisItalic?.Available ?? false)) {
|
||||
ImGui.PushFont(this.Ui.AxisItalic.ImFont);
|
||||
pushed = true;
|
||||
}
|
||||
pushed = true;
|
||||
(Ui.Plugin.Config.FontsEnabled && Ui.ItalicFont != null ? Ui.ItalicFont : Ui.AxisItalic).Push();
|
||||
}
|
||||
|
||||
var content = text.Content;
|
||||
@@ -1393,7 +1384,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
if (chunk.Link is PlayerPayload playerPayload) {
|
||||
var hashCode = $"{this.Ui.Salt}{playerPayload.PlayerName}{playerPayload.World.RowId}".GetHashCode();
|
||||
content = $"Player {hashCode:X8}";
|
||||
} else if (this.Ui.Plugin.ClientState.LocalPlayer is { } player && content.Contains(player.Name.TextValue)) {
|
||||
} else if (Plugin.ClientState.LocalPlayer is { } player && content.Contains(player.Name.TextValue)) {
|
||||
var hashCode = $"{this.Ui.Salt}{player.Name.TextValue}{player.HomeWorld.Id}".GetHashCode();
|
||||
content = content.Replace(player.Name.TextValue, $"Player {hashCode:X8}");
|
||||
}
|
||||
@@ -1407,7 +1398,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||
}
|
||||
|
||||
if (pushed) {
|
||||
ImGui.PopFont();
|
||||
(Ui.Plugin.Config.FontsEnabled && Ui.ItalicFont != null ? Ui.ItalicFont : Ui.AxisItalic).Pop();
|
||||
}
|
||||
|
||||
if (colour != null) {
|
||||
|
||||
+2
-7
@@ -135,10 +135,7 @@ internal static class Fonts {
|
||||
|
||||
stream.ReleaseFileFragment(release);
|
||||
|
||||
var metrics = font.Metrics;
|
||||
var ratio = (metrics.Ascent + metrics.Descent + metrics.LineGap) / (float) metrics.DesignUnitsPerEm;
|
||||
|
||||
return new FaceData(data, ratio);
|
||||
return new FaceData(data);
|
||||
}
|
||||
|
||||
var normalData = GetFontData(normal);
|
||||
@@ -170,11 +167,9 @@ internal static class Fonts {
|
||||
|
||||
internal sealed class FaceData {
|
||||
internal byte[] Data { get; }
|
||||
internal float Ratio { get; }
|
||||
|
||||
internal FaceData(byte[] data, float ratio) {
|
||||
internal FaceData(byte[] data) {
|
||||
this.Data = data;
|
||||
this.Ratio = ratio;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,11 +32,11 @@ internal sealed class Settings : IUiComponent {
|
||||
this.Initialise();
|
||||
|
||||
this.Ui.Plugin.Commands.Register("/chat2", "Perform various actions with Chat 2.").Execute += this.Command;
|
||||
this.Ui.Plugin.Interface.UiBuilder.OpenConfigUi += this.Toggle;
|
||||
Plugin.Interface.UiBuilder.OpenConfigUi += this.Toggle;
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
this.Ui.Plugin.Interface.UiBuilder.OpenConfigUi -= this.Toggle;
|
||||
Plugin.Interface.UiBuilder.OpenConfigUi -= this.Toggle;
|
||||
this.Ui.Plugin.Commands.Register("/chat2").Execute -= this.Command;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ internal sealed class Settings : IUiComponent {
|
||||
|
||||
ImGui.SetNextWindowSize(new Vector2(475, 600) * ImGuiHelpers.GlobalScale, ImGuiCond.FirstUseEver);
|
||||
|
||||
var name = string.Format(Language.Settings_Title, Plugin.Name);
|
||||
var name = string.Format(Language.Settings_Title, Plugin.PluginName);
|
||||
if (!ImGui.Begin($"{name}###chat2-settings", ref this.Ui.SettingsVisible, ImGuiWindowFlags.NoScrollbar | ImGuiWindowFlags.NoScrollWithMouse)) {
|
||||
ImGui.End();
|
||||
return;
|
||||
@@ -117,7 +117,7 @@ internal sealed class Settings : IUiComponent {
|
||||
this.Ui.SettingsVisible = false;
|
||||
}
|
||||
|
||||
var buttonLabel = string.Format(Language.Settings_Kofi, Plugin.Name);
|
||||
var buttonLabel = string.Format(Language.Settings_Kofi, Plugin.PluginName);
|
||||
|
||||
ImGui.PushStyleColor(ImGuiCol.Button, ColourUtil.RgbaToAbgr(0xFF5E5BFF));
|
||||
ImGui.PushStyleColor(ImGuiCol.ButtonHovered, ColourUtil.RgbaToAbgr(0xFF7775FF));
|
||||
@@ -161,11 +161,11 @@ internal sealed class Settings : IUiComponent {
|
||||
this.Ui.Plugin.Store.FilterAllTabs(false);
|
||||
|
||||
if (fontChanged || fontSizeChanged) {
|
||||
this.Ui.Plugin.Interface.UiBuilder.RebuildFonts();
|
||||
this.Ui.BuildFonts();
|
||||
}
|
||||
|
||||
if (langChanged) {
|
||||
this.Ui.Plugin.LanguageChanged(this.Ui.Plugin.Interface.UiLanguage);
|
||||
this.Ui.Plugin.LanguageChanged(Plugin.Interface.UiLanguage);
|
||||
}
|
||||
|
||||
if (sharedChanged) {
|
||||
|
||||
@@ -23,10 +23,10 @@ internal sealed class ChatColours : ISettingsTab {
|
||||
.ToHashSet();
|
||||
var total = Enum.GetValues<ChatType>().Where(type => !type.IsGm()).ToHashSet();
|
||||
if (sortable.Count != total.Count) {
|
||||
Dalamud.Logging.Plugin.Log.Warning($"There are {sortable.Count} sortable channels, but there are {total.Count} total channels.");
|
||||
Plugin.Log.Warning($"There are {sortable.Count} sortable channels, but there are {total.Count} total channels.");
|
||||
total.ExceptWith(sortable);
|
||||
foreach (var missing in total) {
|
||||
Dalamud.Logging.Plugin.Log.Log($"Missing {missing}");
|
||||
Plugin.Log.Information($"Missing {missing}");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"dependencies": {
|
||||
"net7.0-windows7.0": {
|
||||
"net8.0-windows7.0": {
|
||||
"DalamudPackager": {
|
||||
"type": "Direct",
|
||||
"requested": "[2.1.12, )",
|
||||
|
||||
Reference in New Issue
Block a user