Skip to content

Commit

Permalink
Memory emblem reading preview
Browse files Browse the repository at this point in the history
  • Loading branch information
Refragg committed Jan 29, 2021
1 parent 0c837ac commit 14ed4dc
Showing 1 changed file with 60 additions and 32 deletions.
92 changes: 60 additions & 32 deletions SRB2-Emblem-Displayer/Project1/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,16 @@

namespace CountEmblems
{

class Program
{
[DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess,
int lpBaseAddress, byte[] lpBuffer, int dwSize, IntPtr lpNumberOfBytesRead);

static Process gameProc;
public static bool gameHooked = false;

static MenuItem menuGlobalHotkeys = new MenuItem();
static MenuItem menuReset = new MenuItem();
static public bool hotkeysEnabled;
Expand Down Expand Up @@ -328,50 +336,60 @@ static int customAngle
UpdateText();
}
}
static byte ReadByte(ref byte[] bytes)
{
byte value = bytes[0];
bytes = bytes.Skip(1).ToArray();
return value;
}
static int CountEmblems(ref byte[] bytes, int max_emblems)

private static void GameProc_Exited(object sender, EventArgs e)
{
int result = 0;
for (int i = 0; i < max_emblems;)
{
// Function directly copied from SRB2 source code, where the gamedata handling happens
int j;
byte rtemp = ReadByte(ref bytes);
for (j = 0; j < 8 && j + i < max_emblems; ++j)
result += ((rtemp >> j) & 1);
i += j;
}
return result;
gameProc.Exited -= GameProc_Exited;
gameHooked = false;
}

static void Analyze_file(string fileName, string outputName)
{
byte[] bytes;
int total = previousTotal;
if (fileName != null && fileName != "")

int address;
if (gameHooked)
{
try
{
bytes = File.ReadAllBytes(fileName);
// We don't want to read empty/corrupted gamedata
if (bytes.Length < SKIPPED_BYTES + MAXEMBLEMS + MAXEXTRAEMBLEMS && previousError != "short")
byte[] maxEmblemsBuffer = new byte[4];
byte[] maxExtraBuffer = new byte[4];

ReadProcessMemory(gameProc.Handle, 0x0082E0E4, maxEmblemsBuffer, 1, IntPtr.Zero);
ReadProcessMemory(gameProc.Handle, 0x0082E0E0, maxExtraBuffer, 1, IntPtr.Zero);

int maxEmblems = BitConverter.ToInt32(maxEmblemsBuffer, 0);
int maxExtra = BitConverter.ToInt32(maxExtraBuffer, 0);

byte[] currentEmblem = new byte[1];

int emblems = 0;
address = 0x059F477E;
for (int i = 0; i < maxEmblems; i++)
{
//Console.WriteLine("The gamedata is too short.");
previousError = "short";
ReadProcessMemory(gameProc.Handle, address, currentEmblem, 1, IntPtr.Zero);
if (currentEmblem[0] == 1)
{
emblems++;
}
address += 0x80;
}
else

int extraEmblems = 0;
address = 0x059F4302;
for (int i = 0; i < maxExtra; i++)
{
bytes = bytes.Skip(SKIPPED_BYTES).ToArray();
int emblems = CountEmblems(ref bytes, MAXEMBLEMS);
int extraEmblems = CountEmblems(ref bytes, MAXEXTRAEMBLEMS);
total = emblems + extraEmblems;
ReadProcessMemory(gameProc.Handle, address, currentEmblem, 1, IntPtr.Zero);
if (currentEmblem[0] == 1)
{
extraEmblems++;
}
address += 0x44;
}

total = emblems + extraEmblems;
}
catch (FileNotFoundException e)
catch (Exception e)
{
string errorName = e.GetType().Name;
// We don't want error spam for every loop
Expand All @@ -381,9 +399,19 @@ static void Analyze_file(string fileName, string outputName)
MessageBox.Show(errorName + ": " + e.Message, errorName, MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
else
{
try
{
gameProc = Process.GetProcessesByName("srb2win").First();
gameProc.Exited += GameProc_Exited;
gameProc.EnableRaisingEvents = true;
gameHooked = true;
}
catch
{

Thread.Sleep(1000);
}
}

Expand Down

0 comments on commit 14ed4dc

Please sign in to comment.