Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
VideoGameRoulette committed Jul 24, 2021
1 parent 543f78a commit 49493cf
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 43 deletions.
25 changes: 24 additions & 1 deletion SRTPluginProviderRER1/GameMemoryRER1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,41 @@ public class GameMemoryRER1 : IGameMemoryRER1
public GamePlayer Player { get => _player; set => _player = value; }
internal GamePlayer _player;

public GameInventory PlayerInventory { get => _playerInventory; set => _playerInventory = value; }
internal GameInventory _playerInventory;

public GameEnemy[] EnemyHealth { get => _enemyHealth; set => _enemyHealth = value; }
internal GameEnemy[] _enemyHealth;

public GameEndResults EndResults { get => _endResults; set => _endResults = value; }
internal GameEndResults _endResults;

public float IGT { get => _igt; set => _igt = value; }
internal float _igt;

public TimeSpan IGTTimeSpan
{
get
{
TimeSpan timespanIGT;

if (IGT >= 0f)
timespanIGT = TimeSpan.FromSeconds(IGT);
else
timespanIGT = new TimeSpan();

return timespanIGT;
}
}

public string IGTFormattedString => IGTTimeSpan.ToString(IGT_TIMESPAN_STRING_FORMAT, CultureInfo.InvariantCulture);

public TimeSpan SegmentTimeSpan
{
get
{
TimeSpan timespanIGT;

if (EndResults.ClearTime >= 0f)
timespanIGT = TimeSpan.FromSeconds(EndResults.ClearTime);
else
Expand All @@ -39,6 +62,6 @@ public TimeSpan IGTTimeSpan
}
}

