// // EntityFollowHook.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 Reloaded.Memory.Sources; using Remora.Results; namespace NosSmooth.LocalBinding.Hooks.Implementations; /// /// A hook of NetworkManager.EntityFollow. /// internal class EntityFollowHook : CancelableNostaleHook, IEntityFollowHook { /// /// 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 EntityFollowHook(browserManager.Memory, browserManager.PlayerManager), hook => hook.Detour, options ); return hook; } private readonly Optional _playerManager; private readonly IMemory _memory; private EntityFollowHook(IMemory memory, Optional playerManager) { _memory = memory; _playerManager = playerManager; } /// public override string Name => IHookManager.EntityFollowName; /// public override Optional WrapperFunction => _playerManager.Map (playerManager => entity => OriginalFunction(playerManager.Address, entity?.Address ?? 0)); /// protected override IEntityFollowHook.EntityFollowDelegate WrapWithCalling (IEntityFollowHook.EntityFollowDelegate function) => ( playerManagerPtr, entityPtr, un0, un1 ) => { CallingFromNosSmooth = true; var res = function(playerManagerPtr, entityPtr, un0, un1); CallingFromNosSmooth = false; return res; }; private nuint Detour ( nuint playerManagerPtr, nuint entityPtr, int unknown1 = 0, int unknown2 = 1 ) { var entity = new MapBaseObj(_memory, entityPtr); var entityArgs = new EntityEventArgs(entity); return HandleCall(entityArgs); } }