~ruther/NosSmooth.Local

ref: 8a6eeb874448013c576ac7dea8477b66740bd64e NosSmooth.Local/src/Core/NosSmooth.LocalBinding/Structs/SceneManager.cs -rw-r--r-- 4.9 KiB
8a6eeb87 — Rutherther chore: bump versions 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//
//  SceneManager.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>
/// Represents nostale scene manager struct.
/// </summary>
public class SceneManager
{
    /// <summary>
    /// Create <see cref="PlayerManager"/> 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<SceneManager> Create(NosBrowserManager nosBrowserManager, SceneManagerOptions options)
    {
        var characterObjectAddress = nosBrowserManager.Scanner.FindPattern(options.SceneManagerObjectPattern);
        if (!characterObjectAddress.Found)
        {
            return new BindingNotFoundError(options.SceneManagerObjectPattern, "SceneManager");
        }

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

        int staticManagerAddress = (int)nosBrowserManager.Process.MainModule.BaseAddress + characterObjectAddress.Offset;
        return new SceneManager(nosBrowserManager.Memory, staticManagerAddress, options.SceneManagerOffsets);
    }

    private readonly int[] _sceneManagerOffsets;
    private readonly IMemory _memory;
    private readonly int _staticSceneManagerAddress;

    /// <summary>
    /// Initializes a new instance of the <see cref="SceneManager"/> class.
    /// </summary>
    /// <param name="memory">The memory.</param>
    /// <param name="staticSceneManagerAddress">The pointer to the scene manager.</param>
    /// <param name="sceneManagerOffsets">The offsets from the static scene manager address.</param>
    public SceneManager(IMemory memory, int staticSceneManagerAddress, int[] sceneManagerOffsets)
    {
        _memory = memory;
        _staticSceneManagerAddress = staticSceneManagerAddress;
        _sceneManagerOffsets = sceneManagerOffsets;
    }

    /// <summary>
    /// Gets the address of the scene manager.
    /// </summary>
    public nuint Address => _memory.FollowStaticAddressOffsets(_staticSceneManagerAddress, _sceneManagerOffsets);

    /// <summary>
    /// Gets the player list.
    /// </summary>
    public NostaleList<MapBaseObj> PlayerList => new MapBaseList(_memory, ReadPtr(Address + 0xC));

    /// <summary>
    /// Gets the monster list.
    /// </summary>
    public NostaleList<MapBaseObj> MonsterList => new MapBaseList(_memory, ReadPtr(Address + 0x10));

    /// <summary>
    /// Gets the npc list.
    /// </summary>
    public NostaleList<MapBaseObj> NpcList => new MapBaseList(_memory, ReadPtr(Address + 0x14));

    /// <summary>
    /// Gets the item list.
    /// </summary>
    public NostaleList<MapBaseObj> ItemList => new MapBaseList(_memory, ReadPtr(Address + 0x18));

    /// <summary>
    /// Gets the entity that is currently being followed by the player.
    /// </summary>
    public MapBaseObj? FollowEntity
    {
        get
        {
            var ptr = ReadPtr(Address + 0x48);
            if (ptr == nuint.Zero)
            {
                return null;
            }

            return new MapBaseObj(_memory, ptr);
        }
    }

    /// <summary>
    /// Gets the lock on target marked address.
    /// </summary>
    public nuint LockOnTargetMarkedAddress
    {
        get
        {
            var ptr = ReadPtr(Address + 0x1C);
            ptr = ReadPtr(ptr + 0x04);
            ptr = ReadPtr(ptr + 0x00);
            return ptr;
        }
    }

    private nuint ReadPtr(nuint ptr)
    {
        _memory.Read(ptr, out int read);
        return (nuint)read;
    }

    /// <summary>
    /// Find the given entity address.
    /// </summary>
    /// <param name="id">The id of the entity.</param>
    /// <returns>The pointer to the entity or an error.</returns>
    public Result<MapBaseObj?> FindEntity(long id)
    {
        if (id == 0)
        {
            return Result<MapBaseObj?>.FromSuccess(null);
        }

        var item = ItemList.FirstOrDefault(x => x.Id == id);
        if (item is not null)
        {
            return item;
        }

        var monster = MonsterList.FirstOrDefault(x => x.Id == id);
        if (monster is not null)
        {
            return monster;
        }

        var npc = NpcList.FirstOrDefault(x => x.Id == id);
        if (npc is not null)
        {
            return npc;
        }

        var player = PlayerList.FirstOrDefault(x => x.Id == id);
        if (player is not null)
        {
            return player;
        }

        return new NotFoundError($"Could not find entity with id {id}");
    }
}
Do not follow this link