From 5455fcb66c7c15d18412e3afa15a8a211c244435 Mon Sep 17 00:00:00 2001 From: Wexx <86693821+wexxlee@users.noreply.github.com> Date: Sat, 9 Mar 2024 16:24:01 -0800 Subject: [PATCH 01/10] Fix build annotation warning for tech support screen mode (#324) * Fix build annotation warning for tech support screen mode * run dotnet format * use static handler; add window handle re-check * re-add "(unknown)" as default/unset value --- OverlayPlugin.Core/ClipboardTechSupport.cs | 37 ++++++++++++++++++---- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/OverlayPlugin.Core/ClipboardTechSupport.cs b/OverlayPlugin.Core/ClipboardTechSupport.cs index 769df250e..a8b0f9266 100644 --- a/OverlayPlugin.Core/ClipboardTechSupport.cs +++ b/OverlayPlugin.Core/ClipboardTechSupport.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; +using System.Threading; using System.Windows.Forms; using Advanced_Combat_Tracker; using Newtonsoft.Json.Linq; @@ -26,6 +27,8 @@ class ClipboardTechSupport private const ulong WS_POPUP = 0x80000000L; private const ulong WS_CAPTION = 0x00C00000L; + private static string screenMode = "(unknown)"; + [DllImport("user32.dll")] static extern ulong GetWindowLongPtr(IntPtr hWnd, int nIndex); @@ -106,7 +109,12 @@ public ClipboardTechSupport(TinyIoCContainer container) settings.Add(new List { "Machina Region", repository.GetMachinaRegion().ToString() }); string gameVersion = repository.GetGameVersion(); settings.Add(new List { "Game Version", gameVersion != "" ? gameVersion : "(not running)" }); - settings.Add(new List { "Screen Mode", GetFFXIVScreenMode(repository.GetCurrentFFXIVProcess()) }); + + if (screenMode == "(unknown)") + { + repository.RegisterProcessChangedHandler(GetFFXIVScreenMode); + } + settings.Add(new List { "Screen Mode", screenMode }); var tabPage = repository.GetPluginTabPage(); if (tabPage != null) @@ -182,30 +190,45 @@ private Dictionary GetCactbotConfig(IPluginConfig pluginConfig) } } - private string GetFFXIVScreenMode(Process process) + private void GetFFXIVScreenMode(Process process) { if (process == null) - return "(not running)"; + { + screenMode = "(not running)"; + return; + } + // If a handler exists when the game is closed and later re-opened, GetFFXIVScreenMode() + // will be called with the new process before a main window handle is available. + // In this case, just sleep for 15 seconds and try again. IntPtr mainWindowHandle = process.MainWindowHandle; if (mainWindowHandle == IntPtr.Zero) - return "(not running)"; + { + Thread.Sleep(15000); + mainWindowHandle = process.MainWindowHandle; + if (mainWindowHandle == IntPtr.Zero) + { + screenMode = "(not running)"; + return; + } + } ulong style = GetWindowLongPtr(mainWindowHandle, -16); if ((style & WS_POPUP) != 0) { - return "Borderless Windowed"; + screenMode = "Borderless Windowed"; } else if ((style & WS_CAPTION) != 0) { - return "Windowed"; + screenMode = "Windowed"; } else { warnings.Add(new List { "Game running in Full Screen mode." }); - return "Full Screen"; + screenMode = "Full Screen"; } + return; } private static void GetCheckboxes(Control.ControlCollection controls, Dictionary checkboxes) From ea2d8d1dc560d80630bc86137c71fc63ccf63226 Mon Sep 17 00:00:00 2001 From: Wexx <86693821+wexxlee@users.noreply.github.com> Date: Sat, 9 Mar 2024 18:51:15 -0800 Subject: [PATCH 02/10] Revert #324 (#325) Revert "Fix build annotation warning for tech support screen mode (#324)" This reverts commit 5455fcb66c7c15d18412e3afa15a8a211c244435. --- OverlayPlugin.Core/ClipboardTechSupport.cs | 37 ++++------------------ 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/OverlayPlugin.Core/ClipboardTechSupport.cs b/OverlayPlugin.Core/ClipboardTechSupport.cs index a8b0f9266..769df250e 100644 --- a/OverlayPlugin.Core/ClipboardTechSupport.cs +++ b/OverlayPlugin.Core/ClipboardTechSupport.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; -using System.Threading; using System.Windows.Forms; using Advanced_Combat_Tracker; using Newtonsoft.Json.Linq; @@ -27,8 +26,6 @@ class ClipboardTechSupport private const ulong WS_POPUP = 0x80000000L; private const ulong WS_CAPTION = 0x00C00000L; - private static string screenMode = "(unknown)"; - [DllImport("user32.dll")] static extern ulong GetWindowLongPtr(IntPtr hWnd, int nIndex); @@ -109,12 +106,7 @@ public ClipboardTechSupport(TinyIoCContainer container) settings.Add(new List { "Machina Region", repository.GetMachinaRegion().ToString() }); string gameVersion = repository.GetGameVersion(); settings.Add(new List { "Game Version", gameVersion != "" ? gameVersion : "(not running)" }); - - if (screenMode == "(unknown)") - { - repository.RegisterProcessChangedHandler(GetFFXIVScreenMode); - } - settings.Add(new List { "Screen Mode", screenMode }); + settings.Add(new List { "Screen Mode", GetFFXIVScreenMode(repository.GetCurrentFFXIVProcess()) }); var tabPage = repository.GetPluginTabPage(); if (tabPage != null) @@ -190,45 +182,30 @@ private Dictionary GetCactbotConfig(IPluginConfig pluginConfig) } } - private void GetFFXIVScreenMode(Process process) + private string GetFFXIVScreenMode(Process process) { if (process == null) - { - screenMode = "(not running)"; - return; - } + return "(not running)"; - // If a handler exists when the game is closed and later re-opened, GetFFXIVScreenMode() - // will be called with the new process before a main window handle is available. - // In this case, just sleep for 15 seconds and try again. IntPtr mainWindowHandle = process.MainWindowHandle; if (mainWindowHandle == IntPtr.Zero) - { - Thread.Sleep(15000); - mainWindowHandle = process.MainWindowHandle; - if (mainWindowHandle == IntPtr.Zero) - { - screenMode = "(not running)"; - return; - } - } + return "(not running)"; ulong style = GetWindowLongPtr(mainWindowHandle, -16); if ((style & WS_POPUP) != 0) { - screenMode = "Borderless Windowed"; + return "Borderless Windowed"; } else if ((style & WS_CAPTION) != 0) { - screenMode = "Windowed"; + return "Windowed"; } else { warnings.Add(new List { "Game running in Full Screen mode." }); - screenMode = "Full Screen"; + return "Full Screen"; } - return; } private static void GetCheckboxes(Control.ControlCollection controls, Dictionary checkboxes) From ab5291e689f0e70edd5438b6df18a1013319508a Mon Sep 17 00:00:00 2001 From: valarnin Date: Sun, 10 Mar 2024 14:00:09 -0400 Subject: [PATCH 03/10] Remove `UnstableNewLogLines` (#323) Fix exception when running OverlayPlugin without FFXIV_ACT_Plugin, during startup --- .../Integration/UnstableNewLogLines.cs | 167 ------------------ OverlayPlugin.Core/OverlayZCorrector.cs | 11 +- OverlayPlugin.Core/PluginMain.cs | 4 - 3 files changed, 10 insertions(+), 172 deletions(-) delete mode 100644 OverlayPlugin.Core/Integration/UnstableNewLogLines.cs diff --git a/OverlayPlugin.Core/Integration/UnstableNewLogLines.cs b/OverlayPlugin.Core/Integration/UnstableNewLogLines.cs deleted file mode 100644 index 1e03e0154..000000000 --- a/OverlayPlugin.Core/Integration/UnstableNewLogLines.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.IO; -using System.Net.Configuration; -using System.Text; -using System.Threading; -using Advanced_Combat_Tracker; -using Markdig.Helpers; -using RainbowMage.OverlayPlugin.EventSources; -using RainbowMage.OverlayPlugin.MemoryProcessors.InCombat; -using RainbowMage.OverlayPlugin.NetworkProcessors; -using static RainbowMage.OverlayPlugin.MemoryProcessors.InCombat.LineInCombat; - -namespace RainbowMage.OverlayPlugin.Integration -{ - public class UnstableNewLogLines - { - private bool inCutscene = false; - private FFXIVRepository repo = null; - private NetworkParser parser = null; - private EnmityEventSource enmitySource = null; - private ILogger logger = null; - private string logPath = null; - private ConcurrentQueue logQueue = null; - private Thread logThread = null; - private LineInCombat lineInCombat = null; - - public UnstableNewLogLines(TinyIoCContainer container) - { - repo = container.Resolve(); - parser = container.Resolve(); - enmitySource = container.Resolve(); - logger = container.Resolve(); - logPath = Path.GetDirectoryName(ActGlobals.oFormActMain.LogFilePath) + "_OverlayPlugin.log"; - container.TryResolve(out lineInCombat); - - var config = container.Resolve(); - config.LogLinesChanged += (o, e) => - { - if (config.LogLines) - { - Enable(); - } - else - { - Disable(); - } - }; - - if (config.LogLines) - { - Enable(); - } - } - - public void Enable() - { - parser.OnOnlineStatusChanged += OnOnlineStatusChange; - if (lineInCombat != null) - { - lineInCombat.OnInCombatChanged += OnCombatStatusChange; - } - - logThread = new Thread(new ThreadStart(WriteBackgroundLog)); - logThread.IsBackground = true; - logThread.Start(); - } - - public void Disable() - { - parser.OnOnlineStatusChanged -= OnOnlineStatusChange; - if (lineInCombat != null) - { - lineInCombat.OnInCombatChanged -= OnCombatStatusChange; - } - logQueue?.Enqueue(null); - } - - private void WriteBackgroundLog() - { - try - { - logger.Log(LogLevel.Info, "LogWriter: Opening log file {0}.", logPath); - var logFile = File.Open(logPath, FileMode.Append, FileAccess.Write, FileShare.Read); - logQueue = new ConcurrentQueue(); - - while (true) - { - if (logQueue.TryDequeue(out string line)) - { - if (line == null) break; - - var data = Encoding.UTF8.GetBytes(line + "\n"); - logFile.Write(data, 0, data.Length); - } - else - { - Thread.Sleep(500); - } - } - - logger.Log(LogLevel.Info, "LogWriter: Closing log."); - logFile.Close(); - } - catch (Exception ex) - { - logger.Log(LogLevel.Error, "LogWriter: {0}", ex); - logQueue = null; - } - } - - public void WriteLogMessage(string msg) - { - var time = DateTime.Now; - var lineParts = new string[] { "00", time.ToString(), "c0fe", "", "OPLine: " + msg, "" }; - var line = string.Join("|", lineParts); - - ActGlobals.oFormActMain.ParseRawLogLine(false, time, line); - logQueue?.Enqueue(line); - } - - private void OnOnlineStatusChange(object sender, OnlineStatusChangedArgs ev) - { - if (ev.Target != repo.GetPlayerID()) - return; - - var cutsceneStatus = ev.Status == 15; - if (cutsceneStatus != inCutscene) - { - inCutscene = cutsceneStatus; - string msg; - - if (cutsceneStatus) - { - msg = "Entered cutscene"; - } - else - { - msg = "Left cutscene"; - } - - WriteLogMessage(msg); - } - } - - private void OnCombatStatusChange(object sender, InCombatArgs ev) - { - if (!ev.InGameCombatChanged) - { - return; - } - - string msg; - if (ev.InGameCombat) - { - msg = "Entered combat"; - } - else - { - msg = "Left combat"; - } - - WriteLogMessage(msg); - } - } -} diff --git a/OverlayPlugin.Core/OverlayZCorrector.cs b/OverlayPlugin.Core/OverlayZCorrector.cs index a8a93f0ef..9dad308cd 100644 --- a/OverlayPlugin.Core/OverlayZCorrector.cs +++ b/OverlayPlugin.Core/OverlayZCorrector.cs @@ -30,7 +30,16 @@ public OverlayZCorrector(TinyIoCContainer container) var span = TimeSpan.FromSeconds(3); timer = new Timer(EnsureOverlaysAreOverGame, null, span, span); - repository.RegisterProcessChangedHandler(UpdateFFXIVProcess); + try + { + repository.RegisterProcessChangedHandler(UpdateFFXIVProcess); + } + catch (Exception ex) + { + logger.Log(LogLevel.Error, "Failed to register process watcher for FFXIV; this is only an issue if you're playing FFXIV. As a consequence, OverlayPlugin won't be able to ensure overlays are on top."); + logger.Log(LogLevel.Error, "Details: " + ex.ToString()); + } + } public void DeInit() diff --git a/OverlayPlugin.Core/PluginMain.cs b/OverlayPlugin.Core/PluginMain.cs index e223bb0a0..20ef2a784 100644 --- a/OverlayPlugin.Core/PluginMain.cs +++ b/OverlayPlugin.Core/PluginMain.cs @@ -11,7 +11,6 @@ using RainbowMage.HtmlRenderer; using RainbowMage.OverlayPlugin.Controls; using RainbowMage.OverlayPlugin.EventSources; -using RainbowMage.OverlayPlugin.Integration; using RainbowMage.OverlayPlugin.MemoryProcessors; using RainbowMage.OverlayPlugin.MemoryProcessors.Aggro; using RainbowMage.OverlayPlugin.MemoryProcessors.AtkStage; @@ -297,9 +296,6 @@ public void InitPlugin(TabPage pluginScreenSpace, Label pluginStatusText) await Task.Run(LoadAddons); wsConfigPanel.RebuildOverlayOptions(); - this.label.Text = "Init Phase 2: Unstable new stuff"; - _container.Register(new UnstableNewLogLines(_container)); - this.label.Text = "Init Phase 2: UI"; ActGlobals.oFormActMain.Invoke((Action)(() => { From f278ff75ae58a7a1e2559cce542704d3b5924fae Mon Sep 17 00:00:00 2001 From: Wexx <86693821+wexxlee@users.noreply.github.com> Date: Sun, 10 Mar 2024 13:53:54 -0700 Subject: [PATCH 04/10] Fix build annotation warning for tech support screen mode (redo) (#326) * Fix build annotation warning for tech support screen mode * run dotnet format * use static handler; add window handle re-check * add default "unknown" value --- OverlayPlugin.Core/ClipboardTechSupport.cs | 38 ++++++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/OverlayPlugin.Core/ClipboardTechSupport.cs b/OverlayPlugin.Core/ClipboardTechSupport.cs index 769df250e..00be8dce4 100644 --- a/OverlayPlugin.Core/ClipboardTechSupport.cs +++ b/OverlayPlugin.Core/ClipboardTechSupport.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; +using System.Threading; using System.Windows.Forms; using Advanced_Combat_Tracker; using Newtonsoft.Json.Linq; @@ -26,6 +27,8 @@ class ClipboardTechSupport private const ulong WS_POPUP = 0x80000000L; private const ulong WS_CAPTION = 0x00C00000L; + private static string screenMode = null; + [DllImport("user32.dll")] static extern ulong GetWindowLongPtr(IntPtr hWnd, int nIndex); @@ -106,7 +109,13 @@ public ClipboardTechSupport(TinyIoCContainer container) settings.Add(new List { "Machina Region", repository.GetMachinaRegion().ToString() }); string gameVersion = repository.GetGameVersion(); settings.Add(new List { "Game Version", gameVersion != "" ? gameVersion : "(not running)" }); - settings.Add(new List { "Screen Mode", GetFFXIVScreenMode(repository.GetCurrentFFXIVProcess()) }); + + if (screenMode == null) + { + screenMode = "(unknown)"; + repository.RegisterProcessChangedHandler(GetFFXIVScreenMode); + } + settings.Add(new List { "Screen Mode", screenMode }); var tabPage = repository.GetPluginTabPage(); if (tabPage != null) @@ -182,30 +191,45 @@ private Dictionary GetCactbotConfig(IPluginConfig pluginConfig) } } - private string GetFFXIVScreenMode(Process process) + private void GetFFXIVScreenMode(Process process) { if (process == null) - return "(not running)"; + { + screenMode = "(not running)"; + return; + } + // If a handler exists when the game is closed and later re-opened, GetFFXIVScreenMode() + // will be called with the new process before a main window handle is available. + // In this case, just sleep for 15 seconds and try again. IntPtr mainWindowHandle = process.MainWindowHandle; if (mainWindowHandle == IntPtr.Zero) - return "(not running)"; + { + Thread.Sleep(15000); + mainWindowHandle = process.MainWindowHandle; + if (mainWindowHandle == IntPtr.Zero) + { + screenMode = "(not running)"; + return; + } + } ulong style = GetWindowLongPtr(mainWindowHandle, -16); if ((style & WS_POPUP) != 0) { - return "Borderless Windowed"; + screenMode = "Borderless Windowed"; } else if ((style & WS_CAPTION) != 0) { - return "Windowed"; + screenMode = "Windowed"; } else { warnings.Add(new List { "Game running in Full Screen mode." }); - return "Full Screen"; + screenMode = "Full Screen"; } + return; } private static void GetCheckboxes(Control.ControlCollection controls, Dictionary checkboxes) From 85c0f858c9d4a413218486919e8e00890d72a9f2 Mon Sep 17 00:00:00 2001 From: Makar Date: Tue, 19 Mar 2024 08:31:55 -0500 Subject: [PATCH 05/10] Update opcodes for Global 6.58 (#328) --- OverlayPlugin.Core/resources/opcodes.jsonc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OverlayPlugin.Core/resources/opcodes.jsonc b/OverlayPlugin.Core/resources/opcodes.jsonc index 5916f6e32..fea94b8c5 100644 --- a/OverlayPlugin.Core/resources/opcodes.jsonc +++ b/OverlayPlugin.Core/resources/opcodes.jsonc @@ -43,42 +43,42 @@ } }, // Global region - "2024.02.05.0000.0000": { - // Version: 6.57 + "2024.03.08.0000.0000": { + // Version: 6.58 "MapEffect": { - "opcode": 141, + "opcode": 728, "size": 11 }, "CEDirector": { - "opcode": 984, + "opcode": 824, "size": 16 }, "RSVData": { - "opcode": 625, + "opcode": 809, "size": 1080 }, "NpcYell": { - "opcode": 101, + "opcode": 150, "size": 32 }, "BattleTalk2": { - "opcode": 475, + "opcode": 751, "size": 40 }, "Countdown": { - "opcode": 928, + "opcode": 811, "size": 48 }, "CountdownCancel": { - "opcode": 322, + "opcode": 820, "size": 40 }, "ActorMove": { - "opcode": 845, + "opcode": 416, "size": 16 }, "ActorSetPos": { - "opcode": 174, + "opcode": 121, "size": 24 } }, From 4080737632231723468db2cde646b23e5a115d28 Mon Sep 17 00:00:00 2001 From: Wexx <86693821+wexxlee@users.noreply.github.com> Date: Sat, 23 Mar 2024 12:30:24 -0700 Subject: [PATCH 06/10] Add elevation info and multiple-instance warnings to support button (#327) * Add elevation info and multiple-instance warnings to support button * update comment & output * exception handling; remove comment --- OverlayPlugin.Core/ClipboardTechSupport.cs | 98 +++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/OverlayPlugin.Core/ClipboardTechSupport.cs b/OverlayPlugin.Core/ClipboardTechSupport.cs index 00be8dce4..11ab7d913 100644 --- a/OverlayPlugin.Core/ClipboardTechSupport.cs +++ b/OverlayPlugin.Core/ClipboardTechSupport.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; +using System.Security.Principal; using System.Threading; using System.Windows.Forms; using Advanced_Combat_Tracker; @@ -26,12 +27,26 @@ class ClipboardTechSupport private const ulong WS_POPUP = 0x80000000L; private const ulong WS_CAPTION = 0x00C00000L; - + private const uint TOKEN_QUERY = 0x0008; + + private static IntPtr ph = IntPtr.Zero; + private static WindowsIdentity actWi = null; + private static WindowsIdentity ffxivWi = null; + private static Process[] actProcesses = null; + private static string actIsAdmin = null; + private static string ffxivIsAdmin = null; private static string screenMode = null; [DllImport("user32.dll")] static extern ulong GetWindowLongPtr(IntPtr hWnd, int nIndex); + [DllImport("advapi32.dll", SetLastError = true)] + private static extern bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool CloseHandle(IntPtr hObject); + static string hideChatLogForPrivacyName = "chkDisableCombatLog"; // A map of CheckBox names to text. Right now this text matches what the FFXIV Plugin usues in English. @@ -56,6 +71,12 @@ public ClipboardTechSupport(TinyIoCContainer container) plugins = new SimpleTable { new List { "Plugin Name", "Enabled", "Version", "Path" } }; + actProcesses = Process.GetProcessesByName("Advanced Combat Tracker"); + if (actProcesses.Length > 1) + { + warnings.Add(new List { "Multiple instances of ACT running" }); + } + bool foundFFIXVActPlugin = false; bool foundOverlayPlugin = false; @@ -117,6 +138,35 @@ public ClipboardTechSupport(TinyIoCContainer container) } settings.Add(new List { "Screen Mode", screenMode }); + try + { + actWi = WindowsIdentity.GetCurrent(); + if (actWi.Owner.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid)) + { + actIsAdmin = "Elevated (Admin)"; + } + else + { + actIsAdmin = "Not Elevated"; + } + } + catch (Exception e) + { + // The most common exception is an access denied error. + // This *shouldn't* happen when checking the WindowsIdentity of the + // current process, but just in case. + actIsAdmin = "(unknown - check warnings)"; + warnings.Add(new List { "Could not check for ACT process elevation: " + e.Message }); + } + settings.Add(new List { "ACT Process Elevation", actIsAdmin }); + + if (ffxivIsAdmin == null) + { + ffxivIsAdmin = "(unknown)"; + repository.RegisterProcessChangedHandler(GetFFXIVIsRunningAsAdmin); + } + settings.Add(new List { "FFXIV Process Elevation", ffxivIsAdmin }); + var tabPage = repository.GetPluginTabPage(); if (tabPage != null) { @@ -232,6 +282,52 @@ private void GetFFXIVScreenMode(Process process) return; } + private void GetFFXIVIsRunningAsAdmin(Process process) + { + if (process == null) + { + ffxivIsAdmin = "(not running)"; + return; + } + + try + { + OpenProcessToken(process.Handle, TOKEN_QUERY, out ph); + ffxivWi = new WindowsIdentity(ph); + if (ffxivWi.Owner.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid)) + { + ffxivIsAdmin = "Elevated (Admin)"; + } + else + { + ffxivIsAdmin = "Not Elevated"; + } + } + catch (Exception e) + { + // Will get an access-denied exception if ACT is not elevated, but FFXIV is, + // since ACT won't have sufficient permissions to check the FFXIV process. + // Could theoretically be triggered if FFXIV is running under a different + // (non-admin) user, so give a somewhat non-comittal output. + if (e.Message.Contains("Access is denied")) + { + ffxivIsAdmin = "Likely Elevated (access violation)"; + } + else + { + ffxivIsAdmin = "(unknown - check warnings)"; + warnings.Add(new List { "Could not check for FFXIV process elevation: " + e.Message }); + } + } + finally + { + if (ph != IntPtr.Zero) + { + CloseHandle(ph); + } + } + } + private static void GetCheckboxes(Control.ControlCollection controls, Dictionary checkboxes) { foreach (Control control in controls) From f6c51411013a812fe8422310020c1688b068736e Mon Sep 17 00:00:00 2001 From: Makar Date: Tue, 2 Apr 2024 08:00:47 -0500 Subject: [PATCH 07/10] Update opcodes for Global 6.58 Hotfix (#331) --- OverlayPlugin.Core/resources/opcodes.jsonc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/OverlayPlugin.Core/resources/opcodes.jsonc b/OverlayPlugin.Core/resources/opcodes.jsonc index fea94b8c5..942d5fdfb 100644 --- a/OverlayPlugin.Core/resources/opcodes.jsonc +++ b/OverlayPlugin.Core/resources/opcodes.jsonc @@ -43,42 +43,42 @@ } }, // Global region - "2024.03.08.0000.0000": { - // Version: 6.58 + "2024.03.27.0000.0000": { + // Version: 6.58 Hotfix "MapEffect": { - "opcode": 728, + "opcode": 280, "size": 11 }, "CEDirector": { - "opcode": 824, + "opcode": 899, "size": 16 }, "RSVData": { - "opcode": 809, + "opcode": 820, "size": 1080 }, "NpcYell": { - "opcode": 150, + "opcode": 726, "size": 32 }, "BattleTalk2": { - "opcode": 751, + "opcode": 464, "size": 40 }, "Countdown": { - "opcode": 811, + "opcode": 192, "size": 48 }, "CountdownCancel": { - "opcode": 820, + "opcode": 863, "size": 40 }, "ActorMove": { - "opcode": 416, + "opcode": 949, "size": 16 }, "ActorSetPos": { - "opcode": 121, + "opcode": 401, "size": 24 } }, From 51dae886dfffac81dd4f516f7493c26472a939cb Mon Sep 17 00:00:00 2001 From: RaWouk Date: Tue, 2 Apr 2024 22:01:09 +0900 Subject: [PATCH 08/10] Update opcodes for KR 6.5 (#332) * Bump koVersion to 6.5 --- .../MemoryProcessors/FFXIVMemory.cs | 2 +- OverlayPlugin.Core/resources/opcodes.jsonc | 34 ++++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/OverlayPlugin.Core/MemoryProcessors/FFXIVMemory.cs b/OverlayPlugin.Core/MemoryProcessors/FFXIVMemory.cs index 6d60ed620..d2988c356 100644 --- a/OverlayPlugin.Core/MemoryProcessors/FFXIVMemory.cs +++ b/OverlayPlugin.Core/MemoryProcessors/FFXIVMemory.cs @@ -25,7 +25,7 @@ public class FFXIVMemory // The "international" version always uses the most recent. private static Version globalVersion = new Version(99, 0); private static Version cnVersion = new Version(6, 5); - private static Version koVersion = new Version(6, 4); + private static Version koVersion = new Version(6, 5); public FFXIVMemory(TinyIoCContainer container) { diff --git a/OverlayPlugin.Core/resources/opcodes.jsonc b/OverlayPlugin.Core/resources/opcodes.jsonc index 942d5fdfb..b4120af25 100644 --- a/OverlayPlugin.Core/resources/opcodes.jsonc +++ b/OverlayPlugin.Core/resources/opcodes.jsonc @@ -83,19 +83,43 @@ } }, // KR region - "2023.12.18.0000.0000":{ - // Version: 6.45 + "2024.03.28.0000.0000":{ + // Version: 6.5 "MapEffect": { - "opcode": 978, + "opcode": 205, "size": 11 }, "CEDirector": { - "opcode": 540, + "opcode": 915, "size": 16 }, "RSVData": { - "opcode": 168, + "opcode": 463, "size": 1080 + }, + "NpcYell": { + "opcode": 136, + "size": 32 + }, + "BattleTalk2": { + "opcode": 674, + "size": 40 + }, + "Countdown": { + "opcode": 216, + "size": 48 + }, + "CountdownCancel": { + "opcode": 320, + "size": 40 + }, + "ActorMove": { + "opcode": 679, + "size": 16 + }, + "ActorSetPos": { + "opcode": 392, + "size": 24 } } } From 8af11a9d40f3db9407c027bd90cb5ad8b3fcb852 Mon Sep 17 00:00:00 2001 From: valarnin Date: Tue, 2 Apr 2024 09:02:02 -0400 Subject: [PATCH 09/10] Add `ActorControlSelfExtra`, additional categories (#329) * Pull `Server_ActorControlCategory` to a separate file --- .../Integration/OverlayPluginLogLines.cs | 1 + .../LineActorControlCommon.cs | 12 ++ .../LineActorControlExtra.cs | 15 +- .../LineActorControlSelfExtra.cs | 184 ++++++++++++++++++ .../NetworkProcessors/NetworkParser.cs | 2 +- .../resources/reserved_log_lines.json | 7 + 6 files changed, 213 insertions(+), 8 deletions(-) create mode 100644 OverlayPlugin.Core/NetworkProcessors/LineActorControlCommon.cs create mode 100644 OverlayPlugin.Core/NetworkProcessors/LineActorControlSelfExtra.cs diff --git a/OverlayPlugin.Core/Integration/OverlayPluginLogLines.cs b/OverlayPlugin.Core/Integration/OverlayPluginLogLines.cs index c17b563cc..e5932b3f0 100644 --- a/OverlayPlugin.Core/Integration/OverlayPluginLogLines.cs +++ b/OverlayPlugin.Core/Integration/OverlayPluginLogLines.cs @@ -35,6 +35,7 @@ public OverlayPluginLogLines(TinyIoCContainer container) container.Register(new LineActorSetPos(container)); container.Register(new LineSpawnNpcExtra(container)); container.Register(new LineActorControlExtra(container)); + container.Register(new LineActorControlSelfExtra(container)); } } diff --git a/OverlayPlugin.Core/NetworkProcessors/LineActorControlCommon.cs b/OverlayPlugin.Core/NetworkProcessors/LineActorControlCommon.cs new file mode 100644 index 000000000..4fb8d9697 --- /dev/null +++ b/OverlayPlugin.Core/NetworkProcessors/LineActorControlCommon.cs @@ -0,0 +1,12 @@ +namespace RainbowMage.OverlayPlugin.NetworkProcessors +{ + public enum Server_ActorControlCategory : ushort + { + SetAnimationState = 0x003E, // 62 + StatusUpdate = 0x01F8, // 504 + // Name is a guess + DisplayLogMessage = 0x020F, // 527 + DisplayLogMessageParams = 0x0210, // 528 + DisplayPublicContentTextMessage = 0x0834, // 2100 + } +} diff --git a/OverlayPlugin.Core/NetworkProcessors/LineActorControlExtra.cs b/OverlayPlugin.Core/NetworkProcessors/LineActorControlExtra.cs index 5643b8a28..1e25f8304 100644 --- a/OverlayPlugin.Core/NetworkProcessors/LineActorControlExtra.cs +++ b/OverlayPlugin.Core/NetworkProcessors/LineActorControlExtra.cs @@ -1,6 +1,7 @@ using System; using System.Diagnostics; using System.Globalization; +using System.Linq; using System.Reflection; using System.Runtime.InteropServices; @@ -18,10 +19,10 @@ public class LineActorControlExtra private ILogger logger; private readonly FFXIVRepository ffxiv; - // Any category defined in this enum will be allowed as an emitted line - public enum Server_ActorControlCategory : ushort - { - SetAnimationState = 62, + // Any category defined in this array will be allowed as an emitted line + public static readonly Server_ActorControlCategory[] AllowedActorControlCategories = { + Server_ActorControlCategory.SetAnimationState, + Server_ActorControlCategory.DisplayPublicContentTextMessage }; private class RegionalizedInfo @@ -141,9 +142,9 @@ private unsafe void MessageReceived(string id, long epoch, byte[] message) UInt32 sourceId = (UInt32)info.fieldCastSourceId.GetValue(header); object packet = Marshal.PtrToStructure(new IntPtr(buffer), info.actorControlType); - UInt16 category = (UInt16)info.fieldCategory.GetValue(packet); + Server_ActorControlCategory category = (Server_ActorControlCategory)info.fieldCategory.GetValue(packet); - if (Enum.IsDefined(typeof(Server_ActorControlCategory), category)) + if (AllowedActorControlCategories.Contains(category)) { UInt32 param1 = (UInt32)info.fieldParam1.GetValue(packet); UInt32 param2 = (UInt32)info.fieldParam2.GetValue(packet); @@ -152,7 +153,7 @@ private unsafe void MessageReceived(string id, long epoch, byte[] message) string line = string.Format(CultureInfo.InvariantCulture, "{0:X8}|{1:X4}|{2:X}|{3:X}|{4:X}|{5:X}", - sourceId, category, param1, param2, param3, param4); + sourceId, (ushort)category, param1, param2, param3, param4); DateTime serverTime = ffxiv.EpochToDateTime(epoch); logWriter(line, serverTime); diff --git a/OverlayPlugin.Core/NetworkProcessors/LineActorControlSelfExtra.cs b/OverlayPlugin.Core/NetworkProcessors/LineActorControlSelfExtra.cs new file mode 100644 index 000000000..7925061b9 --- /dev/null +++ b/OverlayPlugin.Core/NetworkProcessors/LineActorControlSelfExtra.cs @@ -0,0 +1,184 @@ +using System; +using System.Diagnostics; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; + +// To test `DisplayLogMessage`, you can: +// Open a treasure coffer that gives you item(s): +// 274|2024-01-10T19:28:37.5000000-05:00|10001234|020F|04D0|0|93E0|0|0|0|d274429622d0c27e +// 274|2024-01-10T19:28:37.5000000-05:00|10001234|020F|04D0|0|93F3|0|0|0|d274429622d0c27e +// 00|2024-01-10T19:28:36.0000000-05:00|0A3E||You obtain a windswept shamshir.|92337ce2a33e52f8 +// 00|2024-01-10T19:28:36.0000000-05:00|0A3E||You obtain a windswept shield.|a48cbf20d0255d4e +// Sell TT cards for MGP: +// 274|2024-01-10T20:08:35.3520000-05:00|10001234|020F|129D|0|320|0|0|0|d274429622d0c27e +// 00|2024-01-10T20:08:35.0000000-05:00|0A3E||You obtain 800 MGP.|f768dc4f098c15a6 +// Die in Eureka with a `Spirit of the Remembered` active: +// 274|2024-02-15T19:35:41.9950000-05:00|10001234|020F|236D|0|669|0|0|0|d274429622d0c27e +// 00|2024-02-15T19:35:41.0000000-05:00|0939||The memories of heroes past live on again!|bb3bfbfc487ad4e9 + +// To test `DisplayLogMessageParams`, you can play a Gold Saucer minigame: +// 274|2024-03-21T20:45:41.3680000-04:00|10001234|0210|129D|10001234|F|0|0|0|d274429622d0c27e +// 00|2024-03-21T20:45:40.0000000-04:00|08BE||You obtain 15 MGP.|97702e809544a633 + +namespace RainbowMage.OverlayPlugin.NetworkProcessors +{ + public class LineActorControlSelfExtra + { + public const uint LogFileLineID = 274; + private ILogger logger; + private readonly FFXIVRepository ffxiv; + + // Any category defined in this array will be allowed as an emitted line + public static readonly Server_ActorControlCategory[] AllowedActorControlCategories = { + // Some `LogMessage` messages can be triggered by both 0x020F and 0x0210 categories, not sure what the difference is + // except that 0x0210 messages usually have another actor ID in the parameters + Server_ActorControlCategory.DisplayLogMessage, + Server_ActorControlCategory.DisplayLogMessageParams, + }; + + private class RegionalizedInfo + { + public readonly int packetSize; + public readonly int packetOpcode; + public readonly int offsetMessageType; + public readonly Type headerType; + public readonly Type actorControlType; + public readonly FieldInfo fieldCastSourceId; + public readonly FieldInfo fieldCategory; + public readonly FieldInfo fieldParam1; + public readonly FieldInfo fieldParam2; + public readonly FieldInfo fieldParam3; + public readonly FieldInfo fieldParam4; + public readonly FieldInfo fieldParam5; + public readonly FieldInfo fieldParam6; + + public RegionalizedInfo(Type headerType, Type actorControlType, NetworkParser netHelper) + { + this.headerType = headerType; + this.actorControlType = actorControlType; + fieldCastSourceId = headerType.GetField("ActorID"); + fieldCategory = actorControlType.GetField("category"); + fieldParam1 = actorControlType.GetField("param1"); + fieldParam2 = actorControlType.GetField("param2"); + fieldParam3 = actorControlType.GetField("param3"); + fieldParam4 = actorControlType.GetField("param4"); + fieldParam5 = actorControlType.GetField("param5"); + fieldParam6 = actorControlType.GetField("param6"); + packetOpcode = netHelper.GetOpcode("ActorControlSelf"); + packetSize = Marshal.SizeOf(actorControlType); + offsetMessageType = netHelper.GetOffset(headerType, "MessageType"); + } + } + + private RegionalizedInfo regionalized; + + private readonly Func logWriter; + private readonly NetworkParser netHelper; + + public LineActorControlSelfExtra(TinyIoCContainer container) + { + logger = container.Resolve(); + ffxiv = container.Resolve(); + netHelper = container.Resolve(); + ffxiv.RegisterNetworkParser(MessageReceived); + ffxiv.RegisterProcessChangedHandler(ProcessChanged); + + var customLogLines = container.Resolve(); + logWriter = customLogLines.RegisterCustomLogLine(new LogLineRegistryEntry() + { + Name = "ActorControlSelfExtra", + Source = "OverlayPlugin", + ID = LogFileLineID, + Version = 1, + }); + } + + private void ProcessChanged(Process process) + { + GameRegion region = ffxiv.GetMachinaRegion(); + if (!ffxiv.IsFFXIVPluginPresent()) + return; + try + { + Assembly mach = Assembly.Load("Machina.FFXIV"); + Type headerType = mach.GetType("Machina.FFXIV.Headers.Server_MessageHeader"); + string actorControlTypeStr; + switch (region) + { + case GameRegion.Global: + { + actorControlTypeStr = "Machina.FFXIV.Headers.Server_ActorControlSelf"; + break; + } + case GameRegion.Korean: + { + actorControlTypeStr = "Machina.FFXIV.Headers.Korean.Server_ActorControlSelf"; + break; + } + case GameRegion.Chinese: + { + actorControlTypeStr = "Machina.FFXIV.Headers.Chinese.Server_ActorControlSelf"; + break; + } + default: + { + return; + } + } + + Type actorControlType = mach.GetType(actorControlTypeStr); + RegionalizedInfo info = new RegionalizedInfo(headerType, actorControlType, netHelper); + regionalized = info; + } + catch (System.IO.FileNotFoundException) + { + logger.Log(LogLevel.Error, Resources.NetworkParserNoFfxiv); + } + catch (Exception e) + { + logger.Log(LogLevel.Error, Resources.NetworkParserInitException, e); + } + } + + private unsafe void MessageReceived(string id, long epoch, byte[] message) + { + RegionalizedInfo info = regionalized; + if (info == null) + return; + + if (message.Length < info.packetSize) + return; + + fixed (byte* buffer = message) + { + if (*(ushort*)&buffer[info.offsetMessageType] == info.packetOpcode) + { + object header = Marshal.PtrToStructure(new IntPtr(buffer), info.headerType); + UInt32 sourceId = (UInt32)info.fieldCastSourceId.GetValue(header); + + object packet = Marshal.PtrToStructure(new IntPtr(buffer), info.actorControlType); + Server_ActorControlCategory category = (Server_ActorControlCategory)info.fieldCategory.GetValue(packet); + + if (AllowedActorControlCategories.Contains(category)) + { + UInt32 param1 = (UInt32)info.fieldParam1.GetValue(packet); + UInt32 param2 = (UInt32)info.fieldParam2.GetValue(packet); + UInt32 param3 = (UInt32)info.fieldParam3.GetValue(packet); + UInt32 param4 = (UInt32)info.fieldParam4.GetValue(packet); + UInt32 param5 = (UInt32)info.fieldParam5.GetValue(packet); + UInt32 param6 = (UInt32)info.fieldParam6.GetValue(packet); + + string line = string.Format(CultureInfo.InvariantCulture, + "{0:X8}|{1:X4}|{2:X}|{3:X}|{4:X}|{5:X}|{6:X}|{7:X}", + sourceId, (ushort)category, param1, param2, param3, param4, param5, param6); + + DateTime serverTime = ffxiv.EpochToDateTime(epoch); + logWriter(line, serverTime); + } + } + } + } + } +} \ No newline at end of file diff --git a/OverlayPlugin.Core/NetworkProcessors/NetworkParser.cs b/OverlayPlugin.Core/NetworkProcessors/NetworkParser.cs index 8be7af439..e727c25af 100644 --- a/OverlayPlugin.Core/NetworkProcessors/NetworkParser.cs +++ b/OverlayPlugin.Core/NetworkProcessors/NetworkParser.cs @@ -138,7 +138,7 @@ public unsafe void Parse(string id, long epoch, byte[] message) */ if (*((ushort*)&buffer[MessageType_Offset]) != ActorControl142_Opcode) return; - if (*((ushort*)&buffer[Category_Offset]) != 0x1f8) return; + if (*((ushort*)&buffer[Category_Offset]) != (ushort)Server_ActorControlCategory.StatusUpdate) return; OnOnlineStatusChanged?.Invoke(null, new OnlineStatusChangedArgs(*(uint*)&buffer[ActorID_Offset], *(uint*)&buffer[Param1_Offset])); } diff --git a/OverlayPlugin.Core/resources/reserved_log_lines.json b/OverlayPlugin.Core/resources/reserved_log_lines.json index 57bd4e086..7d2e902e7 100644 --- a/OverlayPlugin.Core/resources/reserved_log_lines.json +++ b/OverlayPlugin.Core/resources/reserved_log_lines.json @@ -132,6 +132,13 @@ "Version": 1, "Comment": "Extra info from ActorControl packets" }, + { + "ID": 274, + "Name": "ActorControlSelfExtra", + "Source": "OverlayPlugin", + "Version": 1, + "Comment": "Extra info from ActorControlSelf packets" + }, { "StartID": 256, "EndID": 512, From 3bd0abca660a93a2e4ff56bc28c1ef425050c777 Mon Sep 17 00:00:00 2001 From: xiashtra <91220277+xiashtra@users.noreply.github.com> Date: Wed, 3 Apr 2024 11:12:16 -0400 Subject: [PATCH 10/10] Version bump to 0.19.28 (#333) bump version to 0.19.28 --- Directory.Build.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 732149765..f1040cee3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -5,8 +5,8 @@ Copyright © RainbowMage 2015, Kuriyama hibiya 2016, ngld 2019, OverlayPlugin Team 2022 false true - 0.19.27 - 0.19.27 + 0.19.28 + 0.19.28 false false true