cleanup
This commit is contained in:
parent
8a0e4bb481
commit
0df70abad7
24 changed files with 0 additions and 1225 deletions
132
src/Roboto.Memory/Snapshots/Entity.cs
Normal file
132
src/Roboto.Memory/Snapshots/Entity.cs
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
namespace Roboto.Memory;
|
||||
|
||||
public enum EntityType
|
||||
{
|
||||
Unknown,
|
||||
Player,
|
||||
Monster,
|
||||
Npc,
|
||||
Effect,
|
||||
WorldItem,
|
||||
MiscellaneousObject,
|
||||
Terrain,
|
||||
Critter,
|
||||
Chest,
|
||||
Shrine,
|
||||
Portal,
|
||||
TownPortal,
|
||||
Waypoint,
|
||||
AreaTransition,
|
||||
Door,
|
||||
Doodad,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raw entity data read from process memory. No business logic or classification —
|
||||
/// type classification lives in EntityReader (Memory-internal) and EntityClassifier (Data layer).
|
||||
/// </summary>
|
||||
public class Entity
|
||||
{
|
||||
public nint Address { get; }
|
||||
public uint Id { get; }
|
||||
public string? Path { get; }
|
||||
public string? Metadata { get; }
|
||||
|
||||
// Position (from Render component)
|
||||
public bool HasPosition { get; internal set; }
|
||||
public float X { get; internal set; }
|
||||
public float Y { get; internal set; }
|
||||
public float Z { get; internal set; }
|
||||
|
||||
// Vitals (from Life component — only populated when explicitly read)
|
||||
public bool HasVitals { get; internal set; }
|
||||
public int LifeCurrent { get; internal set; }
|
||||
public int LifeTotal { get; internal set; }
|
||||
public int ManaCurrent { get; internal set; }
|
||||
public int ManaTotal { get; internal set; }
|
||||
public int EsCurrent { get; internal set; }
|
||||
public int EsTotal { get; internal set; }
|
||||
|
||||
// Component info
|
||||
public int ComponentCount { get; internal set; }
|
||||
public HashSet<string>? Components { get; internal set; }
|
||||
|
||||
// Component-based properties (populated by GameMemoryReader)
|
||||
public bool IsTargetable { get; internal set; }
|
||||
public bool IsOpened { get; internal set; }
|
||||
public bool IsAvailable { get; internal set; }
|
||||
public int Rarity { get; internal set; }
|
||||
|
||||
// Mods (from Mods component)
|
||||
public List<string>? ModNames { get; internal set; }
|
||||
|
||||
// AreaTransition destination (raw area ID, e.g. "G1_4")
|
||||
public string? TransitionName { get; internal set; }
|
||||
public int TransitionState { get; internal set; } = -1;
|
||||
|
||||
// Action state (from Actor component)
|
||||
public short ActionId { get; internal set; }
|
||||
public bool IsAttacking { get; internal set; }
|
||||
public bool IsMoving { get; internal set; }
|
||||
|
||||
// Classification (set by EntityReader)
|
||||
public EntityType Type { get; internal set; }
|
||||
|
||||
// Derived properties
|
||||
public bool IsAlive => HasVitals && LifeCurrent > 0;
|
||||
public bool IsDead => HasVitals && LifeCurrent <= 0;
|
||||
public bool HasComponent(string name) => Components?.Contains(name) == true;
|
||||
|
||||
/// <summary>
|
||||
/// Grid-plane distance to another point (ignores Z).
|
||||
/// </summary>
|
||||
public float DistanceTo(float px, float py)
|
||||
{
|
||||
var dx = X - px;
|
||||
var dy = Y - py;
|
||||
return MathF.Sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Grid-plane distance to another entity.
|
||||
/// </summary>
|
||||
public float DistanceTo(Entity other) => DistanceTo(other.X, other.Y);
|
||||
|
||||
/// <summary>
|
||||
/// Short category string derived from path (e.g. "Monsters", "Effects", "NPC").
|
||||
/// </summary>
|
||||
public string PathCategory
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Path is null) return "?";
|
||||
var parts = Path.Split('/');
|
||||
return parts.Length >= 2 ? parts[1] : "?";
|
||||
}
|
||||
}
|
||||
|
||||
internal Entity(nint address, uint id, string? path)
|
||||
{
|
||||
Address = address;
|
||||
Id = id;
|
||||
Path = path;
|
||||
Metadata = ExtractMetadata(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strips the "@N" instance suffix from the path.
|
||||
/// "Metadata/Monsters/Wolves/RottenWolf1_@2" → "Metadata/Monsters/Wolves/RottenWolf1_"
|
||||
/// </summary>
|
||||
private static string? ExtractMetadata(string? path)
|
||||
{
|
||||
if (path is null) return null;
|
||||
var atIndex = path.LastIndexOf('@');
|
||||
return atIndex > 0 ? path[..atIndex] : path;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var pos = HasPosition ? $"({X:F0},{Y:F0})" : "no pos";
|
||||
return $"[{Id}] {Type} {Path ?? "?"} {pos}";
|
||||
}
|
||||
}
|
||||
80
src/Roboto.Memory/Snapshots/GameStateSnapshot.cs
Normal file
80
src/Roboto.Memory/Snapshots/GameStateSnapshot.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using System.Numerics;
|
||||
using Roboto.Memory.States;
|
||||
|
||||
namespace Roboto.Memory;
|
||||
|
||||
public class GameStateSnapshot
|
||||
{
|
||||
// Process
|
||||
public bool Attached;
|
||||
public int ProcessId;
|
||||
public nint ModuleBase;
|
||||
public int ModuleSize;
|
||||
public string? Error;
|
||||
|
||||
// GameState
|
||||
public nint GameStateBase;
|
||||
public bool OffsetsConfigured;
|
||||
public int StatesCount;
|
||||
public GameStateType CurrentGameState = GameStateType.GameNotLoaded;
|
||||
|
||||
// Pointers
|
||||
public nint ControllerPtr;
|
||||
public nint InGameStatePtr;
|
||||
public nint AreaInstancePtr;
|
||||
public nint ServerDataPtr;
|
||||
public nint LocalPlayerPtr;
|
||||
|
||||
// Area
|
||||
public int AreaLevel;
|
||||
public uint AreaHash;
|
||||
|
||||
// Player
|
||||
public string? CharacterName;
|
||||
|
||||
// Player position (Render component)
|
||||
public bool HasPosition;
|
||||
public float PlayerX, PlayerY, PlayerZ;
|
||||
|
||||
// Player vitals (Life component)
|
||||
public bool HasVitals;
|
||||
public int LifeCurrent, LifeTotal;
|
||||
public int ManaCurrent, ManaTotal;
|
||||
public int EsCurrent, EsTotal;
|
||||
|
||||
// Entities
|
||||
public int EntityCount;
|
||||
public List<Entity>? Entities;
|
||||
|
||||
// Loading state
|
||||
public bool IsLoading;
|
||||
public bool IsEscapeOpen;
|
||||
|
||||
// Live state flags — individual bytes from InGameState+0x200 region
|
||||
public byte[]? StateFlagBytes; // raw bytes from InGameState+0x200, length 0x30
|
||||
public int StateFlagBaseOffset = 0x200;
|
||||
|
||||
// Active game states (ExileCore state machine)
|
||||
public nint[] StateSlots = Array.Empty<nint>(); // State[0]..State[N] pointer values (all 12 slots)
|
||||
public int[]? StateSlotValues; // int32 at state+0x08 for each slot
|
||||
public HashSet<nint> ActiveStates = new(); // which state pointers are in the active list
|
||||
public nint ActiveStatesBegin, ActiveStatesEnd; // debug: raw vector pointers
|
||||
public nint[] ActiveStatesRaw = Array.Empty<nint>(); // debug: all pointers in the vector
|
||||
public (int Offset, nint Value)[] WatchOffsets = []; // candidate controller offsets
|
||||
public (int Offset, nint Value, string? Match, bool Changed, string? DerefInfo)[] ControllerPreSlots = []; // qwords before state array
|
||||
|
||||
// Player skills (from Actor component)
|
||||
public List<SkillSnapshot>? PlayerSkills;
|
||||
|
||||
// Quest flags (from ServerData → PlayerServerData)
|
||||
public List<QuestSnapshot>? QuestFlags;
|
||||
|
||||
// Camera
|
||||
public Matrix4x4? CameraMatrix;
|
||||
|
||||
// Terrain
|
||||
public int TerrainWidth, TerrainHeight;
|
||||
public int TerrainCols, TerrainRows;
|
||||
public WalkabilityGrid? Terrain;
|
||||
public int TerrainWalkablePercent;
|
||||
}
|
||||
22
src/Roboto.Memory/Snapshots/WalkabilityGrid.cs
Normal file
22
src/Roboto.Memory/Snapshots/WalkabilityGrid.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
namespace Roboto.Memory;
|
||||
|
||||
public sealed class WalkabilityGrid
|
||||
{
|
||||
public int Width { get; }
|
||||
public int Height { get; }
|
||||
public byte[] Data { get; }
|
||||
|
||||
public WalkabilityGrid(int width, int height, byte[] data)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
public bool IsWalkable(int x, int y)
|
||||
{
|
||||
if (x < 0 || x >= Width || y < 0 || y >= Height)
|
||||
return false;
|
||||
return Data[y * Width + x] != 0;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue