~ruther/NosSmooth.Local

77a89a28517390d95e111cd86e0fb151410ce6fe — Rutherther 2 years ago 7535dd9
feat: use synchronizer for NosTale calls
M src/Core/NosSmooth.LocalClient/CommandHandlers/Attack/AttackCommandHandler.cs => src/Core/NosSmooth.LocalClient/CommandHandlers/Attack/AttackCommandHandler.cs +11 -2
@@ 9,6 9,7 @@ using NosSmooth.Core.Commands;
using NosSmooth.Core.Commands.Attack;
using NosSmooth.Core.Commands.Control;
using NosSmooth.Core.Extensions;
using NosSmooth.LocalBinding;
using NosSmooth.LocalBinding.Objects;
using NosSmooth.LocalBinding.Structs;
using Remora.Results;


@@ 21,6 22,7 @@ namespace NosSmooth.LocalClient.CommandHandlers.Attack;
public class AttackCommandHandler : ICommandHandler<AttackCommand>
{
    private readonly INostaleClient _nostaleClient;
    private readonly NosThreadSynchronizer _synchronizer;
    private readonly UnitManagerBinding _unitManagerBinding;
    private readonly SceneManager _sceneManager;



@@ 28,12 30,19 @@ public class AttackCommandHandler : ICommandHandler<AttackCommand>
    /// Initializes a new instance of the <see cref="AttackCommandHandler"/> class.
    /// </summary>
    /// <param name="nostaleClient">The NosTale client.</param>
    /// <param name="synchronizer">The thread synchronizer.</param>
    /// <param name="unitManagerBinding">The unit manager binding.</param>
    /// <param name="sceneManager">The scene manager.</param>
    public AttackCommandHandler
        (INostaleClient nostaleClient, UnitManagerBinding unitManagerBinding, SceneManager sceneManager)
    (
        INostaleClient nostaleClient,
        NosThreadSynchronizer synchronizer,
        UnitManagerBinding unitManagerBinding,
        SceneManager sceneManager
    )
    {
        _nostaleClient = nostaleClient;
        _synchronizer = synchronizer;
        _unitManagerBinding = unitManagerBinding;
        _sceneManager = sceneManager;
    }


@@ 46,7 55,7 @@ public class AttackCommandHandler : ICommandHandler<AttackCommand>
            var entityResult = _sceneManager.FindEntity(command.TargetId.Value);
            if (entityResult.IsDefined(out var entity))
            {
                _unitManagerBinding.FocusEntity(entity);
                _synchronizer.EnqueueOperation(() => _unitManagerBinding.FocusEntity(entity));
            }
        }


M src/Core/NosSmooth.LocalClient/NostaleLocalClient.cs => src/Core/NosSmooth.LocalClient/NostaleLocalClient.cs +21 -3
@@ 12,6 12,7 @@ using NosSmooth.Core.Commands;
using NosSmooth.Core.Commands.Control;
using NosSmooth.Core.Extensions;
using NosSmooth.Core.Packets;
using NosSmooth.LocalBinding;
using NosSmooth.LocalBinding.Objects;
using NosSmooth.LocalBinding.Structs;
using NosSmooth.Packets;