public string IGTFormattedString => IGTTimeSpan.ToString(IGT_TIMESPAN_STRING_FORMAT, CultureInfo.InvariantCulture);
public string SegmentFormattedString => SegmentTimeSpan.ToString(IGT_TIMESPAN_STRING_FORMAT, CultureInfo.InvariantCulture);
}
}
29 changes: 21 additions & 8 deletions SRTPluginProviderRER1/GameMemoryRER1Scanner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace SRTPluginProviderRER1
{
internal unsafe class GameMemoryRER1Scanner : IDisposable
{
private readonly int MAX_ENTITIES = 3;
private readonly int MAX_ENTITIES = 16;
// Variables
private ProcessMemoryHandler memoryAccess;
private GameMemoryRER1 gameMemoryValues;
Expand All @@ -16,16 +16,19 @@ internal unsafe class GameMemoryRER1Scanner : IDisposable
public int ProcessExitCode => (memoryAccess != null) ? memoryAccess.ProcessExitCode : 0;

// Pointer Address Variables
private int pointerAddressHP;
private int pointerAddressPlayer;
private int pointerAddressStats;
private int pointerAddressEnemy;
private int pointerAddressIGT;

// Pointer Classes
private IntPtr BaseAddress { get; set; }

private MultilevelPointer[] PointerEnemy { get; set; }
private MultilevelPointer PointerHP { get; set; }
private MultilevelPointer PointerStats { get; set; }
private MultilevelPointer PointerInventory { get; set; }
private MultilevelPointer PointerIGT { get; set; }

internal GameMemoryRER1Scanner(Process process = null)
{
Expand All @@ -49,8 +52,10 @@ internal unsafe void Initialize(Process process)
BaseAddress = NativeWrappers.GetProcessBaseAddress(pid, PInvoke.ListModules.LIST_MODULES_32BIT); // Bypass .NET's managed solution for getting this and attempt to get this info ourselves via PInvoke since some users are getting 299 PARTIAL COPY when they seemingly shouldn't.

//POINTERS
PointerHP = new MultilevelPointer(memoryAccess, IntPtr.Add(BaseAddress, pointerAddressHP), 0x44, 0x10);
PointerHP = new MultilevelPointer(memoryAccess, IntPtr.Add(BaseAddress, pointerAddressPlayer), 0x44, 0x10);
PointerInventory = new MultilevelPointer(memoryAccess, IntPtr.Add(BaseAddress, pointerAddressPlayer), 0x44, 0xF8);
PointerStats = new MultilevelPointer(memoryAccess, IntPtr.Add(BaseAddress, pointerAddressStats));
PointerIGT = new MultilevelPointer(memoryAccess, IntPtr.Add(BaseAddress, pointerAddressIGT));
var position = 0;
PointerEnemy = new MultilevelPointer[MAX_ENTITIES];
gameMemoryValues._enemyHealth = new GameEnemy[MAX_ENTITIES];
Expand All @@ -66,14 +71,17 @@ internal unsafe void Initialize(Process process)
private void SelectPointerAddresses()
{
pointerAddressEnemy = 0xDE6184;
pointerAddressHP = 0xD6F394;
pointerAddressPlayer = 0xD6F394;
pointerAddressStats = 0xD707E4;
pointerAddressIGT = 0xD70B60;
}

internal void UpdatePointers()
{
PointerHP.UpdatePointers();
PointerInventory.UpdatePointers();
PointerStats.UpdatePointers();
PointerIGT.UpdatePointers();
for (var i = 0; i < MAX_ENTITIES; i++)
{
PointerEnemy[i].UpdatePointers();
Expand All @@ -82,16 +90,21 @@ internal void UpdatePointers()

internal unsafe IGameMemoryRER1 Refresh()
{
// Rebecca
gameMemoryValues._player = PointerHP.Deref<GamePlayer>(0xE3C);
// Player
gameMemoryValues._player = PointerHP.Deref<GamePlayer>(0x0);

// Player Inventory
gameMemoryValues._playerInventory = PointerInventory.Deref<GameInventory>(0x0);

// Game Statistics
gameMemoryValues._endResults = PointerStats.Deref<GameEndResults>(0x0);

//Enemy HP
gameMemoryValues._igt = PointerIGT.DerefFloat(0x2C);

// Enemy HP Array
for (var i = 0; i < MAX_ENTITIES; i++)
{
gameMemoryValues._enemyHealth[i] = PointerEnemy[i].Deref<GameEnemy>(0xE3C);
gameMemoryValues._enemyHealth[i] = PointerEnemy[i].Deref<GameEnemy>(0x0);
}

HasScanned = true;
Expand Down
4 changes: 4 additions & 0 deletions SRTPluginProviderRER1/IGameMemoryRER1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ public interface IGameMemoryRER1
string VersionInfo { get; }

GamePlayer Player { get; set; }
GameInventory PlayerInventory { get; set; }
GameEnemy[] EnemyHealth { get; set; }
GameEndResults EndResults { get; set; }
float IGT { get; set; }

TimeSpan IGTTimeSpan { get; }
string IGTFormattedString { get; }
TimeSpan SegmentTimeSpan { get; }
string SegmentFormattedString { get; }

}
}
3 changes: 1 addition & 2 deletions SRTPluginProviderRER1/Structs/GameStructs/GameEndResults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,13 @@ namespace SRTPluginProviderRER1.Structs.GameStructs

public struct GameEndResults
{
[FieldOffset(0x34)] private int rank;
[FieldOffset(0x38)] private int rankScore;
[FieldOffset(0x6B8)] private int shotsFired;
[FieldOffset(0x6BC)] private int enemiesHit;
[FieldOffset(0x6C0)] private int deaths;
[FieldOffset(0x6DC)] private float clearTime;

public int Rank => rank;
public int Rank => (int)Math.Floor((decimal)rankScore / 1000);
public int RankScore => rankScore;
public int ShotsFired => shotsFired;
public int EnemiesHit => enemiesHit;
Expand Down
86 changes: 58 additions & 28 deletions SRTPluginProviderRER1/Structs/GameStructs/GameEnemy.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,68 @@
using System.Diagnostics;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace SRTPluginProviderRER1.Structs.GameStructs
{
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 0x8)]
[DebuggerDisplay("{_DebuggerDisplay,nq}")]
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 0xE44)]
public struct GameEnemy
{
[FieldOffset(0x0)] private float currentHP;
[FieldOffset(0x4)] private float maximumHP;
[FieldOffset(0xE28)] private short id;
[FieldOffset(0xE3C)] private float currentHP;
[FieldOffset(0xE40)] private float maximumHP;

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public string _DebuggerDisplay
{
get
{
if (IsTrigger)
{
return string.Format("TRIGGER", CurrentHP, MaximumHP, Percentage);
}
else if (IsAlive)
{
return string.Format("{0} / {1} ({2:P1})", CurrentHP, MaximumHP, Percentage);
}
return "DEAD / DEAD (0%)";
}
}
public short ID => id;
public string Name => Enemies.NamesList.ContainsKey(ID) ? string.Format("{0}: ", Enemies.NamesList[ID]) : "";
public bool IsNaN(float hp) => hp.CompareTo(float.NaN) == 0;
public float CurrentHP => !IsNaN(currentHP) ? currentHP : 0f;
public float MaximumHP => !IsNaN(maximumHP) ? maximumHP : 0f;
public bool IsTrigger => !Enemies.NamesList.ContainsKey(ID);
public bool IsAlive => !IsTrigger && CurrentHP != 0;
public bool IsDamaged => IsAlive ? CurrentHP < MaximumHP : false;
public float Percentage => (IsAlive) ? CurrentHP / MaximumHP : 0f;
}

public float CurrentHP => currentHP;
public float MaximumHP => maximumHP;
public bool IsTrigger => MaximumHP <= 10f || MaximumHP > 100000f;
public bool IsNaN => MaximumHP.CompareTo(float.NaN) == 0;
public bool IsAlive => !IsNaN && !IsTrigger && CurrentHP <= MaximumHP;
public bool IsDamaged => IsAlive && CurrentHP < MaximumHP;
public float Percentage => ((IsAlive) ? CurrentHP / MaximumHP : 0f);
public class Enemies
{
public static Dictionary<short, string> NamesList = new Dictionary<short, string>()
{
{ 0x1000, "Mutated Ooze" },
{ 0x1010, "Claw Ooze" },
{ 0x1020, "Shooter Ooze" },
{ 0x1030, "Explode Ooze" },
{ 0x1060, "Rachael Ooze" },
{ 0x1070, "Mutated Ooze" },
{ 0x1080, "Claw Ooze" },
{ 0x1090, "Shooter Ooze" },
{ 0x1200, "Sea Creeper" },
{ 0x1201, "Sea Creeper" },
{ 0x1210, "Mutated Dog" },
{ 0x1211, "Mutated Dog" },
{ 0x1220, "Fish" },
{ 0x1221, "Blowfish" },
{ 0x1230, "Green Hunter" },
{ 0x1240, "Invisible Hunter" },
{ 0x1300, "Scarmiglione" },
{ 0x1301, "Scarmiglione" },
{ 0x1310, "Beach Blob" },
{ 0x1320, "Beach Blob" },
{ 0x1330, "LowPoly Beach Blob" },
{ 0x1400, "Scragdead" },
{ 0x1401, "Scragdead" },
{ 0x1410, "Wall Blister" },
{ 0x1420, "Draghignazzo" },
{ 0x1421, "Draghignazzo" },
{ 0x1422, "Draghignazzo" },
{ 0x1430, "Malacoda" },
{ 0x1431, "Malacoda" },
{ 0x1440, "Jack" },
{ 0x1442, "Jack" },
{ 0x1450, "Jack" },
{ 0x1910, "Zenobia" },
{ 0x1911, "Zenobia" },
{ 0x1912, "Zenobia" },
{ 0x1913, "Zenobia" },
{ 0x1920, "Zenobia" }
};
}
}
35 changes: 35 additions & 0 deletions SRTPluginProviderRER1/Structs/GameStructs/GameInventory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System.Runtime.InteropServices;

namespace SRTPluginProviderRER1.Structs.GameStructs
{
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 0xD0)]

