~ruther/NosSmooth.Local

e51bc00dd2fa058cccb36ca13957feb3edf8d99b — Rutherther 2 years ago 8a6eeb8
feat(binding): add nt client with encryption key (session id)
M src/Core/NosSmooth.LocalBinding/Extensions/ServiceCollectionExtensions.cs => src/Core/NosSmooth.LocalBinding/Extensions/ServiceCollectionExtensions.cs +1 -0
@@ 53,6 53,7 @@ public static class ServiceCollectionExtensions
            .AddSingleton(p => p.GetRequiredService<NosBrowserManager>().PlayerManager)
            .AddSingleton(p => p.GetRequiredService<NosBrowserManager>().NetworkManager)
            .AddSingleton(p => p.GetRequiredService<NosBrowserManager>().UnitManager)
            .AddSingleton(p => p.GetRequiredService<NosBrowserManager>().NtClient)
            .AddSingleton(p => p.GetRequiredService<IHookManager>().PacketReceive)
            .AddSingleton(p => p.GetRequiredService<IHookManager>().PacketSend)
            .AddSingleton(p => p.GetRequiredService<IHookManager>().PlayerWalk)

M src/Core/NosSmooth.LocalBinding/Hooks/Implementations/HookManager.cs => src/Core/NosSmooth.LocalBinding/Hooks/Implementations/HookManager.cs +1 -1
@@ 21,7 21,7 @@ internal class HookManager : IHookManager
    /// Initializes a new instance of the <see cref="HookManager"/> class.
    /// </summary>
    /// <param name="options">The hook manager options.</param>
    public HookManager(IOptions<HookManagerOptions> options)
    public HookManager(IOptionsSnapshot<HookManagerOptions> options)
    {
        _options = options.Value;
        _hooks = new Dictionary<string, INostaleHook>();

M src/Core/NosSmooth.LocalBinding/NosBrowserManager.cs => src/Core/NosSmooth.LocalBinding/NosBrowserManager.cs +53 -7
@@ 58,11 58,13 @@ public class NosBrowserManager
    private readonly PetManagerOptions _petManagerOptions;
    private readonly NetworkManagerOptions _networkManagerOptions;
    private readonly UnitManagerOptions _unitManagerOptions;
    private readonly NtClientOptions _ntClientOptions;
    private PlayerManager? _playerManager;
    private SceneManager? _sceneManager;
    private PetManagerList? _petManagerList;
    private NetworkManager? _networkManager;
    private UnitManager? _unitManager;
    private NtClient? _ntClient;

    /// <summary>
    /// Initializes a new instance of the <see cref="NosBrowserManager"/> class.


@@ 72,13 74,15 @@ public class NosBrowserManager
    /// <param name="petManagerOptions">The pet manager options.</param>
    /// <param name="networkManagerOptions">The network manager options.</param>
    /// <param name="unitManagerOptions">The unit manager options.</param>
    /// <param name="ntClientOptions">The nt client options.</param>
    public NosBrowserManager
    (
        IOptions<PlayerManagerOptions> playerManagerOptions,
        IOptions<SceneManagerOptions> sceneManagerOptions,
        IOptions<PetManagerOptions> petManagerOptions,
        IOptions<NetworkManagerOptions> networkManagerOptions,
        IOptions<UnitManagerOptions> unitManagerOptions
        IOptionsSnapshot<PlayerManagerOptions> playerManagerOptions,
        IOptionsSnapshot<SceneManagerOptions> sceneManagerOptions,
        IOptionsSnapshot<PetManagerOptions> petManagerOptions,
        IOptionsSnapshot<NetworkManagerOptions> networkManagerOptions,
        IOptionsSnapshot<UnitManagerOptions> unitManagerOptions,
        IOptionsSnapshot<NtClientOptions> ntClientOptions
    )
        : this
        (


@@ 87,7 91,8 @@ public class NosBrowserManager
            sceneManagerOptions.Value,
            petManagerOptions.Value,
            networkManagerOptions.Value,
            unitManagerOptions.Value
            unitManagerOptions.Value,
            ntClientOptions.Value
        )
    {
    }


@@ 101,6 106,7 @@ public class NosBrowserManager
    /// <param name="petManagerOptions">The pet manager options.</param>
    /// <param name="networkManagerOptions">The network manager options.</param>
    /// <param name="unitManagerOptions">The unit manager options.</param>
    /// <param name="ntClientOptions">The nt client options.</param>
    public NosBrowserManager
    (
        Process process,


@@ 108,7 114,8 @@ public class NosBrowserManager
        SceneManagerOptions sceneManagerOptions,
        PetManagerOptions petManagerOptions,
        NetworkManagerOptions networkManagerOptions,
        UnitManagerOptions unitManagerOptions
        UnitManagerOptions unitManagerOptions,
        NtClientOptions ntClientOptions
    )
    {
        _playerManagerOptions = playerManagerOptions;


@@ 116,6 123,7 @@ public class NosBrowserManager
        _petManagerOptions = petManagerOptions;
        _networkManagerOptions = networkManagerOptions;
        _unitManagerOptions = unitManagerOptions;
        _ntClientOptions = ntClientOptions;
        Process = process;
        Memory = Process.Id == Process.GetCurrentProcess().Id ? new Memory() : new ExternalMemory(process);
        Scanner = new Scanner(process, process.MainModule);


@@ 197,6 205,26 @@ public class NosBrowserManager
    }

    /// <summary>
    /// Gets the nt client.
    /// </summary>
    /// <exception cref="InvalidOperationException">Thrown if the browser is not initialized or there was an error with initialization of nt client.</exception>
    public NtClient NtClient
    {
        get
        {
            if (_ntClient is null)
            {
                throw new InvalidOperationException
                (
                    "Could not get nt client. The browser manager is not initialized. Did you forget to call NosBrowserManager.Initialize?"
                );
            }

            return _ntClient;
        }
    }

    /// <summary>
    /// Gets the player manager.
    /// </summary>
    /// <exception cref="InvalidOperationException">Thrown if the browser is not initialized or there was an error with initialization of player manager.</exception>


@@ 361,6 389,24 @@ public class NosBrowserManager
            _petManagerList = petManagerResult.Entity;
        }

        if (_ntClient is null)
        {
            var ntClientResult = NtClient.Create(this, _ntClientOptions);
            if (!ntClientResult.IsSuccess)
            {
                errorResults.Add
                (
                    Result.FromError
                    (
                        new CouldNotInitializeModuleError(typeof(NtClient), ntClientResult.Error),
                        ntClientResult
                    )
                );
            }

            _ntClient = ntClientResult.Entity;
        }

        return errorResults.Count switch
        {
            0 => Result.FromSuccess(),

A src/Core/NosSmooth.LocalBinding/Options/NtClientOptions.cs => src/Core/NosSmooth.LocalBinding/Options/NtClientOptions.cs +27 -0
@@ 0,0 1,27 @@
//
//  NtClientOptions.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 NosSmooth.LocalBinding.Structs;

namespace NosSmooth.LocalBinding.Options;

/// <summary>
/// Options for <see cref="NtClient"/>.
/// </summary>
public class NtClientOptions
{
    /// <summary>
    /// Gets or sets the pattern to find static pet manager list address at.
    /// </summary>
    public string NtClientPattern { get; set; }
        = "FF ?? ?? ?? ?? 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF 00 00";

    /// <summary>
    /// Gets or sets the offsets to find the scene manager at from the static address.
    /// </summary>
    public int[] NtClientOffsets { get; set; }
        = { 1 };
}
\ No newline at end of file

A src/Core/NosSmooth.LocalBinding/Structs/NtClient.cs => src/Core/NosSmooth.LocalBinding/Structs/NtClient.cs +72 -0
@@ 0,0 1,72 @@
//
//  NtClient.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 NosSmooth.LocalBinding.Errors;
using NosSmooth.LocalBinding.Extensions;
using NosSmooth.LocalBinding.Options;
using Reloaded.Memory.Sources;
using Remora.Results;

namespace NosSmooth.LocalBinding.Structs;

/// <summary>
/// A NosTale client base object.
/// </summary>
public class NtClient : NostaleObject
{
    /// <summary>
    /// Create <see cref="NtClient"/> instance.
    /// </summary>
    /// <param name="nosBrowserManager">The NosTale process browser.</param>
    /// <param name="options">The options.</param>
    /// <returns>The player manager or an error.</returns>
    public static Result<NtClient> Create(NosBrowserManager nosBrowserManager, NtClientOptions options)
    {
        var networkObjectAddress = nosBrowserManager.Scanner.FindPattern(options.NtClientPattern);
        if (!networkObjectAddress.Found)
        {
            return new BindingNotFoundError(options.NtClientPattern, "NtClient");
        }

        if (nosBrowserManager.Process.MainModule is null)
        {
            return new NotFoundError("Cannot find the main module of the target process.");
        }

        var staticAddress = (nuint)(nosBrowserManager.Process.MainModule.BaseAddress + networkObjectAddress.Offset);
        return new NtClient(nosBrowserManager.Memory, staticAddress, options.NtClientOffsets);
    }

    private readonly IMemory _memory;
    private readonly int _staticNtClientAddress;
    private readonly int[] _ntClientOffsets;

    private NtClient(IMemory memory, nuint staticNtClientAddress, int[] ntClientOffsets)
        : base(memory, nuint.Zero)
    {
        _memory = memory;
        _staticNtClientAddress = (int)staticNtClientAddress;
        _ntClientOffsets = ntClientOffsets;
    }

    /// <summary>
    /// Gets the address to the player manager.
    /// </summary>
    public override nuint Address => _memory.FollowStaticAddressOffsets
        (_staticNtClientAddress, _ntClientOffsets);

    /// <summary>
    /// Gets the encryption key used for world encryption.
    /// </summary>
    public int EncryptionKey
    {
        get
        {
            _memory.SafeRead(Address + 0x48, out int encryptionKey);
            return encryptionKey;
        }
    }
}
\ No newline at end of file

Do not follow this link