// // 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 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.PlayerManager), hook => hook.Detour, options ); return hook; } private readonly PlayerManager _playerManager; private EntityFollowHook(PlayerManager playerManager) { _playerManager = playerManager; } /// public override string Name => IHookManager.EntityFollowName; /// public override IEntityFollowHook.EntityFollowWrapperDelegate WrapperFunction => (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(_playerManager.Memory, entityPtr); var entityArgs = new EntityEventArgs(entity); return HandleCall(entityArgs); } }