// // PlayerWalkHook.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.EventArgs; using NosSmooth.LocalBinding.Structs; using Remora.Results; namespace NosSmooth.LocalBinding.Hooks.Implementations; /// /// A hook of NetworkManager.PlayerWalk. /// internal class PlayerWalkHook : CancelableNostaleHook, IPlayerWalkHook { /// /// Create the packet send hook. /// /// The binding manager. /// The browser manager. /// The options for the binding. /// A packet send hook or an error. public static Result Create (NosBindingManager bindingManager, NosBrowserManager browserManager, HookOptions options) { var hook = CreateHook ( bindingManager, () => new PlayerWalkHook(browserManager.PlayerManager), hook => hook.Detour, options ); return hook; } private PlayerWalkHook(PlayerManager playerManager) { _playerManager = playerManager; } private PlayerManager _playerManager; /// public override string Name => IHookManager.CharacterWalkName; /// public override IPlayerWalkHook.WalkWrapperDelegate WrapperFunction => (x, y) => { var playerManagerObject = _playerManager.Address; return OriginalFunction(playerManagerObject, (y << 16) | x) == 1; }; /// protected override IPlayerWalkHook.WalkDelegate WrapWithCalling(IPlayerWalkHook.WalkDelegate function) => ( playerManagerPtr, position, un0, un1 ) => { CallingFromNosSmooth = true; var res = function(playerManagerPtr, position, un0, un1); CallingFromNosSmooth = false; return res; }; private nuint Detour ( nuint playerManagerPtr, int position, short un0, int un1 ) { var walkArgs = new WalkEventArgs((ushort)(position & 0xFFFF), (ushort)((position >> 16) & 0xFFFF)); return HandleCall(walkArgs); } }