work on memory
This commit is contained in:
parent
2f652aa1b7
commit
6e9d89b045
28 changed files with 3590 additions and 111 deletions
|
|
@ -14,23 +14,137 @@ public sealed class TerrainOffsets
|
|||
|
||||
public string ProcessName { get; set; } = "PathOfExileSteam";
|
||||
|
||||
/// <summary>Pattern to find GameState base pointer. Empty = unknown for POE2.</summary>
|
||||
public string GameStatePattern { get; set; } = "";
|
||||
/// <summary>Pattern to find GameState global. Use ^ to mark the RIP displacement position.</summary>
|
||||
public string GameStatePattern { get; set; } = "48 83 EC ?? 48 8B F1 33 ED 48 39 2D ^";
|
||||
|
||||
// Pointer chain: GameState → InGameState → IngameData → TerrainData
|
||||
/// <summary>Fallback: manual offset from module base to GameState global (hex). Used when pattern is empty or fails.</summary>
|
||||
public int GameStateGlobalOffset { get; set; }
|
||||
|
||||
/// <summary>Bytes to add to pattern scan result to reach the actual global.</summary>
|
||||
public int PatternResultAdjust { get; set; } = 0x18;
|
||||
|
||||
// ── GameState → States ──
|
||||
// Dump: GameStateOffset { [0x08] StdVector CurrentStatePtr, [0x48] GameStateBuffer States }
|
||||
// GameStateBuffer = StdTuple2D<IntPtr> (begin/end pair). Each entry is an IntPtr (8 bytes).
|
||||
/// <summary>Offset to States begin/end pair in GameState (dump: 0x48).</summary>
|
||||
public int StatesBeginOffset { get; set; } = 0x48;
|
||||
/// <summary>Bytes per state entry (16 for inline slots, 8 for vector of pointers).</summary>
|
||||
public int StateStride { get; set; } = 0x10;
|
||||
/// <summary>Offset within each state entry to the actual state pointer.</summary>
|
||||
public int StatePointerOffset { get; set; } = 0;
|
||||
/// <summary>Which state index is InGameState (typically 4).</summary>
|
||||
public int InGameStateIndex { get; set; } = 4;
|
||||
/// <summary>If true, states are inline in the controller struct. If false, StatesBeginOffset points to a begin/end vector pair.</summary>
|
||||
public bool StatesInline { get; set; } = true;
|
||||
/// <summary>Direct offset from controller to InGameState pointer (bypasses state array). 0 = use state array instead. CE confirmed: 0x210.</summary>
|
||||
public int InGameStateDirectOffset { get; set; } = 0x210;
|
||||
|
||||
// ── InGameState → sub-structures ──
|
||||
// Dump: InGameStateOffset { [0x298] AreaInstanceData, [0x2F8] WorldData, [0x648] UiRootPtr, [0xC40] IngameUi }
|
||||
/// <summary>InGameState → AreaInstance (IngameData) pointer (dump: 0x298, CE confirmed: 0x290).</summary>
|
||||
public int IngameDataFromStateOffset { get; set; } = 0x290;
|
||||
/// <summary>InGameState → WorldData pointer (dump: 0x2F8).</summary>
|
||||
public int WorldDataFromStateOffset { get; set; } = 0x2F8;
|
||||
|
||||
// ── AreaInstance (IngameData) → sub-structures ──
|
||||
// Dump: AreaInstanceOffsets {
|
||||
// [0xAC] byte CurrentAreaLevel,
|
||||
// [0xEC] uint CurrentAreaHash,
|
||||
// [0x948] StdVector Environments,
|
||||
// [0x9F0] LocalPlayerStruct PlayerInfo, ← contains ServerDataPtr at +0x0, LocalPlayerPtr at +0x20
|
||||
// [0xAF8] EntityListStruct Entities, ← StdMap AwakeEntities + StdMap SleepingEntities
|
||||
// [0xCC0] TerrainStruct TerrainMetadata ← inline, not behind pointer
|
||||
// }
|
||||
/// <summary>AreaInstance → CurrentAreaLevel (dump: byte at 0xAC, CE confirmed: byte at 0xC4).</summary>
|
||||
public int AreaLevelOffset { get; set; } = 0xC4;
|
||||
/// <summary>If true, AreaLevel is a byte. If false, read as int.</summary>
|
||||
public bool AreaLevelIsByte { get; set; } = true;
|
||||
/// <summary>Static offset from module base to cached area level int (CE: exe+3E84B78). 0 = disabled.</summary>
|
||||
public int AreaLevelStaticOffset { get; set; } = 0;
|
||||
/// <summary>AreaInstance → CurrentAreaHash uint (dump: 0xEC).</summary>
|
||||
public int AreaHashOffset { get; set; } = 0xEC;
|
||||
/// <summary>AreaInstance → ServerData pointer (dump: 0x9F0 via LocalPlayerStruct.ServerDataPtr).</summary>
|
||||
public int ServerDataOffset { get; set; } = 0x9F0;
|
||||
/// <summary>AreaInstance → LocalPlayer entity pointer (dump: 0x9F0+0x20 = 0xA10 via LocalPlayerStruct.LocalPlayerPtr).</summary>
|
||||
public int LocalPlayerDirectOffset { get; set; } = 0xA10;
|
||||
/// <summary>AreaInstance → EntityListStruct offset (dump: 0xAF8). Contains StdMap AwakeEntities then SleepingEntities.</summary>
|
||||
public int EntityListOffset { get; set; } = 0xAF8;
|
||||
/// <summary>Offset within StdMap to _Mysize (entity count). MSVC std::map: head(8) + size(8).</summary>
|
||||
public int EntityCountInternalOffset { get; set; } = 0x08;
|
||||
|
||||
// ServerData → fields
|
||||
/// <summary>ServerData → LocalPlayer entity pointer (fallback if LocalPlayerDirectOffset is 0).</summary>
|
||||
public int LocalPlayerOffset { get; set; } = 0x20;
|
||||
|
||||
// ── Entity / Component ──
|
||||
// Dump: ItemStruct { [0x0] VTablePtr, [0x8] EntityDetailsPtr, [0x10] StdVector ComponentListPtr }
|
||||
// Dump: EntityOffsets { [0x0] ItemStruct, [0x80] uint Id, [0x84] byte IsValid }
|
||||
public int ComponentListOffset { get; set; } = 0x10;
|
||||
/// <summary>Entity → ObjectHeader pointer (for alternative component lookup via name→index map). ExileCore: 0x08.</summary>
|
||||
public int EntityHeaderOffset { get; set; } = 0x08;
|
||||
/// <summary>ObjectHeader → NativePtrArray for component name→index lookup. ExileCore: 0x40.</summary>
|
||||
public int ComponentLookupOffset { get; set; } = 0x40;
|
||||
/// <summary>Index of Life component in entity's component list. -1 = auto-discover via pattern scan.</summary>
|
||||
public int LifeComponentIndex { get; set; } = -1;
|
||||
/// <summary>Index of Render/Position component in entity's component list. -1 = unknown.</summary>
|
||||
public int RenderComponentIndex { get; set; } = -1;
|
||||
|
||||
// ── Life component (via direct chain from AreaInstance) ──
|
||||
// Deep scan confirmed: AreaInstance+0x420 → ptr+0x98 → Life component
|
||||
// VitalStruct gaps match dump: HP→Mana = 0x50, Mana→ES = 0x38
|
||||
// HP.Current@+0x188, Mana.Current@+0x1D8, ES.Current@+0x210
|
||||
/// <summary>First offset from AreaInstance to reach Life component (AreaInstance → ptr). 0 = use entity component list instead.</summary>
|
||||
public int LifeComponentOffset1 { get; set; } = 0x420;
|
||||
/// <summary>Second offset from intermediate pointer to Life component (ptr → Life).</summary>
|
||||
public int LifeComponentOffset2 { get; set; } = 0x98;
|
||||
// VitalStruct offsets within Life component (VitalStruct base, add VitalCurrentOffset/VitalTotalOffset)
|
||||
// ECS inner entity path: HP@+0x1D8 = 0x1A8+0x30, Mana@+0x228 = 0x1F8+0x30, ES@+0x260 = 0x230+0x30
|
||||
// (shifted +0x50 from old direct chain due to inner entity component header)
|
||||
public int LifeHealthOffset { get; set; } = 0x1A8;
|
||||
public int LifeManaOffset { get; set; } = 0x1F8;
|
||||
public int LifeEsOffset { get; set; } = 0x230;
|
||||
public int VitalCurrentOffset { get; set; } = 0x30;
|
||||
public int VitalTotalOffset { get; set; } = 0x2C;
|
||||
|
||||
// ── Render/Position component ──
|
||||
// Scan confirmed: position float triplet at +0x138 in component [10] (with real Z height)
|
||||
// Dump reference (older): RenderOffsets { [0xB0] CurrentWorldPosition } — shifted to 0x138 in current build
|
||||
public int PositionXOffset { get; set; } = 0x138;
|
||||
public int PositionYOffset { get; set; } = 0x13C;
|
||||
public int PositionZOffset { get; set; } = 0x140;
|
||||
|
||||
// ── Terrain (inline in AreaInstance) ──
|
||||
// Dump: TerrainStruct (at AreaInstance + 0xCC0) {
|
||||
// [0x18] StdTuple2D<long> TotalTiles,
|
||||
// [0x28] StdVector TileDetailsPtr,
|
||||
// [0xD0] StdVector GridWalkableData,
|
||||
// [0xE8] StdVector GridLandscapeData,
|
||||
// [0x100] int BytesPerRow,
|
||||
// [0x104] short TileHeightMultiplier
|
||||
// }
|
||||
/// <summary>Offset from AreaInstance to inline TerrainStruct (dump: 0xCC0).</summary>
|
||||
public int TerrainListOffset { get; set; } = 0xCC0;
|
||||
/// <summary>If true, terrain is inline in AreaInstance (no pointer dereference). If false, follow pointer.</summary>
|
||||
public bool TerrainInline { get; set; } = true;
|
||||
/// <summary>TerrainStruct → TotalTiles offset (dump: 0x18, StdTuple2D of long).</summary>
|
||||
public int TerrainDimensionsOffset { get; set; } = 0x18;
|
||||
/// <summary>TerrainStruct → GridWalkableData StdVector offset (dump: 0xD0).</summary>
|
||||
public int TerrainWalkableGridOffset { get; set; } = 0xD0;
|
||||
/// <summary>TerrainStruct → BytesPerRow (dump: 0x100).</summary>
|
||||
public int TerrainBytesPerRowOffset { get; set; } = 0x100;
|
||||
/// <summary>Kept for pointer-based terrain mode (TerrainInline=false).</summary>
|
||||
public int TerrainGridPtrOffset { get; set; } = 0x08;
|
||||
public int SubTilesPerCell { get; set; } = 23;
|
||||
|
||||
// Legacy terrain offsets (used by TerrainReader)
|
||||
public int InGameStateOffset { get; set; }
|
||||
public int IngameDataOffset { get; set; }
|
||||
public int TerrainDataOffset { get; set; }
|
||||
|
||||
// Within TerrainData struct
|
||||
public int NumColsOffset { get; set; }
|
||||
public int NumRowsOffset { get; set; }
|
||||
public int LayerMeleeOffset { get; set; }
|
||||
public int BytesPerRowOffset { get; set; }
|
||||
|
||||
/// <summary>Number of sub-tiles per terrain cell (typically 23 for POE).</summary>
|
||||
public int SubTilesPerCell { get; set; } = 23;
|
||||
|
||||
public static TerrainOffsets Load(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue