feat: use hooking instead of network for detection
This commit is contained in:
parent
5eab84fd83
commit
6d42d72b25
|
@ -25,7 +25,6 @@ namespace Globetrotter {
|
||||||
this.pi.UiBuilder.OnBuildUi += this.ui.Draw;
|
this.pi.UiBuilder.OnBuildUi += this.ui.Draw;
|
||||||
this.pi.UiBuilder.OnOpenConfigUi += this.ui.OpenSettings;
|
this.pi.UiBuilder.OnOpenConfigUi += this.ui.OpenSettings;
|
||||||
this.pi.Framework.Gui.HoveredItemChanged += this.maps.OnHover;
|
this.pi.Framework.Gui.HoveredItemChanged += this.maps.OnHover;
|
||||||
this.pi.Framework.Network.OnNetworkMessage += this.maps.OnNetwork;
|
|
||||||
this.pi.CommandManager.AddHandler("/pglobetrotter", new CommandInfo(this.OnConfigCommand) {
|
this.pi.CommandManager.AddHandler("/pglobetrotter", new CommandInfo(this.OnConfigCommand) {
|
||||||
HelpMessage = "Show the Globetrotter config"
|
HelpMessage = "Show the Globetrotter config"
|
||||||
});
|
});
|
||||||
|
@ -48,7 +47,7 @@ namespace Globetrotter {
|
||||||
this.pi.UiBuilder.OnBuildUi -= this.ui.Draw;
|
this.pi.UiBuilder.OnBuildUi -= this.ui.Draw;
|
||||||
this.pi.UiBuilder.OnOpenConfigUi -= this.ui.OpenSettings;
|
this.pi.UiBuilder.OnOpenConfigUi -= this.ui.OpenSettings;
|
||||||
this.pi.Framework.Gui.HoveredItemChanged -= this.maps.OnHover;
|
this.pi.Framework.Gui.HoveredItemChanged -= this.maps.OnHover;
|
||||||
this.pi.Framework.Network.OnNetworkMessage -= this.maps.OnNetwork;
|
this.maps.Dispose();
|
||||||
this.pi.CommandManager.RemoveHandler("/pglobetrotter");
|
this.pi.CommandManager.RemoveHandler("/pglobetrotter");
|
||||||
this.pi.CommandManager.RemoveHandler("/tmap");
|
this.pi.CommandManager.RemoveHandler("/tmap");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Dalamud.Game.Chat.SeStringHandling.Payloads;
|
using Dalamud.Game.Chat.SeStringHandling.Payloads;
|
||||||
using Dalamud.Game.Internal.Network;
|
using Dalamud.Game.Internal.Network;
|
||||||
|
using Dalamud.Hooking;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using System;
|
using System;
|
||||||
|
@ -7,8 +8,7 @@ using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Globetrotter {
|
namespace Globetrotter {
|
||||||
class TreasureMaps {
|
class TreasureMaps : IDisposable {
|
||||||
private const ushort ACTOR_CONTROL = 0x2b3; // updated 5.3 (hotfix 1)
|
|
||||||
private const uint TREASURE_MAPS = 0x54;
|
private const uint TREASURE_MAPS = 0x54;
|
||||||
|
|
||||||
private static Dictionary<uint, uint> _mapToRow;
|
private static Dictionary<uint, uint> _mapToRow;
|
||||||
|
@ -43,10 +43,23 @@ namespace Globetrotter {
|
||||||
private readonly DalamudPluginInterface pi;
|
private readonly DalamudPluginInterface pi;
|
||||||
private readonly Configuration config;
|
private readonly Configuration config;
|
||||||
private TreasureMapPacket lastMap;
|
private TreasureMapPacket lastMap;
|
||||||
|
private bool disposedValue;
|
||||||
|
|
||||||
|
private delegate char HandleActorControlSelfDelegate(long a1, long a2, IntPtr dataPtr);
|
||||||
|
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.pi = 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");
|
||||||
|
if (delegatePtr == IntPtr.Zero) {
|
||||||
|
PluginLog.Log("Unable to detect treasure maps because could not find ACS handler delegate");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.acsHook = new Hook<HandleActorControlSelfDelegate>(delegatePtr, new HandleActorControlSelfDelegate(this.OnACS));
|
||||||
|
this.acsHook.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnHover(object sender, ulong id) {
|
public void OnHover(object sender, ulong id) {
|
||||||
|
@ -57,14 +70,10 @@ namespace Globetrotter {
|
||||||
this.OpenMapLocation();
|
this.OpenMapLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnNetwork(IntPtr dataPtr, ushort opCode, uint sourceActorId, uint targetActorId, NetworkMessageDirection direction) {
|
private char OnACS(long a1, long a2, IntPtr dataPtr) {
|
||||||
if (direction != NetworkMessageDirection.ZoneDown) {
|
TreasureMapPacket packet = ParsePacket(dataPtr);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TreasureMapPacket packet = ParsePacket(dataPtr, opCode);
|
|
||||||
if (packet == null) {
|
if (packet == null) {
|
||||||
return;
|
return this.acsHook.Original(a1, a2, dataPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastMap = packet;
|
this.lastMap = packet;
|
||||||
|
@ -73,6 +82,8 @@ namespace Globetrotter {
|
||||||
// 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenMapLocation() {
|
public void OpenMapLocation() {
|
||||||
|
@ -119,11 +130,7 @@ namespace Globetrotter {
|
||||||
this.pi.Framework.Gui.OpenMapWithMapLink(mapLink);
|
this.pi.Framework.Gui.OpenMapWithMapLink(mapLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TreasureMapPacket ParsePacket(IntPtr dataPtr, ushort opCode) {
|
public static TreasureMapPacket ParsePacket(IntPtr dataPtr) {
|
||||||
if (opCode != ACTOR_CONTROL) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint category = (uint)Marshal.ReadByte(dataPtr);
|
uint category = (uint)Marshal.ReadByte(dataPtr);
|
||||||
if (category != TREASURE_MAPS) {
|
if (category != TREASURE_MAPS) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -157,6 +164,22 @@ namespace Globetrotter {
|
||||||
val *= c;
|
val *= c;
|
||||||
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() {
|
||||||
|
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
||||||
|
Dispose(disposing: true);
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TreasureMapPacket {
|
class TreasureMapPacket {
|
||||||
|
|
Loading…
Reference in New Issue