public struct GameInventory
{
[FieldOffset(0x40)] private uint handgunAmmo;
[FieldOffset(0x44)] private uint shotgunAmmo;
[FieldOffset(0x48)] private uint machineGunAmmo;
[FieldOffset(0x4C)] private uint rifleAmmo;
[FieldOffset(0x50)] private uint magnumAmmo;

[FieldOffset(0xA0)] private uint handGrenade;
[FieldOffset(0xA4)] private uint shockGrenade;
[FieldOffset(0xA8)] private uint bowDecoy;
[FieldOffset(0xAC)] private uint pulseGrenade;

[FieldOffset(0xC8)] private uint greenHerb;
[FieldOffset(0xCC)] private uint oldKey;

public uint HandgunAmmo => handgunAmmo;
public uint ShotgunAmmo => shotgunAmmo;
public uint MachineGunAmmo => machineGunAmmo;
public uint RifleAmmo => rifleAmmo;
public uint MagnumAmmo => magnumAmmo;
public uint HandGrenade => handGrenade;
public uint ShockGrenade => shockGrenade;
public uint BOWDecoy => bowDecoy;
public uint PulseGrenade => pulseGrenade;
public uint GreenHerb => greenHerb;
public uint OldKey => oldKey;
}
}
47 changes: 43 additions & 4 deletions SRTPluginProviderRER1/Structs/GameStructs/GamePlayer.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Runtime.InteropServices;

