// // PeriodicBinding.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 System.Diagnostics; using NosSmooth.LocalBinding.Errors; using NosSmooth.LocalBinding.Extensions; using NosSmooth.LocalBinding.Options; using Reloaded.Hooks.Definitions.X86; using Remora.Results; namespace NosSmooth.LocalBinding.Objects; /// /// Binds to a periodic function to allow synchronizing. /// public class PeriodicBinding { [Function ( new FunctionAttribute.Register[0], FunctionAttribute.Register.eax, FunctionAttribute.StackCleanup.Callee, new[] { FunctionAttribute.Register.ebx, FunctionAttribute.Register.esi, FunctionAttribute.Register.edi, FunctionAttribute.Register.ebp, FunctionAttribute.Register.eax, FunctionAttribute.Register.edx, FunctionAttribute.Register.ecx } )] private delegate void PeriodicDelegate(); /// /// Create the periodic binding with finding the periodic function. /// /// The binding manager. /// The options for the binding. /// A periodic binding or an error. public static Result Create(NosBindingManager bindingManager, PeriodicBindingOptions options) { var binding = new PeriodicBinding(); var periodicHookResult = bindingManager.CreateCustomAsmHookFromPattern ("PeriodicBinding.Periodic", binding.PeriodicDetour, options.PeriodicHook); if (!periodicHookResult.IsDefined(out var periodicHook)) { return Result.FromError(periodicHookResult); } binding._periodicHook = periodicHook; return binding; } private NosAsmHook? _periodicHook; private PeriodicBinding() { } /// /// An action called on every period. /// public event EventHandler? PeriodicCall; /// /// Enable all networking hooks. /// public void EnableHooks() { _periodicHook?.Hook.EnableOrActivate(); } /// /// Disable all the hooks that are currently enabled. /// public void DisableHooks() { _periodicHook?.Hook.Disable(); } private void PeriodicDetour() { PeriodicCall?.Invoke(this, System.EventArgs.Empty); } }