M src/Core/NosSmooth.LocalClient/CommandHandlers/Walk/ControlCommandWalkHandler.cs => src/Core/NosSmooth.LocalClient/CommandHandlers/Walk/ControlCommandWalkHandler.cs +3 -3
@@ 20,7 20,7 @@ namespace NosSmooth.LocalClient.CommandHandlers.Walk;
internal class ControlCommandWalkHandler
{
private readonly INostaleClient _nostaleClient;
- private readonly Func<short, short, Result<bool>> _walkFunction;
+ private readonly Func<short, short, CancellationToken, Task<Result<bool>>> _walkFunction;
private readonly ControlManager _controlManager;
private readonly WalkCommandHandlerOptions _options;
@@ 38,7 38,7 @@ internal class ControlCommandWalkHandler
public ControlCommandWalkHandler
(
INostaleClient nostaleClient,
- Func<short, short, Result<bool>> walkFunction,
+ Func<short, short, CancellationToken, Task<Result<bool>>> walkFunction,
ControlManager controlManager,
WalkCommandHandlerOptions options
)
@@ 131,7 131,7 @@ internal class ControlCommandWalkHandler
private async Task<Result> WalkGrantedCallback(CancellationToken ct)
{
- var result = _walkFunction(_x, _y);
+ var result = await _walkFunction(_x, _y, ct);
if (!result.IsSuccess)
{
return Result.FromError(result);
M src/Core/NosSmooth.LocalClient/CommandHandlers/Walk/PetWalkCommandHandler.cs => src/Core/NosSmooth.LocalClient/CommandHandlers/Walk/PetWalkCommandHandler.cs +6 -1
@@ 25,6 25,7 @@ public class PetWalkCommandHandler : ICommandHandler<PetWalkCommand>
public const string PetWalkControlGroup = "PetWalk";
private readonly PetManagerBinding _petManagerBinding;
+ private readonly UserActionDetector _userActionDetector;
private readonly INostaleClient _nostaleClient;
private readonly WalkCommandHandlerOptions _options;
@@ 32,17 33,20 @@ public class PetWalkCommandHandler : ICommandHandler<PetWalkCommand>
/// Initializes a new instance of the <see cref="PetWalkCommandHandler"/> class.
/// </summary>
/// <param name="petManagerBinding">The character object binding.</param>
+ /// <param name="userActionDetector">The user action detector.</param>
/// <param name="nostaleClient">The nostale client.</param>
/// <param name="options">The options.</param>
public PetWalkCommandHandler
(
PetManagerBinding petManagerBinding,
+ UserActionDetector userActionDetector,
INostaleClient nostaleClient,
IOptions<WalkCommandHandlerOptions> options
)
{
_options = options.Value;
_petManagerBinding = petManagerBinding;
+ _userActionDetector = userActionDetector;
_nostaleClient = nostaleClient;
}
@@ 58,7 62,8 @@ public class PetWalkCommandHandler : ICommandHandler<PetWalkCommand>
var handler = new ControlCommandWalkHandler
(
_nostaleClient,
- (x, y) => _petManagerBinding.PetWalk(command.PetSelector, x, y),
+ async (x, y, ct) => await _userActionDetector.NotUserActionAsync
+ (() => _petManagerBinding.PetWalk(command.PetSelector, x, y), ct),
petManager,
_options
);
M src/Core/NosSmooth.LocalClient/CommandHandlers/Walk/PlayerWalkCommandHandler.cs => src/Core/NosSmooth.LocalClient/CommandHandlers/Walk/PlayerWalkCommandHandler.cs +6 -1
@@ 26,6 26,7 @@ public class PlayerWalkCommandHandler : ICommandHandler<PlayerWalkCommand>
public const string PlayerWalkControlGroup = "PlayerWalk";
private readonly PlayerManagerBinding _playerManagerBinding;
+ private readonly UserActionDetector _userActionDetector;
private readonly INostaleClient _nostaleClient;
private readonly WalkCommandHandlerOptions _options;
@@ 33,17 34,20 @@ public class PlayerWalkCommandHandler : ICommandHandler<PlayerWalkCommand>
/// Initializes a new instance of the <see cref="PlayerWalkCommandHandler"/> class.
/// </summary>
/// <param name="playerManagerBinding">The character object binding.</param>
+ /// <param name="userActionDetector">The user action detector.</param>
/// <param name="nostaleClient">The nostale client.</param>
/// <param name="options">The options.</param>
public PlayerWalkCommandHandler
(
PlayerManagerBinding playerManagerBinding,
+ UserActionDetector userActionDetector,
INostaleClient nostaleClient,
IOptions<WalkCommandHandlerOptions> options
)
{
_options = options.Value;
_playerManagerBinding = playerManagerBinding;
+ _userActionDetector = userActionDetector;
_nostaleClient = nostaleClient;
}
@@ 53,7 57,8 @@ public class PlayerWalkCommandHandler : ICommandHandler<PlayerWalkCommand>
var handler = new ControlCommandWalkHandler
(
_nostaleClient,
- (x, y) => _playerManagerBinding.Walk(x, y),
+ async (x, y, ct) =>
+ await _userActionDetector.NotUserWalkAsync(_playerManagerBinding, x, y, ct),
_playerManagerBinding.PlayerManager,
_options
);
M src/Core/NosSmooth.LocalClient/Extensions/ServiceCollectionExtensions.cs => src/Core/NosSmooth.LocalClient/Extensions/ServiceCollectionExtensions.cs +1 -0
@@ 29,6 29,7 @@ public static class ServiceCollectionExtensions
serviceCollection.AddNostaleCore();
serviceCollection.AddNostaleBindings();
serviceCollection
+ .AddSingleton<UserActionDetector>()
.AddTakeControlCommand()
.AddCommandHandler<AttackCommandHandler>()
.AddCommandHandler<PlayerWalkCommandHandler>()
M src/Core/NosSmooth.LocalClient/NostaleLocalClient.cs => src/Core/NosSmooth.LocalClient/NostaleLocalClient.cs +31 -0
@@ 14,6 14,7 @@ using NosSmooth.Core.Extensions;
using NosSmooth.Core.Packets;
using NosSmooth.LocalBinding.Objects;
using NosSmooth.LocalBinding.Structs;
+using NosSmooth.LocalClient.CommandHandlers.Walk;
using NosSmooth.Packets;
using NosSmooth.Packets.Errors;
using NosSmooth.PacketSerializer.Abstractions.Attributes;
@@ 36,6 37,7 @@ public class NostaleLocalClient : BaseNostaleClient
private readonly ControlCommands _controlCommands;
private readonly IPacketSerializer _packetSerializer;
private readonly IPacketHandler _packetHandler;
+ private readonly UserActionDetector _userActionDetector;
private readonly ILogger _logger;
private readonly IServiceProvider _provider;
private readonly LocalClientOptions _options;
@@ 52,6 54,7 @@ public class NostaleLocalClient : BaseNostaleClient
/// <param name="commandProcessor">The command processor.</param>
/// <param name="packetSerializer">The packet serializer.</param>
/// <param name="packetHandler">The packet handler.</param>
+ /// <param name="userActionDetector">The user action detector.</param>
/// <param name="logger">The logger.</param>
/// <param name="options">The options for the client.</param>
/// <param name="provider">The dependency injection provider.</param>
@@ 64,6 67,7 @@ public class NostaleLocalClient : BaseNostaleClient
CommandProcessor commandProcessor,
IPacketSerializer packetSerializer,
IPacketHandler packetHandler,
+ UserActionDetector userActionDetector,
ILogger<NostaleLocalClient> logger,
IOptions<LocalClientOptions> options,
IServiceProvider provider
@@ 77,6 81,7 @@ public class NostaleLocalClient : BaseNostaleClient
_controlCommands = controlCommands;
_packetSerializer = packetSerializer;
_packetHandler = packetHandler;
+ _userActionDetector = userActionDetector;
_logger = logger;
_provider = provider;
}
@@ 235,11 240,37 @@ public class NostaleLocalClient : BaseNostaleClient
private bool PetWalk(PetManager petManager, ushort x, ushort y)
{
+ if (!_userActionDetector.IsPetWalkUserOperation(petManager, x, y))
+ { // do not cancel operations made by NosTale or bot
+ return true;
+ }
+
+ if (_controlCommands.AllowUserActions)
+ {
+ Task.Run
+ (
+ async () => await _controlCommands.CancelAsync
+ (ControlCommandsFilter.UserCancellable, false, (CancellationToken)_stopRequested!)
+ );
+ }
return _controlCommands.AllowUserActions;
}
private bool Walk(ushort x, ushort y)
{
+ if (!_userActionDetector.IsWalkUserAction(x, y))
+ { // do not cancel operations made by NosTale or bot
+ return true;
+ }
+
+ if (_controlCommands.AllowUserActions)
+ {
+ Task.Run
+ (
+ async () => await _controlCommands.CancelAsync
+ (ControlCommandsFilter.UserCancellable, false, (CancellationToken)_stopRequested!)
+ );
+ }
return _controlCommands.AllowUserActions;
}
}=
\ No newline at end of file