namespace SRTPluginProviderRER1.Structs.GameStructs
{
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 0x8)]
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 0xE44)]

public struct GamePlayer
{
[FieldOffset(0x0)] private float currentHP;
[FieldOffset(0x4)] private float maxHP;
[FieldOffset(0xE28)] private short id;
[FieldOffset(0xE3C)] private float currentHP;
[FieldOffset(0xE40)] private float maxHP;

public short ID => id;
public string Name => Characters.NamesList.ContainsKey(ID) ? string.Format("{0}: ", Characters.NamesList[ID]) : "";
public float CurrentHP => currentHP;
public float MaxHP => maxHP;
public float Percentage => CurrentHP > 0 ? (float)CurrentHP / (float)MaxHP : 0f;
Expand All @@ -24,6 +28,41 @@ public PlayerState HealthState
}
}

public class Characters
{
public static Dictionary<short, string> NamesList = new Dictionary<short, string>()
{
{ 0x1000, "Chris" },
{ 0x1010, "Jill" },
{ 0x1020, "Parker" },
{ 0x1030, "Jessica" },
{ 0x1040, "Keith" },
{ 0x1050, "Quint" },
{ 0x1060, "O'Brian" },
{ 0x1070, "Raymond" },
{ 0x1080, "Morgan" },
{ 0x1090, "Jack" },
{ 0x1100, "Chris" },
{ 0x1110, "Jill" },
{ 0x1120, "Parker" },
{ 0x1130, "Jessica" },
{ 0x1140, "Keith" },
{ 0x1150, "Quint" },
{ 0x1200, "Chris" },
{ 0x1210, "Jill" },
{ 0x1220, "Parker" },
{ 0x1230, "Jessica" },
{ 0x1240, "Keith" },
{ 0x1250, "Quint" },
{ 0x1300, "Chris" },
{ 0x1310, "Jill" },
{ 0x1320, "NoModel" },
{ 0x1330, "Jessica" },
{ 0x1400, "Chris" },
{ 0x1420, "Parker" }
};
}

public enum PlayerState
{
Dead,
Expand Down

0 comments on commit 49493cf

Please sign in to comment.