diff --git a/ChatTwo/ChatTwo.csproj b/ChatTwo/ChatTwo.csproj
index 875f50f..fcf5f9b 100755
--- a/ChatTwo/ChatTwo.csproj
+++ b/ChatTwo/ChatTwo.csproj
@@ -9,6 +9,8 @@
false
true
preview
+ true
+ full
@@ -47,10 +49,10 @@
-
+
-
+
@@ -80,4 +82,4 @@
-
\ No newline at end of file
+
diff --git a/ChatTwo/Configuration.cs b/ChatTwo/Configuration.cs
index 41558e4..e9b8faa 100755
--- a/ChatTwo/Configuration.cs
+++ b/ChatTwo/Configuration.cs
@@ -34,6 +34,7 @@ internal class Configuration : IPluginConfiguration {
public bool FilterIncludePreviousSessions;
public bool SharedMode;
+ public bool FontsEnabled = true;
public float FontSize = 17f;
public float JapaneseFontSize = 17f;
public float SymbolsFontSize = 17f;
@@ -66,6 +67,7 @@ internal class Configuration : IPluginConfiguration {
this.LoadPreviousSession = other.LoadPreviousSession;
this.FilterIncludePreviousSessions = other.FilterIncludePreviousSessions;
this.SharedMode = other.SharedMode;
+ this.FontsEnabled = other.FontsEnabled;
this.FontSize = other.FontSize;
this.JapaneseFontSize = other.JapaneseFontSize;
this.SymbolsFontSize = other.SymbolsFontSize;
diff --git a/ChatTwo/GameFunctions/Chat.cs b/ChatTwo/GameFunctions/Chat.cs
index 6064efe..1d202f1 100755
--- a/ChatTwo/GameFunctions/Chat.cs
+++ b/ChatTwo/GameFunctions/Chat.cs
@@ -34,7 +34,7 @@ internal sealed unsafe class Chat : IDisposable {
[Signature("E8 ?? ?? ?? ?? 48 3B F0 74 35")]
private readonly delegate* unmanaged _getFocus = null!;
- [Signature("44 8B 89 ?? ?? ?? ?? 4C 8B C1")]
+ [Signature("44 8B 89 ?? ?? ?? ?? 4C 8B C1 45 85 C9")]
private readonly delegate* unmanaged _getTellHistory = null!;
[Signature("E8 ?? ?? ?? ?? B8 ?? ?? ?? ?? 48 8D 4D 50")]
diff --git a/ChatTwo/GameFunctions/Context.cs b/ChatTwo/GameFunctions/Context.cs
index 90d31b1..0a7abf5 100755
--- a/ChatTwo/GameFunctions/Context.cs
+++ b/ChatTwo/GameFunctions/Context.cs
@@ -87,8 +87,8 @@ internal sealed unsafe class Context {
}
var uiModule = Framework.Instance()->GetUiModule();
- var vf35 = (delegate* unmanaged) uiModule->vfunc[35];
- var a1 = vf35(uiModule);
+ var vf36 = (delegate* unmanaged) uiModule->vfunc[36];
+ var a1 = vf36(uiModule);
this._searchForRecipesUsingItem(a1, itemId);
}
diff --git a/ChatTwo/GameFunctions/GameFunctions.cs b/ChatTwo/GameFunctions/GameFunctions.cs
index 3a57428..9ecf503 100755
--- a/ChatTwo/GameFunctions/GameFunctions.cs
+++ b/ChatTwo/GameFunctions/GameFunctions.cs
@@ -30,7 +30,7 @@ internal unsafe class GameFunctions : IDisposable {
[Signature("48 89 5C 24 ?? 57 48 83 EC 20 48 8B FA 48 8B D9 E8 ?? ?? ?? ?? 48 8B 8B ?? ?? ?? ?? 48 85 C9", Fallibility = Fallibility.Fallible)]
private readonly delegate* unmanaged _openPartyFinder = null!;
- [Signature("E8 ?? ?? ?? ?? EB 42 48 8B 47 30", Fallibility = Fallibility.Fallible)]
+ [Signature("E8 ?? ?? ?? ?? EB 20 48 8B 46 28", Fallibility = Fallibility.Fallible)]
private readonly delegate* unmanaged _openAchievement = null!;
#endregion
@@ -164,27 +164,27 @@ internal unsafe class GameFunctions : IDisposable {
var agentPtr = (IntPtr) agent;
- // addresses mentioned here are 6.01
+ // addresses mentioned here are 6.11
// see the call near the end of AgentItemDetail.Update
- // offsets valid as of 6.01
+ // offsets valid as of 6.11
- // 8BFC49: sets some shit
+ // A54B19: sets some shit
*(uint*) (agentPtr + 0x20) = 22;
- // 8C04C8: switch goes down to default, which is what we want
+ // A55218: switch goes down to default, which is what we want
*(byte*) (agentPtr + 0x118) = 1;
- // 8BFCF6: item id when hovering over item in chat
+ // A54BE0: item id when hovering over item in chat
*(uint*) (agentPtr + 0x11C) = id;
- // 8BFCE4: always 0 when hovering over item in chat
+ // A54BCC: always 0 when hovering over item in chat
*(uint*) (agentPtr + 0x120) = 0;
- // 8C0B55: skips a check to do with inventory
+ // A558A5: skips a check to do with inventory
*(byte*) (agentPtr + 0x128) &= 0xEF;
- // 8BFC7C: when set to 1, lets everything continue (one frame)
- *(byte*) (agentPtr + 0x146) = 1;
- // 8BFC89: skips early return
- *(byte*) (agentPtr + 0x14A) = 0;
+ // A54B3F: when set to 1, lets everything continue (one frame)
+ *(byte*) (agentPtr + 0x14A) = 1;
+ // A54B59: skips early return
+ *(byte*) (agentPtr + 0x14E) = 0;
// this just probably needs to be set
- agent->AddonId = (uint) addon->ID;
+ agent->AddonId = addon->ID;
// vcall from E8 ?? ?? ?? ?? 0F B7 C0 48 83 C4 60
var vf5 = (delegate* unmanaged*) ((IntPtr) addon->VTable + 40);
diff --git a/ChatTwo/GameFunctions/Party.cs b/ChatTwo/GameFunctions/Party.cs
index 3031d8a..58bdf47 100755
--- a/ChatTwo/GameFunctions/Party.cs
+++ b/ChatTwo/GameFunctions/Party.cs
@@ -31,7 +31,7 @@ internal sealed unsafe class Party {
return;
}
- // 6.05: 20D722
+ // 6.11: 214A55
var a1 = this.Plugin.Functions.GetInfoProxyByIndex(1);
fixed (byte* namePtr = name.ToTerminatedBytes()) {
// this only works if target is on the same world
@@ -44,7 +44,7 @@ internal sealed unsafe class Party {
return;
}
- // 6.05: 20D722
+ // 6.11: 214A55
var a1 = this.Plugin.Functions.GetInfoProxyByIndex(1);
if (contentId != 0) {
// third param is world, but it requires a specific world
diff --git a/ChatTwo/PluginUi.cs b/ChatTwo/PluginUi.cs
index 892e538..42e66f8 100755
--- a/ChatTwo/PluginUi.cs
+++ b/ChatTwo/PluginUi.cs
@@ -2,6 +2,7 @@ using System.Numerics;
using System.Runtime.InteropServices;
using ChatTwo.Ui;
using Dalamud.Interface;
+using Dalamud.Interface.GameFonts;
using Dalamud.Logging;
using ImGuiNET;
@@ -14,6 +15,9 @@ 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 ImFontPtr? RegularFont { get; private set; }
internal ImFontPtr? ItalicFont { get; private set; }
internal Vector4 DefaultText { get; private set; }
@@ -112,7 +116,11 @@ internal sealed class PluginUi : IDisposable {
BuildRange(out this._jpRange, GlyphRangesJapanese.GlyphRanges);
this.SetUpUserFonts();
- var gameSym = File.ReadAllBytes(Path.Combine(this.Plugin.Interface.DalamudAssetDirectory.FullName, "UIRes", "gamesym.ttf"));
+ 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
@@ -165,9 +173,13 @@ internal sealed class PluginUi : IDisposable {
this.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;
- if (font) {
+ if (pushed) {
ImGui.PushFont(this.RegularFont!.Value);
+ } else if (axis) {
+ ImGui.PushFont(this.Axis.ImFont);
}
foreach (var component in this.Components) {
@@ -178,7 +190,7 @@ internal sealed class PluginUi : IDisposable {
}
}
- if (font) {
+ if (pushed || axis) {
ImGui.PopFont();
}
}
@@ -274,6 +286,11 @@ internal sealed class PluginUi : IDisposable {
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,
+ });
+
// load regular noto sans and merge in jp + game icons
this.RegularFont = ImGui.GetIO().Fonts.AddFontFromMemoryTTF(
this._regularFont.Item1.AddrOfPinnedObject(),
diff --git a/ChatTwo/Resources/Language.Designer.cs b/ChatTwo/Resources/Language.Designer.cs
index 14c1a17..5d24af5 100755
--- a/ChatTwo/Resources/Language.Designer.cs
+++ b/ChatTwo/Resources/Language.Designer.cs
@@ -519,6 +519,15 @@ namespace ChatTwo.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Enable custom fonts.
+ ///
+ internal static string Options_FontsEnabled {
+ get {
+ return ResourceManager.GetString("Options_FontsEnabled", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Font size.
///
diff --git a/ChatTwo/Resources/Language.resx b/ChatTwo/Resources/Language.resx
index 2696338..133c427 100755
--- a/ChatTwo/Resources/Language.resx
+++ b/ChatTwo/Resources/Language.resx
@@ -494,4 +494,7 @@
Opacity
+
+ Enable custom fonts
+
diff --git a/ChatTwo/Ui/ChatLog.cs b/ChatTwo/Ui/ChatLog.cs
index a27f37f..44775ad 100755
--- a/ChatTwo/Ui/ChatLog.cs
+++ b/ChatTwo/Ui/ChatLog.cs
@@ -39,12 +39,14 @@ internal sealed class ChatLog : IUiComponent {
private PayloadHandler PayloadHandler { get; }
private Dictionary TextCommandChannels { get; } = new();
+ private HashSet AllCommands { get; } = new();
internal ChatLog(PluginUi ui) {
this.Ui = ui;
this.PayloadHandler = new PayloadHandler(this.Ui, this);
this.SetUpTextCommandChannels();
+ this.SetUpAllCommands();
this.Ui.Plugin.Commands.Register("/clearlog2", "Clear the Chat 2 chat log").Execute += this.ClearLog;
this.Ui.Plugin.Commands.Register("/chat2").Execute += this.ToggleChat;
@@ -137,6 +139,11 @@ internal sealed class ChatLog : IUiComponent {
}
}
+ private bool IsValidCommand(string command) {
+ return this.Ui.Plugin.CommandManager.Commands.ContainsKey(command)
+ || this.AllCommands.Contains(command);
+ }
+
private void ClearLog(string command, string arguments) {
switch (arguments) {
case "all":
@@ -213,6 +220,23 @@ internal sealed class ChatLog : IUiComponent {
this.TextCommandChannels[command.ShortAlias] = type;
}
+ private void SetUpAllCommands() {
+ if (this.Ui.Plugin.DataManager.GetExcelSheet() is not { } commands) {
+ return;
+ }
+
+ var commandNames = commands.SelectMany(cmd => new[] {
+ cmd.Command.RawString,
+ cmd.ShortCommand.RawString,
+ cmd.Alias.RawString,
+ cmd.ShortAlias.RawString,
+ });
+
+ foreach (var command in commandNames) {
+ this.AllCommands.Add(command);
+ }
+ }
+
private void AddBacklog(string message) {
for (var i = 0; i < this._inputBacklog.Count; i++) {
if (this._inputBacklog[i] != message) {
@@ -479,6 +503,10 @@ internal sealed class ChatLog : IUiComponent {
if (this.TextCommandChannels.TryGetValue(command, out var channel)) {
inputType = channel;
}
+
+ if (!this.IsValidCommand(command)) {
+ inputType = ChatType.Error;
+ }
}
var normalColour = *ImGui.GetStyleColorVec4(ImGuiCol.Text);
@@ -1040,8 +1068,17 @@ internal sealed class ChatLog : IUiComponent {
ImGui.PushStyleColor(ImGuiCol.Text, colour.Value);
}
- if (text.Italic && this.Ui.ItalicFont.HasValue) {
- ImGui.PushFont(this.Ui.ItalicFont.Value);
+ 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) {
+ ImGui.PushFont(this.Ui.AxisItalic.ImFont);
+ pushed = true;
+ }
}
var content = text.Content;
@@ -1062,7 +1099,7 @@ internal sealed class ChatLog : IUiComponent {
ImGuiUtil.PostPayload(chunk, handler);
}
- if (text.Italic && this.Ui.ItalicFont.HasValue) {
+ if (pushed) {
ImGui.PopFont();
}
diff --git a/ChatTwo/Ui/SettingsTabs/Fonts.cs b/ChatTwo/Ui/SettingsTabs/Fonts.cs
index 1dec4ac..36b769a 100755
--- a/ChatTwo/Ui/SettingsTabs/Fonts.cs
+++ b/ChatTwo/Ui/SettingsTabs/Fonts.cs
@@ -27,66 +27,71 @@ public class Fonts : ISettingsTab {
}
ImGui.PushTextWrapPos();
-
- if (ImGuiUtil.BeginComboVertical(Language.Options_Font_Name, this.Mutable.GlobalFont)) {
- foreach (var font in Ui.Fonts.GlobalFonts) {
- if (ImGui.Selectable(font.Name, this.Mutable.GlobalFont == font.Name)) {
- this.Mutable.GlobalFont = font.Name;
- }
-
- if (ImGui.IsWindowAppearing() && this.Mutable.GlobalFont == font.Name) {
- ImGui.SetScrollHereY(0.5f);
- }
- }
-
- ImGui.Separator();
-
- foreach (var name in this.GlobalFonts) {
- if (ImGui.Selectable(name, this.Mutable.GlobalFont == name)) {
- this.Mutable.GlobalFont = name;
- }
-
- if (ImGui.IsWindowAppearing() && this.Mutable.GlobalFont == name) {
- ImGui.SetScrollHereY(0.5f);
- }
- }
-
- ImGui.EndCombo();
- }
-
- ImGuiUtil.HelpText(string.Format(Language.Options_Font_Description, Plugin.PluginName));
- ImGuiUtil.WarningText(Language.Options_Font_Warning);
+
+ ImGui.Checkbox(Language.Options_FontsEnabled, ref this.Mutable.FontsEnabled);
ImGui.Spacing();
- if (ImGuiUtil.BeginComboVertical(Language.Options_JapaneseFont_Name, this.Mutable.JapaneseFont)) {
- foreach (var (name, _) in Ui.Fonts.JapaneseFonts) {
- if (ImGui.Selectable(name, this.Mutable.JapaneseFont == name)) {
- this.Mutable.JapaneseFont = name;
+ if (this.Mutable.FontsEnabled) {
+ if (ImGuiUtil.BeginComboVertical(Language.Options_Font_Name, this.Mutable.GlobalFont)) {
+ foreach (var font in Ui.Fonts.GlobalFonts) {
+ if (ImGui.Selectable(font.Name, this.Mutable.GlobalFont == font.Name)) {
+ this.Mutable.GlobalFont = font.Name;
+ }
+
+ if (ImGui.IsWindowAppearing() && this.Mutable.GlobalFont == font.Name) {
+ ImGui.SetScrollHereY(0.5f);
+ }
}
- if (ImGui.IsWindowAppearing() && this.Mutable.JapaneseFont == name) {
- ImGui.SetScrollHereY(0.5f);
+ ImGui.Separator();
+
+ foreach (var name in this.GlobalFonts) {
+ if (ImGui.Selectable(name, this.Mutable.GlobalFont == name)) {
+ this.Mutable.GlobalFont = name;
+ }
+
+ if (ImGui.IsWindowAppearing() && this.Mutable.GlobalFont == name) {
+ ImGui.SetScrollHereY(0.5f);
+ }
}
+
+ ImGui.EndCombo();
}
- ImGui.Separator();
+ ImGuiUtil.HelpText(string.Format(Language.Options_Font_Description, Plugin.PluginName));
+ ImGuiUtil.WarningText(Language.Options_Font_Warning);
+ ImGui.Spacing();
- foreach (var family in this.JpFonts) {
- if (ImGui.Selectable(family, this.Mutable.JapaneseFont == family)) {
- this.Mutable.JapaneseFont = family;
+ if (ImGuiUtil.BeginComboVertical(Language.Options_JapaneseFont_Name, this.Mutable.JapaneseFont)) {
+ foreach (var (name, _) in Ui.Fonts.JapaneseFonts) {
+ if (ImGui.Selectable(name, this.Mutable.JapaneseFont == name)) {
+ this.Mutable.JapaneseFont = name;
+ }
+
+ if (ImGui.IsWindowAppearing() && this.Mutable.JapaneseFont == name) {
+ ImGui.SetScrollHereY(0.5f);
+ }
}
- if (ImGui.IsWindowAppearing() && this.Mutable.JapaneseFont == family) {
- ImGui.SetScrollHereY(0.5f);
+ ImGui.Separator();
+
+ foreach (var family in this.JpFonts) {
+ if (ImGui.Selectable(family, this.Mutable.JapaneseFont == family)) {
+ this.Mutable.JapaneseFont = family;
+ }
+
+ if (ImGui.IsWindowAppearing() && this.Mutable.JapaneseFont == family) {
+ ImGui.SetScrollHereY(0.5f);
+ }
}
+
+ ImGui.EndCombo();
}
- ImGui.EndCombo();
+ ImGuiUtil.HelpText(string.Format(Language.Options_JapaneseFont_Description, Plugin.PluginName));
+ ImGui.Spacing();
}
- ImGuiUtil.HelpText(string.Format(Language.Options_JapaneseFont_Description, Plugin.PluginName));
- ImGui.Spacing();
-
const float speed = .0125f;
const float min = 8f;
const float max = 36f;