@@ 31,6 32,7 @@ namespace NosSmooth.LocalClient;
/// </remarks>
public class NostaleLocalClient : BaseNostaleClient
{
    private readonly NosThreadSynchronizer _synchronizer;
    private readonly NetworkBinding _networkBinding;
    private readonly PlayerManagerBinding _playerManagerBinding;
    private readonly PetManagerBinding _petManagerBinding;


@@ 47,6 49,7 @@ public class NostaleLocalClient : BaseNostaleClient
    /// <summary>
    /// Initializes a new instance of the <see cref="NostaleLocalClient"/> class.
    /// </summary>
    /// <param name="synchronizer">The thread synchronizer.</param>
    /// <param name="networkBinding">The network binding.</param>
    /// <param name="playerManagerBinding">The player manager binding.</param>
    /// <param name="petManagerBinding">The pet manager binding.</param>


@@ 60,6 63,7 @@ public class NostaleLocalClient : BaseNostaleClient
    /// <param name="provider">The dependency injection provider.</param>
    public NostaleLocalClient
    (
        NosThreadSynchronizer synchronizer,
        NetworkBinding networkBinding,
        PlayerManagerBinding playerManagerBinding,
        PetManagerBinding petManagerBinding,


@@ 75,6 79,7 @@ public class NostaleLocalClient : BaseNostaleClient
        : base(commandProcessor, packetSerializer)
    {
        _options = options.Value;
        _synchronizer = synchronizer;
        _networkBinding = networkBinding;
        _playerManagerBinding = playerManagerBinding;
        _petManagerBinding = petManagerBinding;


@@ 91,6 96,7 @@ public class NostaleLocalClient : BaseNostaleClient
    {
        _stopRequested = stopRequested;
        _logger.LogInformation("Starting local client");
        _synchronizer.StartSynchronizer();
        _networkBinding.PacketSend += SendCallback;
        _networkBinding.PacketReceive += ReceiveCallback;



@@ 170,13 176,19 @@ public class NostaleLocalClient : BaseNostaleClient

    private void SendPacket(string packetString)
    {
        _networkBinding.SendPacket(packetString);
        _synchronizer.EnqueueOperation
        (
            () => _networkBinding.SendPacket(packetString)
        );
        _logger.LogDebug($"Sending client packet {packetString}");
    }

    private void ReceivePacket(string packetString)
    {
        _networkBinding.ReceivePacket(packetString);
        _synchronizer.EnqueueOperation
        (
            () => _networkBinding.ReceivePacket(packetString)
        );
        _logger.LogDebug($"Receiving client packet {packetString}");
    }



@@ 205,7 217,13 @@ public class NostaleLocalClient : BaseNostaleClient
            }

            Result result = await _packetHandler.HandlePacketAsync
                (this, type, packet, packetString, _stopRequested ?? default);
            (
                this,
                type,
                packet,
                packetString,
                _stopRequested ?? default
            );

            if (!result.IsSuccess)
            {

M src/Samples/HighLevel/SimplePiiBot/Commands/EntityCommands.cs => src/Samples/HighLevel/SimplePiiBot/Commands/EntityCommands.cs +25 -8
@@ 7,6 7,7 @@
using NosSmooth.ChatCommands;
using NosSmooth.Extensions.Combat.Errors;
using NosSmooth.Game;
using NosSmooth.LocalBinding;
using NosSmooth.LocalBinding.Objects;
using NosSmooth.LocalBinding.Structs;
using Remora.Commands.Attributes;


@@ 21,6 22,7 @@ namespace SimplePiiBot.Commands;
public class EntityCommands : CommandGroup
{
    private readonly Game _game;
    private readonly NosThreadSynchronizer _synchronizer;
    private readonly UnitManagerBinding _unitManagerBinding;
    private readonly SceneManager _sceneManager;
    private readonly PlayerManagerBinding _playerManagerBinding;


@@ 30,6 32,7 @@ public class EntityCommands : CommandGroup
    /// Initializes a new instance of the <see cref="EntityCommands"/> class.
    /// </summary>
    /// <param name="game">The game.</param>
    /// <param name="synchronizer">The thread synchronizer.</param>
    /// <param name="unitManagerBinding">The scene manager binding.</param>
    /// <param name="sceneManager">The scene manager.</param>
    /// <param name="playerManagerBinding">The character binding.</param>


@@ 37,6 40,7 @@ public class EntityCommands : CommandGroup
    public EntityCommands
    (
        Game game,
        NosThreadSynchronizer synchronizer,
        UnitManagerBinding unitManagerBinding,
        SceneManager sceneManager,
        PlayerManagerBinding playerManagerBinding,


@@ 44,6 48,7 @@ public class EntityCommands : CommandGroup
    )
    {
        _game = game;
        _synchronizer = synchronizer;
        _unitManagerBinding = unitManagerBinding;
        _sceneManager = sceneManager;
        _playerManagerBinding = playerManagerBinding;


@@ 100,15 105,19 @@ public class EntityCommands : CommandGroup
    /// <param name="entityId">The entity id to focus.</param>
    /// <returns>A task that may or may not have succeeded.</returns>
    [Command("focus")]
    public Task<Result> HandleFocusAsync(int entityId)
    public async Task<Result> HandleFocusAsync(int entityId)
    {
        var entityResult = _sceneManager.FindEntity(entityId);
        if (!entityResult.IsSuccess)
        {
            return Task.FromResult(Result.FromError(entityResult));
            return Result.FromError(entityResult);
        }

        return Task.FromResult(_unitManagerBinding.FocusEntity(entityResult.Entity));
        return await _synchronizer.SynchronizeAsync
        (
            () => _unitManagerBinding.FocusEntity(entityResult.Entity),
            CancellationToken
        );
    }

    /// <summary>


@@ 117,15 126,19 @@ public class EntityCommands : CommandGroup
    /// <param name="entityId">The entity id to follow.</param>
    /// <returns>A task that may or may not have succeeded.</returns>
    [Command("follow")]
    public Task<Result> HandleFollowAsync(int entityId)
    public async Task<Result> HandleFollowAsync(int entityId)
    {
        var entityResult = _sceneManager.FindEntity(entityId);
        if (!entityResult.IsSuccess)
        {
            return Task.FromResult(Result.FromError(entityResult));
            return Result.FromError(entityResult);
        }

        return Task.FromResult(_playerManagerBinding.FollowEntity(entityResult.Entity));
        return await _synchronizer.SynchronizeAsync
        (
            () => _playerManagerBinding.FollowEntity(entityResult.Entity),
            CancellationToken
        );
    }

    /// <summary>


@@ 133,8 146,12 @@ public class EntityCommands : CommandGroup
    /// </summary>
    /// <returns>A task that may or may not have succeeded.</returns>
    [Command("unfollow")]
    public Task<Result> HandleUnfollowAsync()
    public async Task<Result> HandleUnfollowAsync()
    {
        return Task.FromResult(_playerManagerBinding.UnfollowEntity());
        return await _synchronizer.SynchronizeAsync
        (
            () => _playerManagerBinding.UnfollowEntity(),
            CancellationToken
        );
    }
}
\ No newline at end of file

Do not follow this link