refactor: clean up code

This commit is contained in:
Anna 2021-03-19 16:06:45 -04:00
parent 671aef656f
commit 2eae9e8012
Signed by: anna
GPG Key ID: 0B391D8F06FCD9E0
10 changed files with 168 additions and 198 deletions

0
Globetrotter.sln Executable file → Normal file
View File

View File

@ -4,8 +4,8 @@ using System;
namespace Globetrotter { namespace Globetrotter {
[Serializable] [Serializable]
class Configuration : IPluginConfiguration { internal class Configuration : IPluginConfiguration {
private DalamudPluginInterface pi; private DalamudPluginInterface _pi;
public int Version { get; set; } = 1; public int Version { get; set; } = 1;
@ -13,11 +13,11 @@ namespace Globetrotter {
public bool ShowOnOpen { get; set; } = true; public bool ShowOnOpen { get; set; } = true;
public void Initialize(DalamudPluginInterface pi) { public void Initialize(DalamudPluginInterface pi) {
this.pi = pi ?? throw new ArgumentNullException(nameof(pi), "DalamudPluginInterface cannot be null"); this._pi = pi ?? throw new ArgumentNullException(nameof(pi), "DalamudPluginInterface cannot be null");
} }
public void Save() { public void Save() {
this.pi.SavePluginConfig(this); this._pi.SavePluginConfig(this);
} }
} }
} }

2
Globetrotter/DalamudPackager.targets Executable file → Normal file
View File

@ -5,7 +5,7 @@
ProjectDir="$(ProjectDir)" ProjectDir="$(ProjectDir)"
OutputPath="$(OutputPath)" OutputPath="$(OutputPath)"
AssemblyName="$(AssemblyName)" AssemblyName="$(AssemblyName)"
VersionCompenents="3" VersionComponents="3"
MakeZip="true"/> MakeZip="true"/>
</Target> </Target>
</Project> </Project>

View File

@ -1,8 +0,0 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters", Justification = "<Pending>", Scope = "module")]

49
Globetrotter/Globetrotter.csproj Executable file → Normal file
View File

@ -1,27 +1,28 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Version>1.1.2</Version> <Version>1.1.2</Version>
<TargetFramework>net48</TargetFramework> <TargetFramework>net48</TargetFramework>
</PropertyGroup> <LangVersion>latest</LangVersion>
<ItemGroup> </PropertyGroup>
<Reference Include="Dalamud, Version=5.2.2.0, Culture=neutral, PublicKeyToken=null"> <ItemGroup>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Dalamud.dll</HintPath> <Reference Include="Dalamud, Version=5.2.3.3, Culture=neutral, PublicKeyToken=null">
</Reference> <HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll</HintPath>
<Reference Include="ImGui.NET, Version=1.72.0.0, Culture=neutral, PublicKeyToken=null"> </Reference>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\ImGui.NET.dll</HintPath> <Reference Include="ImGui.NET, Version=1.72.0.0, Culture=neutral, PublicKeyToken=null">
</Reference> <HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\ImGui.NET.dll</HintPath>
<Reference Include="ImGuiScene, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> </Reference>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\ImGuiScene.dll</HintPath> <Reference Include="ImGuiScene, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
</Reference> <HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\ImGuiScene.dll</HintPath>
<Reference Include="Lumina, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"> </Reference>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Lumina.dll</HintPath> <Reference Include="Lumina, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null">
</Reference> <HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.dll</HintPath>
<Reference Include="Lumina.Excel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"> </Reference>
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\Lumina.Excel.dll</HintPath> <Reference Include="Lumina.Excel, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
</Reference> <HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.Excel.dll</HintPath>
</ItemGroup> </Reference>
<ItemGroup> </ItemGroup>
<PackageReference Include="DalamudPackager" Version="1.2.0" /> <ItemGroup>
</ItemGroup> <PackageReference Include="DalamudPackager" Version="1.2.0"/>
</ItemGroup>
</Project> </Project>

0
Globetrotter/Globetrotter.yaml Executable file → Normal file
View File

View File

@ -4,70 +4,63 @@ using System;
namespace Globetrotter { namespace Globetrotter {
public class GlobetrotterPlugin : IDalamudPlugin { public class GlobetrotterPlugin : IDalamudPlugin {
private bool disposedValue; private bool _disposedValue;
public string Name => "Globetrotter"; public string Name => "Globetrotter";
private DalamudPluginInterface pi; private DalamudPluginInterface _pi = null!;
private Configuration config; private Configuration _config = null!;
private PluginUI ui; private PluginUi _ui = null!;
private TreasureMaps maps; private TreasureMaps _maps = null!;
public void Initialize(DalamudPluginInterface pluginInterface) { public void Initialize(DalamudPluginInterface pluginInterface) {
this.pi = pluginInterface ?? throw new ArgumentNullException(nameof(pluginInterface), "DalamudPluginInterface cannot be null"); this._pi = pluginInterface ?? throw new ArgumentNullException(nameof(pluginInterface), "DalamudPluginInterface cannot be null");
this.config = this.pi.GetPluginConfig() as Configuration ?? new Configuration();
this.config.Initialize(this.pi);
this.ui = new PluginUI(this.pi, this.config); this._config = this._pi.GetPluginConfig() as Configuration ?? new Configuration();
this.maps = new TreasureMaps(this.pi, this.config); this._config.Initialize(this._pi);
this.pi.UiBuilder.OnBuildUi += this.ui.Draw; this._ui = new PluginUi(this._config);
this.pi.UiBuilder.OnOpenConfigUi += this.ui.OpenSettings; this._maps = new TreasureMaps(this._pi, this._config);
this.pi.Framework.Gui.HoveredItemChanged += this.maps.OnHover;
this.pi.CommandManager.AddHandler("/pglobetrotter", new CommandInfo(this.OnConfigCommand) { this._pi.UiBuilder.OnBuildUi += this._ui.Draw;
HelpMessage = "Show the Globetrotter config" this._pi.UiBuilder.OnOpenConfigUi += this._ui.OpenSettings;
this._pi.Framework.Gui.HoveredItemChanged += this._maps.OnHover;
this._pi.CommandManager.AddHandler("/pglobetrotter", new CommandInfo(this.OnConfigCommand) {
HelpMessage = "Show the Globetrotter config",
}); });
this.pi.CommandManager.AddHandler("/tmap", new CommandInfo(this.OnCommand) { this._pi.CommandManager.AddHandler("/tmap", new CommandInfo(this.OnCommand) {
HelpMessage = "Open the map and place a flag at the location of your current treasure map" HelpMessage = "Open the map and place a flag at the location of your current treasure map",
}); });
} }
private void OnConfigCommand(string command, string args) { private void OnConfigCommand(string command, string args) {
this.ui.OpenSettings(null, null); this._ui.OpenSettings(null, null);
} }
private void OnCommand(string command, string args) { private void OnCommand(string command, string args) {
this.maps.OpenMapLocation(); this._maps.OpenMapLocation();
} }
protected virtual void Dispose(bool disposing) { protected virtual void Dispose(bool disposing) {
if (!disposedValue) { if (this._disposedValue) {
if (disposing) { return;
this.pi.UiBuilder.OnBuildUi -= this.ui.Draw;
this.pi.UiBuilder.OnOpenConfigUi -= this.ui.OpenSettings;
this.pi.Framework.Gui.HoveredItemChanged -= this.maps.OnHover;
this.maps.Dispose();
this.pi.CommandManager.RemoveHandler("/pglobetrotter");
this.pi.CommandManager.RemoveHandler("/tmap");
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
disposedValue = true;
} }
}
// // TODO: override finalizer only if 'Dispose(bool disposing)' has code to free unmanaged resources if (disposing) {
// ~GlobetrotterPlugin() this._pi.UiBuilder.OnBuildUi -= this._ui.Draw;
// { this._pi.UiBuilder.OnOpenConfigUi -= this._ui.OpenSettings;
// // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method this._pi.Framework.Gui.HoveredItemChanged -= this._maps.OnHover;
// Dispose(disposing: false); this._maps.Dispose();
// } this._pi.CommandManager.RemoveHandler("/pglobetrotter");
this._pi.CommandManager.RemoveHandler("/tmap");
}
this._disposedValue = true;
}
public void Dispose() { public void Dispose() {
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true); this.Dispose(true);
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
} }

View File

@ -1,49 +0,0 @@
using Dalamud.Plugin;
using ImGuiNET;
using System;
namespace Globetrotter {
class PluginUI {
private readonly DalamudPluginInterface pi;
private readonly Configuration config;
private bool _displaySettings = false;
internal bool DisplaySettings { get => this._displaySettings; private set => this._displaySettings = value; }
public PluginUI(DalamudPluginInterface pi, Configuration config) {
this.pi = pi ?? throw new ArgumentNullException(nameof(pi), "DalamudPluginInterface cannot be null");
this.config = config ?? throw new ArgumentNullException(nameof(config), "Configuration cannot be null");
}
public void OpenSettings(object sender, EventArgs e) {
this.DisplaySettings = true;
}
public void Draw() {
if (!this.DisplaySettings) {
return;
}
if (ImGui.Begin("Globetrotter settings", ref this._displaySettings)) {
ImGui.Text("Use /tmap to open your current treasure map.");
ImGui.Text("If you have a map and this plugin isn't working, change zone.");
ImGui.Separator();
bool showOnHover = this.config.ShowOnHover;
if (ImGui.Checkbox("Show on hover", ref showOnHover)) {
this.config.ShowOnHover = showOnHover;
this.config.Save();
}
bool showOnOpen = this.config.ShowOnOpen;
if (ImGui.Checkbox("Show on open", ref showOnOpen)) {
this.config.ShowOnOpen = showOnOpen;
this.config.Save();
}
ImGui.End();
}
}
}
}

52
Globetrotter/PluginUi.cs Normal file
View File

@ -0,0 +1,52 @@
using ImGuiNET;
using System;
namespace Globetrotter {
internal class PluginUi {
private Configuration Config { get; }
private bool _displaySettings;
private bool DisplaySettings {
get => this._displaySettings;
set => this._displaySettings = value;
}
public PluginUi(Configuration config) {
this.Config = config ?? throw new ArgumentNullException(nameof(config), "Configuration cannot be null");
}
public void OpenSettings(object sender, EventArgs e) {
this.DisplaySettings = true;
}
public void Draw() {
if (!this.DisplaySettings) {
return;
}
if (!ImGui.Begin("Globetrotter settings", ref this._displaySettings)) {
return;
}
ImGui.TextUnformatted("Use /tmap to open your current treasure map.");
ImGui.TextUnformatted("If you have a map and this plugin isn't working, change zone.");
ImGui.Separator();
var showOnHover = this.Config.ShowOnHover;
if (ImGui.Checkbox("Show on hover", ref showOnHover)) {
this.Config.ShowOnHover = showOnHover;
this.Config.Save();
}
var showOnOpen = this.Config.ShowOnOpen;
if (ImGui.Checkbox("Show on open", ref showOnOpen)) {
this.Config.ShowOnOpen = showOnOpen;
this.Config.Save();
}
ImGui.End();
}
}
}

View File

@ -7,20 +7,21 @@ using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Globetrotter { namespace Globetrotter {
class TreasureMaps : IDisposable { internal sealed class TreasureMaps : IDisposable {
private const uint TREASURE_MAPS = 0x54; private const uint TreasureMapsCode = 0x54;
private static Dictionary<uint, uint> _mapToRow; private static Dictionary<uint, uint> _mapToRow;
private Dictionary<uint, uint> MapToRow { private Dictionary<uint, uint> MapToRow {
get { get {
if (_mapToRow != null) { if (_mapToRow != null) {
return _mapToRow; return _mapToRow;
} }
Dictionary<uint, uint> mapToRow = new Dictionary<uint, uint>(); var mapToRow = new Dictionary<uint, uint>();
foreach (TreasureHuntRank rank in this.pi.Data.GetExcelSheet<TreasureHuntRank>()) { foreach (var rank in this.Interface.Data.GetExcelSheet<TreasureHuntRank>()) {
Item unopened = rank.ItemName.Value; var unopened = rank.ItemName.Value;
if (unopened == null) { if (unopened == null) {
continue; continue;
} }
@ -32,6 +33,7 @@ namespace Globetrotter {
} catch (NullReferenceException) { } catch (NullReferenceException) {
opened = null; opened = null;
} }
if (opened == null) { if (opened == null) {
continue; continue;
} }
@ -45,30 +47,30 @@ namespace Globetrotter {
} }
} }
private readonly DalamudPluginInterface pi; private DalamudPluginInterface Interface { get; }
private readonly Configuration config; private Configuration Config { get; }
private TreasureMapPacket lastMap; private TreasureMapPacket _lastMap;
private bool disposedValue;
private delegate char HandleActorControlSelfDelegate(long a1, long a2, IntPtr dataPtr); private delegate char HandleActorControlSelfDelegate(long a1, long a2, IntPtr dataPtr);
private readonly Hook<HandleActorControlSelfDelegate> acsHook;
private readonly Hook<HandleActorControlSelfDelegate> _acsHook;
public TreasureMaps(DalamudPluginInterface pi, Configuration config) { public TreasureMaps(DalamudPluginInterface pi, Configuration config) {
this.pi = pi ?? throw new ArgumentNullException(nameof(pi), "DalamudPluginInterface cannot be null"); this.Interface = pi ?? throw new ArgumentNullException(nameof(pi), "DalamudPluginInterface cannot be null");
this.config = config ?? throw new ArgumentNullException(nameof(config), "Configuration cannot be null"); this.Config = config ?? throw new ArgumentNullException(nameof(config), "Configuration cannot be null");
IntPtr delegatePtr = this.pi.TargetModuleScanner.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 30 48 8B D9 49 8B F8 41 0F B7 08"); var delegatePtr = this.Interface.TargetModuleScanner.ScanText("48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 30 48 8B D9 49 8B F8 41 0F B7 08");
if (delegatePtr == IntPtr.Zero) { if (delegatePtr == IntPtr.Zero) {
PluginLog.Log("Unable to detect treasure maps because could not find ACS handler delegate"); PluginLog.Log("Unable to detect treasure maps because could not find ACS handler delegate");
return; return;
} }
this.acsHook = new Hook<HandleActorControlSelfDelegate>(delegatePtr, new HandleActorControlSelfDelegate(this.OnACS)); this._acsHook = new Hook<HandleActorControlSelfDelegate>(delegatePtr, new HandleActorControlSelfDelegate(this.OnACS));
this.acsHook.Enable(); this._acsHook.Enable();
} }
public void OnHover(object sender, ulong id) { public void OnHover(object sender, ulong id) {
if (!this.config.ShowOnHover || this.lastMap == null || this.lastMap.EventItemId != id) { if (!this.Config.ShowOnHover || this._lastMap == null || this._lastMap.EventItemId != id) {
return; return;
} }
@ -76,81 +78,71 @@ namespace Globetrotter {
} }
private char OnACS(long a1, long a2, IntPtr dataPtr) { private char OnACS(long a1, long a2, IntPtr dataPtr) {
TreasureMapPacket packet = ParsePacket(dataPtr); var packet = ParsePacket(dataPtr);
if (packet == null) { if (packet == null) {
return this.acsHook.Original(a1, a2, dataPtr); return this._acsHook.Original(a1, a2, dataPtr);
} }
this.lastMap = packet; this._lastMap = packet;
if (this.config.ShowOnOpen && packet.JustOpened) { if (this.Config.ShowOnOpen && packet.JustOpened) {
// this does not work because the offset in memory is not yet updated with the thing // this does not work because the offset in memory is not yet updated with the thing
this.OpenMapLocation(); this.OpenMapLocation();
} }
return this.acsHook.Original(a1, a2, dataPtr); return this._acsHook.Original(a1, a2, dataPtr);
} }
public void OpenMapLocation() { public void OpenMapLocation() {
TreasureMapPacket packet = this.lastMap; var packet = this._lastMap;
if (packet == null) { if (packet == null) {
return; return;
} }
if (!this.MapToRow.TryGetValue(packet.EventItemId, out uint rowId)) { if (!this.MapToRow.TryGetValue(packet.EventItemId, out var rowId)) {
return; return;
} }
TreasureSpot spot = this.pi.Data.GetExcelSheet<TreasureSpot>().GetRow(rowId, packet.SubRowId); var spot = this.Interface.Data.GetExcelSheet<TreasureSpot>().GetRow(rowId, packet.SubRowId);
if (spot == null) {
var loc = spot?.Location?.Value;
var map = loc?.Map?.Value;
var terr = map?.TerritoryType?.Value;
if (terr == null) {
return; return;
} }
if (spot.Location.Value == null) { var x = ToMapCoordinate(loc.X, map.SizeFactor);
return; var y = ToMapCoordinate(loc.Z, map.SizeFactor);
} var mapLink = new MapLinkPayload(
Level loc = spot.Location.Value; this.Interface.Data,
if (loc.Map.Value == null) {
return;
}
Map map = loc.Map.Value;
if (map.TerritoryType.Value == null) {
return;
}
TerritoryType terr = map.TerritoryType.Value;
float x = ToMapCoordinate(loc.X, map.SizeFactor);
float y = ToMapCoordinate(loc.Z, map.SizeFactor);
MapLinkPayload mapLink = new MapLinkPayload(
this.pi.Data,
terr.RowId, terr.RowId,
map.RowId, map.RowId,
ConvertMapCoordinateToRawPosition(x, map.SizeFactor), ConvertMapCoordinateToRawPosition(x, map.SizeFactor),
ConvertMapCoordinateToRawPosition(y, map.SizeFactor) ConvertMapCoordinateToRawPosition(y, map.SizeFactor)
); );
this.pi.Framework.Gui.OpenMapWithMapLink(mapLink); this.Interface.Framework.Gui.OpenMapWithMapLink(mapLink);
} }
public static TreasureMapPacket ParsePacket(IntPtr dataPtr) { private static TreasureMapPacket ParsePacket(IntPtr dataPtr) {
uint category = Marshal.ReadByte(dataPtr); uint category = Marshal.ReadByte(dataPtr);
if (category != TREASURE_MAPS) { if (category != TreasureMapsCode) {
return null; return null;
} }
dataPtr += 4; // skip padding dataPtr += 4; // skip padding
uint param1 = (uint)Marshal.ReadInt32(dataPtr); var param1 = (uint) Marshal.ReadInt32(dataPtr);
dataPtr += 4; dataPtr += 4;
uint param2 = (uint)Marshal.ReadInt32(dataPtr); var param2 = (uint) Marshal.ReadInt32(dataPtr);
dataPtr += 4; dataPtr += 4;
uint param3 = (uint)Marshal.ReadInt32(dataPtr); var param3 = (uint) Marshal.ReadInt32(dataPtr);
uint eventItemId = param1; var eventItemId = param1;
uint subRowId = param2; var subRowId = param2;
bool justOpened = param3 == 1; var justOpened = param3 == 1;
return new TreasureMapPacket(eventItemId, subRowId, justOpened); return new TreasureMapPacket(eventItemId, subRowId, justOpened);
} }
@ -161,8 +153,9 @@ namespace Globetrotter {
var scaledPos = (((pos - 1.0f) * c / 41.0f * 2048.0f) - 1024.0f) / c; var scaledPos = (((pos - 1.0f) * c / 41.0f * 2048.0f) - 1024.0f) / c;
scaledPos *= 1000.0f; scaledPos *= 1000.0f;
return (int)scaledPos; return (int) scaledPos;
} }
private static float ToMapCoordinate(float val, float scale) { private static float ToMapCoordinate(float val, float scale) {
var c = scale / 100f; var c = scale / 100f;
@ -170,27 +163,15 @@ namespace Globetrotter {
return (41f / c * ((val + 1024f) / 2048f)) + 1; return (41f / c * ((val + 1024f) / 2048f)) + 1;
} }
protected virtual void Dispose(bool disposing) {
if (!disposedValue) {
if (disposing) {
this.acsHook?.Dispose();
}
disposedValue = true;
}
}
public void Dispose() { public void Dispose() {
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method this._acsHook?.Dispose();
Dispose(disposing: true);
GC.SuppressFinalize(this);
} }
} }
class TreasureMapPacket { internal class TreasureMapPacket {
public uint EventItemId { get; private set; } public uint EventItemId { get; }
public uint SubRowId { get; private set; } public uint SubRowId { get; }
public bool JustOpened { get; private set; } public bool JustOpened { get; }
public TreasureMapPacket(uint eventItemId, uint subRowId, bool justOpened) { public TreasureMapPacket(uint eventItemId, uint subRowId, bool justOpened) {
this.EventItemId = eventItemId; this.EventItemId = eventItemId;