M Core/NosSmooth.Core/Commands/WalkCommand.cs => Core/NosSmooth.Core/Commands/WalkCommand.cs +1 -1
@@ 13,4 13,4 @@ namespace NosSmooth.Core.Commands;
/// <param name="TargetX">The x coordinate of the target position to move to.</param>
/// <param name="TargetY">The y coordinate of the target position to move to.</param>
/// <param name="CancelOnUserMove">Whether to cancel the walk when the user clicks to move somewhere.</param>
-public record WalkCommand(int TargetX, int TargetY, bool CancelOnUserMove = true) : ICommand;>
\ No newline at end of file
+public record WalkCommand(ushort TargetX, ushort TargetY, bool CancelOnUserMove = true) : ICommand;<
\ No newline at end of file
M Local/NosSmooth.LocalClient/CommandHandlers/Walk/WalkCommandHandler.cs => Local/NosSmooth.LocalClient/CommandHandlers/Walk/WalkCommandHandler.cs +8 -11
@@ 6,8 6,8 @@
using Microsoft.Extensions.Options;
using NosSmooth.Core.Commands;
+using NosSmooth.LocalBinding.Objects;
using NosSmooth.LocalClient.CommandHandlers.Walk.Errors;
-using NosSmoothCore;
using Remora.Results;
namespace NosSmooth.LocalClient.CommandHandlers.Walk;
@@ 17,20 17,20 @@ namespace NosSmooth.LocalClient.CommandHandlers.Walk;
/// </summary>
public class WalkCommandHandler : ICommandHandler<WalkCommand>
{
- private readonly NosClient _nosClient;
+ private readonly CharacterBinding _characterBinding;
private readonly WalkStatus _walkStatus;
private readonly WalkCommandHandlerOptions _options;
/// <summary>
/// Initializes a new instance of the <see cref="WalkCommandHandler"/> class.
/// </summary>
- /// <param name="nosClient">The local client.</param>
+ /// <param name="characterBinding">The character object binding.</param>
/// <param name="walkStatus">The walk status.</param>
/// <param name="options">The options.</param>
- public WalkCommandHandler(NosClient nosClient, WalkStatus walkStatus, IOptions<WalkCommandHandlerOptions> options)
+ public WalkCommandHandler(CharacterBinding characterBinding, WalkStatus walkStatus, IOptions<WalkCommandHandlerOptions> options)
{
_options = options.Value;
- _nosClient = nosClient;
+ _characterBinding = characterBinding;
_walkStatus = walkStatus;
}
@@ 46,11 46,8 @@ public class WalkCommandHandler : ICommandHandler<WalkCommand>
await _walkStatus.SetWalking(linked, command.TargetX, command.TargetY, command.CancelOnUserMove);
while (!ct.IsCancellationRequested)
{
- try
- {
- _nosClient.GetCharacter().Walk(command.TargetX, command.TargetY);
- }
- catch (Exception e)
+ var walkResult = _characterBinding.Walk(command.TargetX, command.TargetY);
+ if (!walkResult.IsSuccess)
{
try
{
@@ 61,7 58,7 @@ public class WalkCommandHandler : ICommandHandler<WalkCommand>
// ignored, just for cancellation
}
- return e;
+ return walkResult;
}
try
M Local/NosSmooth.LocalClient/CommandHandlers/Walk/WalkCommandHandlerOptions.cs => Local/NosSmooth.LocalClient/CommandHandlers/Walk/WalkCommandHandlerOptions.cs +0 -6
@@ 4,12 4,6 @@
// 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;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
namespace NosSmooth.LocalClient.CommandHandlers.Walk
{
/// <summary>
M Local/NosSmooth.LocalClient/CommandHandlers/Walk/WalkStatus.cs => Local/NosSmooth.LocalClient/CommandHandlers/Walk/WalkStatus.cs +7 -7
@@ 4,7 4,7 @@
// 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 NosSmooth.LocalClient.Hooks;
+using NosSmooth.LocalBinding.Objects;
namespace NosSmooth.LocalClient.CommandHandlers.Walk;
@@ 13,7 13,7 @@ namespace NosSmooth.LocalClient.CommandHandlers.Walk;
/// </summary>
public class WalkStatus
{
- private readonly NostaleHookManager _hookManager;
+ private readonly CharacterBinding _characterBinding;
private readonly SemaphoreSlim _semaphore;
private CancellationTokenSource? _walkingCancellation;
private bool _userCanCancel;
@@ 22,10 22,10 @@ public class WalkStatus
/// <summary>
/// Initializes a new instance of the <see cref="WalkStatus"/> class.
/// </summary>
- /// <param name="hookManager">The hooking manager.</param>
- public WalkStatus(NostaleHookManager hookManager)
+ /// <param name="characterBinding">The character binding.</param>
+ public WalkStatus(CharacterBinding characterBinding)
{
- _hookManager = hookManager;
+ _characterBinding = characterBinding;
_semaphore = new SemaphoreSlim(1, 1);
}
@@ 110,7 110,7 @@ public class WalkStatus
if (!_walkHooked)
{
- _hookManager.ClientWalked += OnCharacterWalked;
+ _characterBinding.WalkCall += OnCharacterWalked;
_walkHooked = true;
}
@@ 159,7 159,7 @@ public class WalkStatus
await CancelWalkingAsync(ct: ct);
}
- private bool OnCharacterWalked(WalkEventArgs walkEventArgs)
+ private bool OnCharacterWalked(ushort x, ushort y)
{
if (IsWalking)
{
M Local/NosSmooth.LocalClient/Extensions/ServiceCollectionExtensions.cs => Local/NosSmooth.LocalClient/Extensions/ServiceCollectionExtensions.cs +2 -5
@@ 8,10 8,8 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using NosSmooth.Core.Client;
using NosSmooth.Core.Extensions;
-using NosSmooth.LocalClient.CommandHandlers;
+using NosSmooth.LocalBinding.Extensions;
using NosSmooth.LocalClient.CommandHandlers.Walk;
-using NosSmooth.LocalClient.Hooks;
-using NosSmoothCore;
namespace NosSmooth.LocalClient.Extensions;
@@ 28,13 26,12 @@ public static class ServiceCollectionExtensions
public static IServiceCollection AddLocalClient(this IServiceCollection serviceCollection)
{
serviceCollection.AddNostaleCore();
+ serviceCollection.AddNostaleBindings();
serviceCollection
.AddCommandHandler<WalkCommandHandler>()
.AddPacketResponder<WalkPacketResponder>()
.AddSingleton<WalkStatus>();
serviceCollection.TryAddSingleton<NostaleLocalClient>();
- serviceCollection.TryAddSingleton<NostaleHookManager>();
- serviceCollection.TryAddSingleton<NosClient>();
serviceCollection.TryAddSingleton<INostaleClient>(p => p.GetRequiredService<NostaleLocalClient>());
return serviceCollection;
D Local/NosSmooth.LocalClient/Hooks/NostaleHookManager.cs => Local/NosSmooth.LocalClient/Hooks/NostaleHookManager.cs +0 -74
@@ 1,74 0,0 @@
-//
-// NostaleHookManager.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.ComponentModel;
-using NosSmoothCore;
-using Remora.Results;
-
-namespace NosSmooth.LocalClient.Hooks;
-
-/// <summary>
-/// The manager for hooking functions.
-/// </summary>
-public class NostaleHookManager
-{
- private readonly NosClient _nosClient;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="NostaleHookManager"/> class.
- /// </summary>
- /// <param name="nosClient">The nostale client.</param>
- public NostaleHookManager(NosClient nosClient)
- {
- _nosClient = nosClient;
- }
-
- /// <summary>
- /// Event for the character walk function.
- /// </summary>
- public event Func<WalkEventArgs, bool>? ClientWalked;
-
- /// <summary>
- /// Hook the Character.Walk function.
- /// </summary>
- /// <returns>A result that may or may not have succeeded.</returns>
- public Result HookCharacterWalk()
- {
- try
- {
- _nosClient.GetCharacter().SetWalkCallback(Walk);
- }
- catch (Exception e)
- {
- return e;
- }
-
- return Result.FromSuccess();
- }
-
- /// <summary>
- /// Reset the registered hooks.
- /// </summary>
- /// <returns>A result that may or may not have succeeded.</returns>
- public Result ResetHooks()
- {
- try
- {
- _nosClient.ResetHooks();
- }
- catch (Exception e)
- {
- return e;
- }
-
- return Result.FromSuccess();
- }
-
- private bool Walk(int position)
- {
- return ClientWalked?.Invoke(new WalkEventArgs(position & 0xFFFF, (int)((position & 0xFFFF0000) >> 16))) ?? true;
- }
-}>
\ No newline at end of file
D Local/NosSmooth.LocalClient/Hooks/WalkEventArgs.cs => Local/NosSmooth.LocalClient/Hooks/WalkEventArgs.cs +0 -34
@@ 1,34 0,0 @@
-//
-// WalkEventArgs.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.
-
-namespace NosSmooth.LocalClient.Hooks;
-
-/// <summary>
-/// The event args for event in <see cref="NostaleHookManager"/>.
-/// </summary>
-public class WalkEventArgs
-{
- /// <summary>
- /// Initializes a new instance of the <see cref="WalkEventArgs"/> class.
- /// </summary>
- /// <param name="targetX">The target x coordinate.</param>
- /// <param name="targetY">The target y coordinate.</param>
- public WalkEventArgs(int targetX, int targetY)
- {
- TargetX = targetX;
- TargetY = targetY;
- }
-
- /// <summary>
- /// Gets the target x coordinate.
- /// </summary>
- public int TargetX { get; }
-
- /// <summary>
- /// Gets the target y coordinate.
- /// </summary>
- public int TargetY { get; }
-}>
\ No newline at end of file
M Local/NosSmooth.LocalClient/LocalClientOptions.cs => Local/NosSmooth.LocalClient/LocalClientOptions.cs +0 -26
@@ 4,8 4,6 @@
// 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 NosSmooth.Core.Commands;
-
namespace NosSmooth.LocalClient;
/// <summary>
@@ 17,28 15,4 @@ public class LocalClientOptions
/// Gets or sets whether the interception of packets should be allowed.
/// </summary>
public bool AllowIntercept { get; set; }
-
- /// <summary>
- /// Hook the packet sent method.
- /// </summary>
- /// <remarks>
- /// Packet handlers and interceptors won't be called for sent packets.
- /// </remarks>
- public bool HookPacketSend { get; set; } = true;
-
- /// <summary>
- /// Hook the packet received method.
- /// </summary>
- /// <remarks>
- /// Packet handlers and interceptors won't be called for received packets.
- /// </remarks>
- public bool HookPacketReceive { get; set; } = true;
-
- /// <summary>
- /// Whether to hook Character.Walk method. True by default.
- /// </summary>
- /// <remarks>
- /// If set to false, <see cref="WalkCommand.CancelOnUserMove"/> won't take any effect.
- /// </remarks>
- public bool HookCharacterWalk { get; set; } = true;
}=
\ No newline at end of file
M Local/NosSmooth.LocalClient/NosSmooth.LocalClient.csproj => Local/NosSmooth.LocalClient/NosSmooth.LocalClient.csproj +8 -1
@@ 5,15 5,22 @@
<Nullable>enable</Nullable>
<LangVersion>10</LangVersion>
<TargetFramework>net48</TargetFramework>
+ <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\Core\NosSmooth.Core\NosSmooth.Core.csproj" />
- <ProjectReference Include="..\NosSmooth.LocalCore\NosSmooth.LocalCore.vcxproj" />
+ <ProjectReference Include="..\NosSmooth.LocalBinding\NosSmooth.LocalBinding.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
+ <PackageReference Include="Reloaded.Hooks" Version="3.5.0" />
+ <PackageReference Include="Reloaded.Memory.Sigscan" Version="1.2.1" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Folder Include="Bindings" />
</ItemGroup>
</Project>
M Local/NosSmooth.LocalClient/NostaleLocalClient.cs => Local/NosSmooth.LocalClient/NostaleLocalClient.cs +12 -33
@@ 11,11 11,10 @@ using NosSmooth.Core.Client;
using NosSmooth.Core.Commands;
using NosSmooth.Core.Extensions;
using NosSmooth.Core.Packets;
-using NosSmooth.LocalClient.Hooks;
+using NosSmooth.LocalBinding.Objects;
using NosSmooth.Packets;
using NosSmooth.Packets.Attributes;
using NosSmooth.Packets.Errors;
-using NosSmoothCore;
using Remora.Results;
namespace NosSmooth.LocalClient;
@@ 29,12 28,11 @@ namespace NosSmooth.LocalClient;
/// </remarks>
public class NostaleLocalClient : BaseNostaleClient
{
+ private readonly NetworkBinding _networkBinding;
private readonly IPacketSerializer _packetSerializer;
- private readonly NostaleHookManager _hookManager;
private readonly IPacketHandler _packetHandler;
private readonly ILogger _logger;
private readonly IServiceProvider _provider;
- private readonly NosClient _client;
private readonly LocalClientOptions _options;
private CancellationToken? _stopRequested;
private IPacketInterceptor? _interceptor;
@@ 42,34 40,31 @@ public class NostaleLocalClient : BaseNostaleClient
/// <summary>
/// Initializes a new instance of the <see cref="NostaleLocalClient"/> class.
/// </summary>
+ /// <param name="networkBinding">The network binding.</param>
/// <param name="commandProcessor">The command processor.</param>
/// <param name="packetSerializer">The packet serializer.</param>
- /// <param name="hookManager">The hooking manager.</param>
/// <param name="packetHandler">The packet handler.</param>
/// <param name="logger">The logger.</param>
/// <param name="options">The options for the client.</param>
/// <param name="provider">The dependency injection provider.</param>
- /// <param name="client">The nostale managed client.</param>
public NostaleLocalClient
(
+ NetworkBinding networkBinding,
CommandProcessor commandProcessor,
IPacketSerializer packetSerializer,
- NostaleHookManager hookManager,
IPacketHandler packetHandler,
ILogger<NostaleLocalClient> logger,
IOptions<LocalClientOptions> options,
- IServiceProvider provider,
- NosClient client
+ IServiceProvider provider
)
: base(commandProcessor, packetSerializer)
{
_options = options.Value;
+ _networkBinding = networkBinding;
_packetSerializer = packetSerializer;
- _hookManager = hookManager;
_packetHandler = packetHandler;
_logger = logger;
_provider = provider;
- _client = client;
}
/// <inheritdoc />
@@ 77,25 72,8 @@ public class NostaleLocalClient : BaseNostaleClient
{
_stopRequested = stopRequested;
_logger.LogInformation("Starting local client");
- NetworkCallback receiveCallback = ReceiveCallback;
- NetworkCallback sendCallback = SendCallback;
-
- if (_options.HookPacketReceive)
- {
- _client.GetNetwork().SetReceiveCallback(receiveCallback);
- }
-
- if (_options.HookPacketSend)
- {
- _client.GetNetwork().SetSendCallback(sendCallback);
- }
-
- if (_options.HookCharacterWalk)
- {
- _hookManager.HookCharacterWalk();
- }
-
- _logger.LogInformation("Packet methods hooked successfully");
+ _networkBinding.PacketSend += SendCallback;
+ _networkBinding.PacketReceive += ReceiveCallback;
try
{
@@ 106,7 84,8 @@ public class NostaleLocalClient : BaseNostaleClient
// ignored
}
- _client.ResetHooks();
+ _networkBinding.PacketSend -= SendCallback;
+ _networkBinding.PacketReceive -= ReceiveCallback;
return Result.FromSuccess();
}
@@ 163,13 142,13 @@ public class NostaleLocalClient : BaseNostaleClient
private void SendPacket(string packetString)
{
- _client.GetNetwork().SendPacket(packetString);
+ _networkBinding.SendPacket(packetString);
_logger.LogDebug($"Sending client packet {packetString}");
}
private void ReceivePacket(string packetString)
{
- _client.GetNetwork().ReceivePacket(packetString);
+ _networkBinding.ReceivePacket(packetString);
_logger.LogDebug($"Receiving client packet {packetString}");
}
M Samples/WalkCommands/Commands/WalkCommands.cs => Samples/WalkCommands/Commands/WalkCommands.cs +2 -2
@@ 39,8 39,8 @@ public class WalkCommands
/// <returns>A result that may or may not have succeeded.</returns>
public async Task<Result> HandleWalkToAsync
(
- int x,
- int y,
+ ushort x,
+ ushort y,
bool isCancellable = true,
CancellationToken ct = default
)