From 59aa8c7dc7670b4269b11889477a15b72e6f2471 Mon Sep 17 00:00:00 2001 From: Liza Carvelli Date: Tue, 3 Oct 2023 10:36:31 +0200 Subject: [PATCH] API 9 --- .gitignore | 10 +- Configuration.cs | 26 +--- FishNotify.cs | 330 ++++++++++++++++++++++------------------------ FishNotify.csproj | 8 +- OpcodeList.cs | 7 + OpcodeRegion.cs | 10 ++ 6 files changed, 187 insertions(+), 204 deletions(-) create mode 100644 OpcodeList.cs create mode 100644 OpcodeRegion.cs diff --git a/.gitignore b/.gitignore index b6f3f18..65f048b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ -.vs/ -obj/ -dist/ -*.user \ No newline at end of file +/dist +/obj +/bin +/.idea +/.vs +*.user diff --git a/Configuration.cs b/Configuration.cs index c731662..0be04aa 100644 --- a/Configuration.cs +++ b/Configuration.cs @@ -1,25 +1,9 @@ using Dalamud.Configuration; -using Dalamud.Plugin; -using System; -namespace FishNotify +namespace FishNotify; + +internal sealed class Configuration : IPluginConfiguration { - internal class Configuration : IPluginConfiguration - { - public int Version { get; set; } = 0; - public bool ChatAlerts { get; set; } = false; - - [NonSerialized] - private DalamudPluginInterface pluginInterface = null!; - - public void Initialize(DalamudPluginInterface pluginInterface) - { - this.pluginInterface = pluginInterface; - } - - public void Save() - { - this.pluginInterface.SavePluginConfig(this); - } - } + public int Version { get; set; } = 0; + public bool ChatAlerts { get; set; } = false; } diff --git a/FishNotify.cs b/FishNotify.cs index 424a24b..4283f69 100644 --- a/FishNotify.cs +++ b/FishNotify.cs @@ -1,10 +1,7 @@ -using Dalamud.Data; -using Dalamud.Game.Gui; -using Dalamud.Game.Network; +using Dalamud.Game.Network; using Dalamud.Game.Text.SeStringHandling; using Dalamud.Interface.Colors; using Dalamud.IoC; -using Dalamud.Logging; using Dalamud.Plugin; using ImGuiNET; using Newtonsoft.Json; @@ -13,197 +10,184 @@ using System.Collections.Generic; using System.Net.Http; using System.Runtime.InteropServices; using System.Threading.Tasks; +using Dalamud.Plugin.Services; -namespace FishNotify +namespace FishNotify; + +public sealed class FishNotifyPlugin : IDalamudPlugin { - public sealed class FishNotifyPlugin : IDalamudPlugin + [PluginService] + [RequiredVersion("1.0")] + private DalamudPluginInterface PluginInterface { get; set; } = null!; + + [PluginService] + private IGameNetwork Network { get; set; } = null!; + + [PluginService] + private IChatGui Chat { get; set; } = null!; + + [PluginService] + private IPluginLog PluginLog { get; set; } = null!; + + private readonly Configuration _configuration; + private bool _settingsVisible; + private int _expectedOpCode = -1; + private uint _fishCount; + + public FishNotifyPlugin() { - public string Name => "FishNotify"; + _configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration(); - [PluginService] - [RequiredVersion("1.0")] - private DalamudPluginInterface PluginInterface { get; set; } = null!; + Network.NetworkMessage += OnNetworkMessage; + PluginInterface.UiBuilder.Draw += OnDrawUI; + PluginInterface.UiBuilder.OpenConfigUi += OnOpenConfigUi; - [PluginService] - private GameNetwork Network { get; set; } = null!; + var client = new HttpClient(); + client.GetStringAsync("https://raw.githubusercontent.com/karashiiro/FFXIVOpcodes/master/opcodes.min.json") + .ContinueWith(ExtractOpCode); + } - [PluginService] - public static ChatGui Chat { get; set; } = null!; + public void Dispose() + { + Network.NetworkMessage -= OnNetworkMessage; + PluginInterface.UiBuilder.Draw -= OnDrawUI; + PluginInterface.UiBuilder.OpenConfigUi -= OnOpenConfigUi; + } - private Configuration configuration; - private bool settingsVisible; - private int expectedOpCode = -1; - private uint fishCount = 0; - - public FishNotifyPlugin() + private void ExtractOpCode(Task task) + { + try { - configuration = PluginInterface.GetPluginConfig() as Configuration ?? new Configuration(); - configuration.Initialize(PluginInterface); - - Network.NetworkMessage += OnNetworkMessage; - PluginInterface.UiBuilder.Draw += OnDrawUI; - PluginInterface.UiBuilder.OpenConfigUi += OnOpenConfigUi; - - var client = new HttpClient(); - client.GetStringAsync("https://raw.githubusercontent.com/karashiiro/FFXIVOpcodes/master/opcodes.min.json") - .ContinueWith(ExtractOpCode); - } - - public void Dispose() - { - Network.NetworkMessage -= OnNetworkMessage; - PluginInterface.UiBuilder.Draw -= OnDrawUI; - PluginInterface.UiBuilder.OpenConfigUi -= OnOpenConfigUi; - } - - private void ExtractOpCode(Task task) - { - try - { - var regions = JsonConvert.DeserializeObject>(task.Result); - if (regions == null) - { - PluginLog.Warning("No regions found in opcode list"); - return; - } - - var region = regions.Find(r => r.Region == "Global"); - if (region == null || region.Lists == null) - { - PluginLog.Warning("No global region found in opcode list"); - return; - } - - if (!region.Lists.TryGetValue("ServerZoneIpcType", out List? serverZoneIpcTypes) || serverZoneIpcTypes == null) - { - PluginLog.Warning("No ServerZoneIpcType in opcode list"); - return; - } - - var eventPlay = serverZoneIpcTypes.Find(opcode => opcode.Name == "EventPlay"); - if (eventPlay == null) - { - PluginLog.Warning("No EventPlay opcode in ServerZoneIpcType"); - return; - } - - expectedOpCode = eventPlay.Opcode; - PluginLog.Debug($"Found EventPlay opcode {expectedOpCode:X4}"); - } - catch (Exception e) - { - PluginLog.Error(e, "Could not download/extract opcodes: {}", e.Message); - } - } - - private void OnNetworkMessage(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction) - { - if (direction != NetworkMessageDirection.ZoneDown || opCode != expectedOpCode) - return; - - var data = new byte[32]; - Marshal.Copy(dataPtr, data, 0, data.Length); - - int eventId = BitConverter.ToInt32(data, 8); - short scene = BitConverter.ToInt16(data, 12); - int param5 = BitConverter.ToInt32(data, 28); - - // Fishing event? - if (eventId != 0x00150001) - return; - - // Fish hooked? - if (scene != 5) - return; - - switch (param5) - { - - case 0x124: - // light tug (!) - ++fishCount; - Sounds.PlaySound(Resources.Info); - SendChatAlert("light"); - break; - - case 0x125: - // medium tug (!!) - ++fishCount; - Sounds.PlaySound(Resources.Alert); - SendChatAlert("medium"); - break; - - case 0x126: - // heavy tug (!!!) - ++fishCount; - Sounds.PlaySound(Resources.Alarm); - SendChatAlert("heavy"); - break; - - default: - Sounds.Stop(); - break; - } - } - - private void SendChatAlert(string size) - { - if (!configuration.ChatAlerts) + var regions = JsonConvert.DeserializeObject>(task.Result); + if (regions == null) { + PluginLog.Warning("No regions found in opcode list"); return; } - SeString message = new SeStringBuilder() - .AddUiForeground(514) - .Append("[FishNotify]") - .AddUiForegroundOff() - .Append($" You hook a fish with a ") - .AddUiForeground(514) - .Append(size) - .AddUiForegroundOff() - .Append(" bite.") - .Build(); - Chat.Print(message); - } - - private void OnDrawUI() - { - if (!settingsVisible) - return; - - if (ImGui.Begin("FishNotify", ref this.settingsVisible, ImGuiWindowFlags.AlwaysAutoResize)) + var region = regions.Find(r => r.Region == "Global"); + if (region == null || region.Lists == null) { - var chatAlerts = configuration.ChatAlerts; - if (ImGui.Checkbox("Show chat message on hooking a fish", ref chatAlerts)) - { - configuration.ChatAlerts = chatAlerts; - configuration.Save(); - } - - if (expectedOpCode > -1) - ImGui.TextColored(ImGuiColors.HealerGreen, $"Status: {(fishCount == 0 ? "Unknown (not triggered yet)" : $"OK ({fishCount} fish hooked)")}, opcode = {expectedOpCode:X}"); - else - ImGui.TextColored(ImGuiColors.DalamudRed, "Status: No opcode :("); + PluginLog.Warning("No global region found in opcode list"); + return; } - ImGui.End(); - } - private void OnOpenConfigUi() + if (!region.Lists.TryGetValue("ServerZoneIpcType", out List? serverZoneIpcTypes) || serverZoneIpcTypes == null) + { + PluginLog.Warning("No ServerZoneIpcType in opcode list"); + return; + } + + var eventPlay = serverZoneIpcTypes.Find(opcode => opcode.Name == "EventPlay"); + if (eventPlay == null) + { + PluginLog.Warning("No EventPlay opcode in ServerZoneIpcType"); + return; + } + + _expectedOpCode = eventPlay.Opcode; + PluginLog.Debug($"Found EventPlay opcode {_expectedOpCode:X4}"); + } + catch (Exception e) { - settingsVisible = !settingsVisible; + PluginLog.Error(e, "Could not download/extract opcodes: {}", e.Message); } } - public class OpcodeRegion + private void OnNetworkMessage(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction) { - public string? Version { get; set; } - public string? Region { get; set; } - public Dictionary>? Lists { get; set; } + if (direction != NetworkMessageDirection.ZoneDown || opCode != _expectedOpCode) + return; + + var data = new byte[32]; + Marshal.Copy(dataPtr, data, 0, data.Length); + + int eventId = BitConverter.ToInt32(data, 8); + short scene = BitConverter.ToInt16(data, 12); + int param5 = BitConverter.ToInt32(data, 28); + + // Fishing event? + if (eventId != 0x00150001) + return; + + // Fish hooked? + if (scene != 5) + return; + + switch (param5) + { + + case 0x124: + // light tug (!) + ++_fishCount; + Sounds.PlaySound(Resources.Info); + SendChatAlert("light"); + break; + + case 0x125: + // medium tug (!!) + ++_fishCount; + Sounds.PlaySound(Resources.Alert); + SendChatAlert("medium"); + break; + + case 0x126: + // heavy tug (!!!) + ++_fishCount; + Sounds.PlaySound(Resources.Alarm); + SendChatAlert("heavy"); + break; + + default: + Sounds.Stop(); + break; + } } - public class OpcodeList + private void SendChatAlert(string size) { - public string? Name { get; set; } - public ushort Opcode { get; set; } + if (!_configuration.ChatAlerts) + { + return; + } + + SeString message = new SeStringBuilder() + .AddUiForeground(514) + .Append("[FishNotify]") + .AddUiForegroundOff() + .Append(" You hook a fish with a ") + .AddUiForeground(514) + .Append(size) + .AddUiForegroundOff() + .Append(" bite.") + .Build(); + Chat.Print(message); + } + + private void OnDrawUI() + { + if (!_settingsVisible) + return; + + if (ImGui.Begin("FishNotify", ref _settingsVisible, ImGuiWindowFlags.AlwaysAutoResize)) + { + var chatAlerts = _configuration.ChatAlerts; + if (ImGui.Checkbox("Show chat message on hooking a fish", ref chatAlerts)) + { + _configuration.ChatAlerts = chatAlerts; + PluginInterface.SavePluginConfig(_configuration); + } + + if (_expectedOpCode > -1) + ImGui.TextColored(ImGuiColors.HealerGreen, $"Status: {(_fishCount == 0 ? "Unknown (not triggered yet)" : $"OK ({_fishCount} fish hooked)")}, opcode = {_expectedOpCode:X}"); + else + ImGui.TextColored(ImGuiColors.DalamudRed, "Status: No opcode :("); + } + ImGui.End(); + } + + private void OnOpenConfigUi() + { + _settingsVisible = !_settingsVisible; } } diff --git a/FishNotify.csproj b/FishNotify.csproj index 6c521ee..083d43d 100644 --- a/FishNotify.csproj +++ b/FishNotify.csproj @@ -3,7 +3,7 @@ - 5.0 + 6.0 Plays a sound effect when a fish bites https://github.com/carvelli/Fish-Notify @@ -37,7 +37,7 @@ - + $(DalamudLibPath)FFXIVClientStructs.dll @@ -55,10 +55,6 @@ $(DalamudLibPath)ImGui.NET.dll false - - $(DalamudLibPath)ImGuiScene.dll - false - $(DalamudLibPath)Lumina.dll false diff --git a/OpcodeList.cs b/OpcodeList.cs new file mode 100644 index 0000000..1a01532 --- /dev/null +++ b/OpcodeList.cs @@ -0,0 +1,7 @@ +namespace FishNotify; + +public class OpcodeList +{ + public string? Name { get; set; } + public ushort Opcode { get; set; } +} diff --git a/OpcodeRegion.cs b/OpcodeRegion.cs new file mode 100644 index 0000000..fd566f9 --- /dev/null +++ b/OpcodeRegion.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace FishNotify; + +public class OpcodeRegion +{ + public string? Version { get; set; } + public string? Region { get; set; } + public Dictionary>? Lists { get; set; } +}