From 2d0fe0a749c4e7587d3e06cb59759707f34e499e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20Boh=C3=A1=C4=8Dek?= Date: Sun, 23 Jan 2022 09:25:08 +0100 Subject: [PATCH] feat(localbinding): split obtaining objects from hooking completely --- .../Extensions/MemoryExtensions.cs | 33 ++++++++ .../ExternalNosBrowser.cs | 14 ++-- .../NosBindingManager.cs | 55 ++++++++++--- .../Objects/PlayerManagerBinding.cs | 37 ++++----- .../Objects/SceneManagerBinding.cs | 26 ++---- .../Options/CharacterBindingOptions.cs | 9 --- .../Options/PlayerManagerOptions.cs | 27 +++++++ .../Options/SceneManagerBindingOptions.cs | 9 --- .../Options/SceneManagerOptions.cs | 30 +++++++ .../Structs/ControlManager.cs | 79 +++++++++++++++++++ .../Structs/MapObjBaseList.cs | 8 +- .../Structs/PlayerManager.cs | 77 ++++-------------- .../Structs/SceneManager.cs | 38 +++++---- 13 files changed, 285 insertions(+), 157 deletions(-) create mode 100644 Local/NosSmooth.LocalBinding/Extensions/MemoryExtensions.cs create mode 100644 Local/NosSmooth.LocalBinding/Options/PlayerManagerOptions.cs create mode 100644 Local/NosSmooth.LocalBinding/Options/SceneManagerOptions.cs create mode 100644 Local/NosSmooth.LocalBinding/Structs/ControlManager.cs diff --git a/Local/NosSmooth.LocalBinding/Extensions/MemoryExtensions.cs b/Local/NosSmooth.LocalBinding/Extensions/MemoryExtensions.cs new file mode 100644 index 0000000..c367ed2 --- /dev/null +++ b/Local/NosSmooth.LocalBinding/Extensions/MemoryExtensions.cs @@ -0,0 +1,33 @@ +// +// MemoryExtensions.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Reloaded.Memory.Sources; + +namespace NosSmooth.LocalBinding.Extensions; + +/// +/// Extension methods for . +/// +public static class MemoryExtensions +{ + /// + /// Follows the offsets to a 32-bit pointer. + /// + /// The memory. + /// The static address to follow offsets from. + /// The offsets, first offset is the 0-th element. + /// A final address. + public static IntPtr FollowStaticAddressOffsets(this IMemory memory, int staticAddress, int[] offsets) + { + int address = staticAddress; + foreach (var offset in offsets) + { + memory.SafeRead((IntPtr)(address + offset), out address); + } + + return (IntPtr)address; + } +} \ No newline at end of file diff --git a/Local/NosSmooth.LocalBinding/ExternalNosBrowser.cs b/Local/NosSmooth.LocalBinding/ExternalNosBrowser.cs index aa1467e..a3a7285 100644 --- a/Local/NosSmooth.LocalBinding/ExternalNosBrowser.cs +++ b/Local/NosSmooth.LocalBinding/ExternalNosBrowser.cs @@ -19,8 +19,8 @@ namespace NosSmooth.LocalBinding; /// public class ExternalNosBrowser { - private readonly CharacterBindingOptions _characterOptions; - private readonly SceneManagerBindingOptions _sceneManagerOptions; + private readonly PlayerManagerOptions _playerManagerOptions; + private readonly SceneManagerOptions _sceneManagerOptions; private PlayerManager? _playerManager; private SceneManager? _sceneManager; @@ -28,16 +28,16 @@ public class ExternalNosBrowser /// Initializes a new instance of the class. /// /// The process to browse. - /// The options for obtaining player manager. + /// The options for obtaining player manager. /// The scene manager options. public ExternalNosBrowser ( Process process, - CharacterBindingOptions characterOptions, - SceneManagerBindingOptions sceneManagerOptions + PlayerManagerOptions playerManagerOptions, + SceneManagerOptions sceneManagerOptions ) { - _characterOptions = characterOptions; + _playerManagerOptions = playerManagerOptions; _sceneManagerOptions = sceneManagerOptions; Process = process; Memory = new ExternalMemory(process); @@ -67,7 +67,7 @@ public class ExternalNosBrowser { if (_playerManager is null) { - var playerManagerResult = PlayerManager.Create(this, _characterOptions); + var playerManagerResult = PlayerManager.Create(this, _playerManagerOptions); if (!playerManagerResult.IsSuccess) { return playerManagerResult; diff --git a/Local/NosSmooth.LocalBinding/NosBindingManager.cs b/Local/NosSmooth.LocalBinding/NosBindingManager.cs index cad9805..aee0c75 100644 --- a/Local/NosSmooth.LocalBinding/NosBindingManager.cs +++ b/Local/NosSmooth.LocalBinding/NosBindingManager.cs @@ -23,6 +23,7 @@ public class NosBindingManager : IDisposable { private readonly CharacterBindingOptions _characterBindingOptions; private readonly NetworkBindingOptions _networkBindingOptions; + private readonly ExternalNosBrowser _nosBrowser; private SceneManagerBindingOptions _sceneManagerBindingOptions; private NetworkBinding? _networkBinding; @@ -35,11 +36,15 @@ public class NosBindingManager : IDisposable /// The character binding options. /// The network binding options. /// The scene manager binding options. + /// The player manager options. + /// The scene manager options. public NosBindingManager ( IOptions characterBindingOptions, IOptions networkBindingOptions, - IOptions sceneManagerBindingOptions + IOptions sceneManagerBindingOptions, + IOptions playerManagerOptions, + IOptions sceneManagerOptions ) { Hooks = new ReloadedHooks(); @@ -48,6 +53,8 @@ public class NosBindingManager : IDisposable _characterBindingOptions = characterBindingOptions.Value; _networkBindingOptions = networkBindingOptions.Value; _sceneManagerBindingOptions = sceneManagerBindingOptions.Value; + _nosBrowser = new ExternalNosBrowser + (Process.GetCurrentProcess(), playerManagerOptions.Value, sceneManagerOptions.Value); } /// @@ -76,7 +83,9 @@ public class NosBindingManager : IDisposable if (_networkBinding is null) { throw new InvalidOperationException - ("Could not get network. The binding manager is not initialized. Did you forget to call NosBindingManager.Initialize?"); + ( + "Could not get network. The binding manager is not initialized. Did you forget to call NosBindingManager.Initialize?" + ); } return _networkBinding; @@ -94,7 +103,9 @@ public class NosBindingManager : IDisposable if (_characterBinding is null) { throw new InvalidOperationException - ("Could not get character. The binding manager is not initialized. Did you forget to call NosBindingManager.Initialize?"); + ( + "Could not get character. The binding manager is not initialized. Did you forget to call NosBindingManager.Initialize?" + ); } return _characterBinding; @@ -112,7 +123,9 @@ public class NosBindingManager : IDisposable if (_sceneManagerBinding is null) { throw new InvalidOperationException - ("Could not get scene manager. The binding manager is not initialized. Did you forget to call NosBindingManager.Initialize?"); + ( + "Could not get scene manager. The binding manager is not initialized. Did you forget to call NosBindingManager.Initialize?" + ); } return _sceneManagerBinding; @@ -132,19 +145,41 @@ public class NosBindingManager : IDisposable } _networkBinding = network.Entity; - var character = PlayerManagerBinding.Create(this, _characterBindingOptions); - if (!character.IsSuccess) + var playerManager = _nosBrowser.GetPlayerManager(); + if (!playerManager.IsSuccess) { - return Result.FromError(character); + return Result.FromError(playerManager); } - _characterBinding = character.Entity; - var sceneManager = SceneManagerBinding.Create(this, _sceneManagerBindingOptions); + var sceneManager = _nosBrowser.GetSceneManager(); if (!sceneManager.IsSuccess) { return Result.FromError(sceneManager); } - _sceneManagerBinding = sceneManager.Entity; + + var playerManagerBinding = PlayerManagerBinding.Create + ( + this, + playerManager.Entity, + _characterBindingOptions + ); + if (!playerManagerBinding.IsSuccess) + { + return Result.FromError(playerManagerBinding); + } + _characterBinding = playerManagerBinding.Entity; + + var sceneManagerBinding = SceneManagerBinding.Create + ( + this, + sceneManager.Entity, + _sceneManagerBindingOptions + ); + if (!sceneManagerBinding.IsSuccess) + { + return Result.FromError(sceneManagerBinding); + } + _sceneManagerBinding = sceneManagerBinding.Entity; return Result.FromSuccess(); } diff --git a/Local/NosSmooth.LocalBinding/Objects/PlayerManagerBinding.cs b/Local/NosSmooth.LocalBinding/Objects/PlayerManagerBinding.cs index 6141202..809fe89 100644 --- a/Local/NosSmooth.LocalBinding/Objects/PlayerManagerBinding.cs +++ b/Local/NosSmooth.LocalBinding/Objects/PlayerManagerBinding.cs @@ -19,7 +19,7 @@ namespace NosSmooth.LocalBinding.Objects; /// public class PlayerManagerBinding { - [Function + [Function ( new[] { FunctionAttribute.Register.eax, FunctionAttribute.Register.edx, FunctionAttribute.Register.ecx }, FunctionAttribute.Register.eax, @@ -53,16 +53,12 @@ public class PlayerManagerBinding /// Create the network binding with finding the network object and functions. /// /// The binding manager. + /// The player manager. /// The options for the binding. /// A network binding or an error. - public static Result Create(NosBindingManager bindingManager, CharacterBindingOptions options) + public static Result Create(NosBindingManager bindingManager, PlayerManager playerManager, CharacterBindingOptions options) { var process = Process.GetCurrentProcess(); - var characterObjectAddress = bindingManager.Scanner.CompiledFindPattern(options.CharacterObjectPattern); - if (!characterObjectAddress.Found) - { - return new BindingNotFoundError(options.CharacterObjectPattern, "CharacterBinding"); - } var walkFunctionAddress = bindingManager.Scanner.CompiledFindPattern(options.WalkFunctionPattern); if (!walkFunctionAddress.Found) @@ -97,7 +93,7 @@ public class PlayerManagerBinding var binding = new PlayerManagerBinding ( bindingManager, - (IntPtr)(characterObjectAddress.Offset + (int)process.MainModule!.BaseAddress + 0x06), + playerManager, walkWrapper, followEntityWrapper, unfollowEntityWrapper @@ -129,7 +125,6 @@ public class PlayerManagerBinding } private readonly NosBindingManager _bindingManager; - private readonly IntPtr _characterAddress; private IHook? _walkHook; private IHook? _followHook; @@ -142,19 +137,24 @@ public class PlayerManagerBinding private PlayerManagerBinding ( NosBindingManager bindingManager, - IntPtr characterAddress, + PlayerManager playerManager, WalkDelegate originalWalk, FollowEntityDelegate originalFollowEntity, UnfollowEntityDelegate originalUnfollowEntity ) { + PlayerManager = playerManager; _bindingManager = bindingManager; - _characterAddress = characterAddress; _originalWalk = originalWalk; _originalFollowEntity = originalFollowEntity; _originalUnfollowEntity = originalUnfollowEntity; } + /// + /// Gets the player manager. + /// + public PlayerManager PlayerManager { get; } + /// /// Event that is called when walk was called by NosTale. /// @@ -181,15 +181,6 @@ public class PlayerManagerBinding return Result.FromSuccess(); } - private IntPtr GetCharacterAddress() - { - IntPtr characterAddress = _characterAddress; - _bindingManager.Memory.Read(characterAddress, out characterAddress); - _bindingManager.Memory.Read(characterAddress, out characterAddress); - - return characterAddress; - } - /// /// Walk to the given position. /// @@ -201,7 +192,7 @@ public class PlayerManagerBinding int param = (y << 16) | x; try { - return _originalWalk(GetCharacterAddress(), param); + return _originalWalk(PlayerManager.Address, param); } catch (Exception e) { @@ -237,7 +228,7 @@ public class PlayerManagerBinding { try { - _originalFollowEntity(GetCharacterAddress(), entityAddress); + _originalFollowEntity(PlayerManager.Address, entityAddress); } catch (Exception e) { @@ -255,7 +246,7 @@ public class PlayerManagerBinding { try { - _originalUnfollowEntity(GetCharacterAddress()); + _originalUnfollowEntity(PlayerManager.Address); } catch (Exception e) { diff --git a/Local/NosSmooth.LocalBinding/Objects/SceneManagerBinding.cs b/Local/NosSmooth.LocalBinding/Objects/SceneManagerBinding.cs index 9fee27c..3ce7946 100644 --- a/Local/NosSmooth.LocalBinding/Objects/SceneManagerBinding.cs +++ b/Local/NosSmooth.LocalBinding/Objects/SceneManagerBinding.cs @@ -36,18 +36,13 @@ public class SceneManagerBinding /// Create the scene manager binding. /// /// The binding manager. + /// The scene manager. /// The options for the binding. /// A network binding or an error. public static Result Create - (NosBindingManager bindingManager, SceneManagerBindingOptions bindingOptions) + (NosBindingManager bindingManager, SceneManager sceneManager, SceneManagerBindingOptions bindingOptions) { var process = Process.GetCurrentProcess(); - var sceneManagerObjectAddress = bindingManager.Scanner.CompiledFindPattern - (bindingOptions.SceneManagerObjectPattern); - if (!sceneManagerObjectAddress.Found) - { - return new BindingNotFoundError(bindingOptions.SceneManagerObjectPattern, "SceneManagerBinding"); - } var focusEntityAddress = bindingManager.Scanner.CompiledFindPattern(bindingOptions.FocusEntityPattern); if (!focusEntityAddress.Found) @@ -62,7 +57,7 @@ public class SceneManagerBinding var binding = new SceneManagerBinding ( bindingManager, - (IntPtr)(sceneManagerObjectAddress.Offset + (int)process.MainModule!.BaseAddress + 0x01), + sceneManager, focusEntityWrapper ); @@ -77,7 +72,6 @@ public class SceneManagerBinding } private readonly NosBindingManager _bindingManager; - private readonly IntPtr _sceneManagerAddress; private FocusEntityDelegate _originalFocusEntity; private IHook? _focusHook; @@ -85,13 +79,13 @@ public class SceneManagerBinding private SceneManagerBinding ( NosBindingManager bindingManager, - IntPtr sceneManagerAddress, + SceneManager sceneManager, FocusEntityDelegate originalFocusEntity ) { _originalFocusEntity = originalFocusEntity; _bindingManager = bindingManager; - _sceneManagerAddress = sceneManagerAddress; + SceneManager = sceneManager; } /// @@ -105,15 +99,7 @@ public class SceneManagerBinding /// /// Gets the scene manager object. /// - public SceneManager SceneManager => new SceneManager(_bindingManager.Memory, GetSceneManagerAddress()); - - private IntPtr GetSceneManagerAddress() - { - IntPtr sceneManagerAddress = _sceneManagerAddress; - _bindingManager.Memory.Read(sceneManagerAddress, out sceneManagerAddress); - - return sceneManagerAddress; - } + public SceneManager SceneManager { get; } /// /// Focus the entity with the given id. diff --git a/Local/NosSmooth.LocalBinding/Options/CharacterBindingOptions.cs b/Local/NosSmooth.LocalBinding/Options/CharacterBindingOptions.cs index 0224a94..c06dee9 100644 --- a/Local/NosSmooth.LocalBinding/Options/CharacterBindingOptions.cs +++ b/Local/NosSmooth.LocalBinding/Options/CharacterBindingOptions.cs @@ -18,15 +18,6 @@ public class CharacterBindingOptions /// public bool HookWalk { get; set; } = true; - /// - /// Gets or sets the pattern to find the character object at. - /// - /// - /// The address of the object is "three pointers down" from address found on this pattern. - /// - public string CharacterObjectPattern { get; set; } - = "33 C9 8B 55 FC A1 ?? ?? ?? ?? E8 ?? ?? ?? ??"; - /// /// Gets or sets the pattern to find the walk function at. /// diff --git a/Local/NosSmooth.LocalBinding/Options/PlayerManagerOptions.cs b/Local/NosSmooth.LocalBinding/Options/PlayerManagerOptions.cs new file mode 100644 index 0000000..4fa5fd6 --- /dev/null +++ b/Local/NosSmooth.LocalBinding/Options/PlayerManagerOptions.cs @@ -0,0 +1,27 @@ +// +// PlayerManagerOptions.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.LocalBinding.Structs; + +namespace NosSmooth.LocalBinding.Options; + +/// +/// Options for . +/// +public class PlayerManagerOptions +{ + /// + /// Gets or sets the pattern to find the character object at. + /// + public string PlayerManagerPattern { get; set; } + = "33 C9 8B 55 FC A1 ?? ?? ?? ?? E8 ?? ?? ?? ??"; + + /// + /// Gets or sets the offsets to find the player manager at from the static address. + /// + public int[] PlayerManagerOffsets { get; set; } + = { 6, 0, 0 }; +} \ No newline at end of file diff --git a/Local/NosSmooth.LocalBinding/Options/SceneManagerBindingOptions.cs b/Local/NosSmooth.LocalBinding/Options/SceneManagerBindingOptions.cs index fdd9266..18d669c 100644 --- a/Local/NosSmooth.LocalBinding/Options/SceneManagerBindingOptions.cs +++ b/Local/NosSmooth.LocalBinding/Options/SceneManagerBindingOptions.cs @@ -13,15 +13,6 @@ namespace NosSmooth.LocalBinding.Options; /// public class SceneManagerBindingOptions { - /// - /// Gets or sets the pattern to find the scene manager object at. - /// - /// - /// The address of the object is direct pointer to the scene manager. - /// - public string SceneManagerObjectPattern { get; set; } - = "FF ?? ?? ?? ?? ?? FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF"; - /// /// Gets or sets the pattern to find the focus entity method at. /// diff --git a/Local/NosSmooth.LocalBinding/Options/SceneManagerOptions.cs b/Local/NosSmooth.LocalBinding/Options/SceneManagerOptions.cs new file mode 100644 index 0000000..80260a6 --- /dev/null +++ b/Local/NosSmooth.LocalBinding/Options/SceneManagerOptions.cs @@ -0,0 +1,30 @@ +// +// SceneManagerOptions.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NosSmooth.LocalBinding.Structs; + +namespace NosSmooth.LocalBinding.Options; + +/// +/// Options for . +/// +public class SceneManagerOptions +{ + /// + /// Gets or sets the pattern to find the scene manager object at. + /// + /// + /// The address of the object is direct pointer to the scene manager. + /// + public string SceneManagerObjectPattern { get; set; } + = "FF ?? ?? ?? ?? ?? FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF"; + + /// + /// Gets or sets the offsets to find the scene manager at from the static address. + /// + public int[] SceneManagerOffsets { get; set; } + = { 1 }; +} \ No newline at end of file diff --git a/Local/NosSmooth.LocalBinding/Structs/ControlManager.cs b/Local/NosSmooth.LocalBinding/Structs/ControlManager.cs new file mode 100644 index 0000000..3b66661 --- /dev/null +++ b/Local/NosSmooth.LocalBinding/Structs/ControlManager.cs @@ -0,0 +1,79 @@ +// +// ControlManager.cs +// +// Copyright (c) František Boháček. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using Reloaded.Memory.Sources; + +namespace NosSmooth.LocalBinding.Structs; + +/// +/// Base for player and pet managers. +/// +public abstract class ControlManager +{ + private readonly IMemory _memory; + + /// + /// Initializes a new instance of the class. + /// + /// The memory. + public ControlManager(IMemory memory) + { + _memory = memory; + } + + /// + /// Gets the address of the manager. + /// + public abstract IntPtr Address { get; } + + /// + /// Gets the current player position x coordinate. + /// + public int X + { + get + { + _memory.SafeRead(Address + 0x4, out short x); + return x; + } + } + + /// + /// Gets the current player position x coordinate. + /// + public int Y + { + get + { + _memory.SafeRead(Address + 0x6, out short y); + return y; + } + } + + /// + /// Gets the target x coordinate the player is moving to. + /// + public int TargetX + { + get + { + _memory.SafeRead(Address + 0x8, out short targetX); + return targetX; + } + } + + /// + /// Gets the target y coordinate the player is moving to. + /// + public int TargetY + { + get + { + _memory.SafeRead(Address + 0xA, out short targetX); + return targetX; + } + } +} \ No newline at end of file diff --git a/Local/NosSmooth.LocalBinding/Structs/MapObjBaseList.cs b/Local/NosSmooth.LocalBinding/Structs/MapObjBaseList.cs index 66755f2..13585b0 100644 --- a/Local/NosSmooth.LocalBinding/Structs/MapObjBaseList.cs +++ b/Local/NosSmooth.LocalBinding/Structs/MapObjBaseList.cs @@ -17,7 +17,7 @@ public class MapObjBaseList : IEnumerable { private readonly IMemory _memory; private readonly IntPtr _objListPointer; - private readonly ArrayPtr _objList; + private readonly ArrayPtr _objList; /// /// Initializes a new instance of the class. @@ -26,8 +26,8 @@ public class MapObjBaseList : IEnumerable /// The object list pointer. public MapObjBaseList(IMemory memory, IntPtr objListPointer) { - memory.Read(objListPointer + 0x04, out IntPtr arrayFirst); - _objList = new ArrayPtr((ulong)arrayFirst, source: memory); + memory.Read(objListPointer + 0x04, out uint arrayFirst); + _objList = new ArrayPtr(arrayFirst, source: memory); _memory = memory; _objListPointer = objListPointer; } @@ -46,7 +46,7 @@ public class MapObjBaseList : IEnumerable throw new IndexOutOfRangeException(); } - return new MapBaseObj(_memory, _objList[index]); + return new MapBaseObj(_memory, (IntPtr)_objList[index]); } } diff --git a/Local/NosSmooth.LocalBinding/Structs/PlayerManager.cs b/Local/NosSmooth.LocalBinding/Structs/PlayerManager.cs index df934b9..1e3519c 100644 --- a/Local/NosSmooth.LocalBinding/Structs/PlayerManager.cs +++ b/Local/NosSmooth.LocalBinding/Structs/PlayerManager.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Options; using NosSmooth.LocalBinding.Errors; +using NosSmooth.LocalBinding.Extensions; using NosSmooth.LocalBinding.Options; using Reloaded.Memory.Sources; using Remora.Results; @@ -15,7 +16,7 @@ namespace NosSmooth.LocalBinding.Structs; /// /// NosTale player manager. /// -public class PlayerManager +public class PlayerManager : ControlManager { /// /// Create instance. @@ -23,12 +24,12 @@ public class PlayerManager /// The NosTale process browser. /// The options. /// The player manager or an error. - public static Result Create(ExternalNosBrowser nosBrowser, CharacterBindingOptions options) + public static Result Create(ExternalNosBrowser nosBrowser, PlayerManagerOptions options) { - var characterObjectAddress = nosBrowser.Scanner.CompiledFindPattern(options.CharacterObjectPattern); + var characterObjectAddress = nosBrowser.Scanner.CompiledFindPattern(options.PlayerManagerPattern); if (!characterObjectAddress.Found) { - return new BindingNotFoundError(options.CharacterObjectPattern, "PlayerManager"); + return new BindingNotFoundError(options.PlayerManagerPattern, "PlayerManager"); } if (nosBrowser.Process.MainModule is null) @@ -36,77 +37,33 @@ public class PlayerManager return new NotFoundError("Cannot find the main module of the target process."); } - var ptrAddress = nosBrowser.Process.MainModule.BaseAddress + characterObjectAddress.Offset + 0x06; - nosBrowser.Memory.SafeRead(ptrAddress, out int address); - nosBrowser.Memory.SafeRead((IntPtr)address, out address); - return new PlayerManager(nosBrowser.Memory, (IntPtr)address); + var staticAddress = (int)nosBrowser.Process.MainModule.BaseAddress + characterObjectAddress.Offset; + return new PlayerManager(nosBrowser.Memory, staticAddress, options.PlayerManagerOffsets); } private readonly IMemory _memory; + private readonly int _staticPlayerManagerAddress; + private readonly int[] _playerManagerOffsets; /// /// Initializes a new instance of the class. /// /// The memory. - /// The pointer to the beginning of the player manager structure. - public PlayerManager(IMemory memory, IntPtr playerManager) + /// The pointer to the beginning of the player manager structure. + /// The offsets to get the player manager address from the static one. + public PlayerManager(IMemory memory, int staticPlayerManagerAddress, int[] playerManagerOffsets) + : base(memory) { _memory = memory; - Address = playerManager; + _staticPlayerManagerAddress = staticPlayerManagerAddress; + _playerManagerOffsets = playerManagerOffsets; } /// /// Gets the address to the player manager. /// - public IntPtr Address { get; } - - /// - /// Gets the current player position x coordinate. - /// - public int X - { - get - { - _memory.SafeRead(Address + 0x4, out short x); - return x; - } - } - - /// - /// Gets the current player position x coordinate. - /// - public int Y - { - get - { - _memory.SafeRead(Address + 0x6, out short y); - return y; - } - } - - /// - /// Gets the target x coordinate the player is moving to. - /// - public int TargetX - { - get - { - _memory.SafeRead(Address + 0x8, out short targetX); - return targetX; - } - } - - /// - /// Gets the target y coordinate the player is moving to. - /// - public int TargetY - { - get - { - _memory.SafeRead(Address + 0xA, out short targetX); - return targetX; - } - } + public override IntPtr Address => _memory.FollowStaticAddressOffsets + (_staticPlayerManagerAddress, _playerManagerOffsets); /// /// Gets the player object. diff --git a/Local/NosSmooth.LocalBinding/Structs/SceneManager.cs b/Local/NosSmooth.LocalBinding/Structs/SceneManager.cs index a6c3e53..d426f36 100644 --- a/Local/NosSmooth.LocalBinding/Structs/SceneManager.cs +++ b/Local/NosSmooth.LocalBinding/Structs/SceneManager.cs @@ -5,6 +5,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using NosSmooth.LocalBinding.Errors; +using NosSmooth.LocalBinding.Extensions; using NosSmooth.LocalBinding.Options; using Reloaded.Memory.Sources; using Remora.Results; @@ -22,7 +23,7 @@ public class SceneManager /// The NosTale process browser. /// The options. /// The player manager or an error. - public static Result Create(ExternalNosBrowser nosBrowser, SceneManagerBindingOptions options) + public static Result Create(ExternalNosBrowser nosBrowser, SceneManagerOptions options) { var characterObjectAddress = nosBrowser.Scanner.CompiledFindPattern(options.SceneManagerObjectPattern); if (!characterObjectAddress.Found) @@ -35,44 +36,51 @@ public class SceneManager return new NotFoundError("Cannot find the main module of the target process."); } - var ptrAddress = nosBrowser.Process.MainModule.BaseAddress + characterObjectAddress.Offset; - nosBrowser.Memory.SafeRead(ptrAddress, out ptrAddress); - return new SceneManager(nosBrowser.Memory, ptrAddress); + int staticManagerAddress = (int)nosBrowser.Process.MainModule.BaseAddress + characterObjectAddress.Offset + 1; + return new SceneManager(nosBrowser.Memory, staticManagerAddress, options.SceneManagerOffsets); } + private readonly int[] _sceneManagerOffsets; private readonly IMemory _memory; - private readonly IntPtr _sceneManager; + private readonly int _staticSceneManagerAddress; /// /// Initializes a new instance of the class. /// /// The memory. - /// The pointer to the scene manager. - public SceneManager(IMemory memory, IntPtr sceneManager) + /// The pointer to the scene manager. + /// The offsets from the static scene manager address. + public SceneManager(IMemory memory, int staticSceneManagerAddress, int[] sceneManagerOffsets) { _memory = memory; - _sceneManager = sceneManager; + _staticSceneManagerAddress = staticSceneManagerAddress; + _sceneManagerOffsets = sceneManagerOffsets; } + /// + /// Gets the address of the scene manager. + /// + public IntPtr Address => _memory.FollowStaticAddressOffsets(_staticSceneManagerAddress, _sceneManagerOffsets); + /// /// Gets the player list. /// - public MapObjBaseList PlayerList => new MapObjBaseList(_memory, ReadPtr(_sceneManager + 0xC)); + public MapObjBaseList PlayerList => new MapObjBaseList(_memory, ReadPtr(Address + 0xC)); /// /// Gets the monster list. /// - public MapObjBaseList MonsterList => new MapObjBaseList(_memory, ReadPtr(_sceneManager + 0x10)); + public MapObjBaseList MonsterList => new MapObjBaseList(_memory, ReadPtr(Address + 0x10)); /// /// Gets the npc list. /// - public MapObjBaseList NpcList => new MapObjBaseList(_memory, ReadPtr(_sceneManager + 0x14)); + public MapObjBaseList NpcList => new MapObjBaseList(_memory, ReadPtr(Address + 0x14)); /// /// Gets the item list. /// - public MapObjBaseList ItemList => new MapObjBaseList(_memory, ReadPtr(_sceneManager + 0x18)); + public MapObjBaseList ItemList => new MapObjBaseList(_memory, ReadPtr(Address + 0x18)); /// /// Gets the entity that is currently being followed by the player. @@ -81,7 +89,7 @@ public class SceneManager { get { - var ptr = ReadPtr(_sceneManager + 0x48); + var ptr = ReadPtr(Address + 0x48); if (ptr == IntPtr.Zero) { return null; @@ -93,7 +101,7 @@ public class SceneManager private IntPtr ReadPtr(IntPtr ptr) { - _memory.Read(ptr, out IntPtr read); - return read; + _memory.Read(ptr, out int read); + return (IntPtr)read; } } \ No newline at end of file -- 2.49.0