From 05dfa400fada0057af7434ab5a831402641c073b Mon Sep 17 00:00:00 2001 From: Rutherther Date: Sat, 31 Dec 2022 15:39:01 +0100 Subject: [PATCH] feat(client): add user action detector --- .../UserActionDetector.cs | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/Core/NosSmooth.LocalClient/UserActionDetector.cs diff --git a/src/Core/NosSmooth.LocalClient/UserActionDetector.cs b/src/Core/NosSmooth.LocalClient/UserActionDetector.cs new file mode 100644 index 0000000..5828f49 --- /dev/null +++ b/src/Core/NosSmooth.LocalClient/UserActionDetector.cs @@ -0,0 +1,126 @@ +// +// UserActionDetector.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.Data.SqlTypes; +using NosSmooth.LocalBinding.Objects; +using NosSmooth.LocalBinding.Structs; +using Remora.Results; + +namespace NosSmooth.LocalClient; + +/// +/// Tries to determine whether NosTale function calls +/// were made by user. +/// +public class UserActionDetector +{ + private readonly SemaphoreSlim _semaphore; + private bool _handlingDisabled; + private (ushort X, ushort Y) _lastWalkPosition; + + /// + /// Initializes a new instance of the class. + /// + public UserActionDetector() + { + _semaphore = new SemaphoreSlim(1, 1); + } + + /// + /// Execute an action that makes sure walk won't be treated as a user action. + /// + /// The action to execute. + /// The cancellation token for cancelling the operation. + /// The return type. + /// Return value of the action. + public async Task NotUserActionAsync(Func action, CancellationToken ct = default) + { + await _semaphore.WaitAsync(ct); + _handlingDisabled = true; + var result = action(); + _handlingDisabled = false; + _semaphore.Release(); + return result; + } + + /// + /// Execute an action that makes sure walk won't be treated as a user action. + /// + /// The action to execute. + /// The return type. + /// Return value of the action. + public T NotUserAction(Func action) + { + _semaphore.Wait(); + _handlingDisabled = true; + var result = action(); + _handlingDisabled = false; + _semaphore.Release(); + return result; + } + + /// + /// Execute walk action and make sure walk won't be treated as a user action. + /// + /// The player manager. + /// The x coordinate. + /// The y coordinate. + /// The cancellation token used for cancelling the operation. + /// The result of the walk. + public async Task> NotUserWalkAsync(PlayerManagerBinding playerManager, short x, short y, CancellationToken ct = default) + { + return await NotUserActionAsync + ( + () => + { + _lastWalkPosition = ((ushort)x, (ushort)y); + return playerManager.Walk(x, y); + }, + ct + ); + } + + /// + /// Checks whether the given Walk call + /// is a user action or not (either bot or NosTale action). + /// + /// The x coordinate of Walk call. + /// The y coordinate of Walk call. + /// Whether the action is a user action. + public bool IsWalkUserAction(ushort x, ushort y) + { + if (_handlingDisabled) + { + _lastWalkPosition = (x, y); + return false; + } + + if (_lastWalkPosition.X == x && _lastWalkPosition.Y == y) + { + return false; + } + + return true; + } + + /// + /// Checks whether the given PetWalk call + /// is a user action or not (either bot or NosTale action). + /// + /// The pet manager. + /// The x coordinate of PetWalk call. + /// The y coordinate of PetWalk call. + /// Whether the action is a user action. + public bool IsPetWalkUserOperation(PetManager petManager, ushort x, ushort y) + { + if (_handlingDisabled) + { + return false; + } + + return true; + } +} \ No newline at end of file -- 2.48.1