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