diff --git a/Rayman2LevelSwitcher.sln b/Rayman2LevelSwitcher.sln
index 235279b..b39d453 100644
--- a/Rayman2LevelSwitcher.sln
+++ b/Rayman2LevelSwitcher.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29123.88
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Rayman2LevelSwitcher", "Rayman2LevelSwitcher\Rayman2LevelSwitcher.csproj", "{BCBA08D4-60A2-457E-AD48-EBC82C0973D3}"
EndProject
@@ -19,4 +19,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {20EEF419-052A-42FD-BA98-9CBA248DEE11}
+ EndGlobalSection
EndGlobal
diff --git a/Rayman2LevelSwitcher/Game/Rayman2Manager.cs b/Rayman2LevelSwitcher/Game/Rayman2Manager.cs
index 33e4ff0..6de44cf 100644
--- a/Rayman2LevelSwitcher/Game/Rayman2Manager.cs
+++ b/Rayman2LevelSwitcher/Game/Rayman2Manager.cs
@@ -13,39 +13,84 @@ public class Rayman2Manager
{
#region Constant Values
- private const int Off_engineStructure = 0x500380;
- private const int Off_engineMode = Off_engineStructure + 0x0;
- private const int Off_levelName = Off_engineStructure + 0x1F;
- private const int Off_healthpointer_1 = 0x500584;
- private const int Off_voidpointer = 0x500FAA;
+ private const int OffEngineStructure = 0x500380;
+ private const int OffEngineMode = OffEngineStructure + 0x0;
+ private const int OffLevelName = OffEngineStructure + 0x1F;
+ private const int OffHealthPointer = 0x500584;
+ private const int OffVoidPointer = 0x500FAA;
#endregion
+ public (float, float, float) PlayerCoordinates
+ {
+ get => ReadCoordinates(0x500560, 0x224, 0x310, 0x34, 0x0, 0x1ac);
+ set => WriteCoordinates(value.Item1, value.Item2, value.Item3, 0x500560, 0x224, 0x310, 0x34, 0x0, 0x1ac);
+ }
+
+ public (float, float, float) GlmCoordinates
+ {
+ get => ReadCoordinates(0x500298, 0x234, 0x10, 0xC, 0xB0);
+ set => WriteCoordinates(value.Item1, value.Item2, value.Item3, 0x500298, 0x234, 0x10, 0xC, 0xB0);
+ }
+
///
- /// Loads the specified position
+ /// Write coordinates to the game memory
///
///
///
///
- public void LoadPosition(float x, float y, float z)
+ ///
+ ///
+ private void WriteCoordinates(float x, float y, float z, int baseAddress, params int[] offsets)
{
int processHandle = GetRayman2ProcessHandle();
-
if (processHandle < 0)
return;
int bytesReadOrWritten = 0;
- int off_xcoord = Memory.GetPointerPath(processHandle, 0x500560, 0x224, 0x310, 0x34, 0x0) + 0x1ac;
- int off_ycoord = off_xcoord + 4;
- int off_zcoord = off_xcoord + 8;
+ int offXcoord = Memory.GetPointerPath(processHandle, baseAddress, offsets);
+ int offYcoord = offXcoord + 4;
+ int offZcoord = offXcoord + 8;
byte[] xCoordBuffer = BitConverter.GetBytes(x);
byte[] yCoordBuffer = BitConverter.GetBytes(y);
byte[] zCoordBuffer = BitConverter.GetBytes(z);
- Memory.WriteProcessMemory(processHandle, off_xcoord, xCoordBuffer, 4, ref bytesReadOrWritten);
- Memory.WriteProcessMemory(processHandle, off_ycoord, yCoordBuffer, 4, ref bytesReadOrWritten);
- Memory.WriteProcessMemory(processHandle, off_zcoord, zCoordBuffer, 4, ref bytesReadOrWritten);
+ Memory.WriteProcessMemory(processHandle, offXcoord, xCoordBuffer, 4, ref bytesReadOrWritten);
+ Memory.WriteProcessMemory(processHandle, offYcoord, yCoordBuffer, 4, ref bytesReadOrWritten);
+ Memory.WriteProcessMemory(processHandle, offZcoord, zCoordBuffer, 4, ref bytesReadOrWritten);
+ }
+
+ ///
+ /// Reads coordinates from game memory
+ ///
+ ///
+ ///
+ ///
+ private (float, float, float) ReadCoordinates(int baseAddress, params int[] offsets)
+ {
+ int processHandle = GetRayman2ProcessHandle();
+ if (processHandle < 0)
+ return (0, 0, 0);
+
+ int bytesReadOrWritten = 0;
+ int offXcoord = Memory.GetPointerPath(processHandle, baseAddress, offsets);
+ int offYcoord = offXcoord + 4;
+ int offZcoord = offXcoord + 8;
+
+ byte[] xCoordBuffer = new byte[4];
+ byte[] yCoordBuffer = new byte[4];
+ byte[] zCoordBuffer = new byte[4];
+
+ Memory.ReadProcessMemory(processHandle, offXcoord, xCoordBuffer, 4, ref bytesReadOrWritten);
+ Memory.ReadProcessMemory(processHandle, offYcoord, yCoordBuffer, 4, ref bytesReadOrWritten);
+ Memory.ReadProcessMemory(processHandle, offZcoord, zCoordBuffer, 4, ref bytesReadOrWritten);
+
+ return (
+ BitConverter.ToSingle(xCoordBuffer, 0),
+ BitConverter.ToSingle(yCoordBuffer, 0),
+ BitConverter.ToSingle(zCoordBuffer, 0)
+ );
}
///
@@ -99,7 +144,7 @@ public string GetCurrentLevelName(int processHandle)
byte[] buffer = new byte[16];
- Memory.ReadProcessMemory(processHandle, Off_levelName, buffer, buffer.Length, ref bytesReadOrWritten);
+ Memory.ReadProcessMemory(processHandle, OffLevelName, buffer, buffer.Length, ref bytesReadOrWritten);
string levelName = Encoding.ASCII.GetString(buffer);
@@ -116,14 +161,14 @@ public bool IsRayman2Focused()
{
const int nChars = 256;
- StringBuilder Buff = new StringBuilder(nChars);
+ StringBuilder buff = new StringBuilder(nChars);
IntPtr handle = Memory.GetForegroundWindow();
- if (Memory.GetWindowText(handle, Buff, nChars) <= 0)
+ if (Memory.GetWindowText(handle, buff, nChars) <= 0)
return false;
- return Buff.ToString() == "Rayman II";
+ return buff.ToString() == "Rayman II";
}
///
@@ -141,7 +186,7 @@ public bool IsRayman2Paused()
byte[] pausePointerBuffer = new byte[4];
- Memory.ReadProcessMemory(processHandle, Off_voidpointer, pausePointerBuffer, pausePointerBuffer.Length, ref bytesReadOrWritten);
+ Memory.ReadProcessMemory(processHandle, OffVoidPointer, pausePointerBuffer, pausePointerBuffer.Length, ref bytesReadOrWritten);
return BitConverter.ToInt32(pausePointerBuffer, 0) == 1;
}
@@ -161,11 +206,11 @@ public void ActivateNoHealth()
byte[] buffer = { 0 };
byte[] healthPointerBuffer = new byte[4];
- Memory.ReadProcessMemory(processHandle, Off_healthpointer_1, healthPointerBuffer, healthPointerBuffer.Length, ref bytesReadOrWritten);
+ Memory.ReadProcessMemory(processHandle, OffHealthPointer, healthPointerBuffer, healthPointerBuffer.Length, ref bytesReadOrWritten);
- int off_healthPointer = BitConverter.ToInt32(healthPointerBuffer, 0) + 0x245;
+ int offHealthPointer = BitConverter.ToInt32(healthPointerBuffer, 0) + 0x245;
- Memory.WriteProcessMemory(processHandle, off_healthPointer, buffer, buffer.Length, ref bytesReadOrWritten);
+ Memory.WriteProcessMemory(processHandle, offHealthPointer, buffer, buffer.Length, ref bytesReadOrWritten);
}
///
@@ -173,7 +218,7 @@ public void ActivateNoHealth()
///
public void ActivateVoid()
{
- Process process = new Rayman2Manager().GetRayman2Process();
+ Process process = GetRayman2Process();
if (process == null)
{
@@ -187,7 +232,7 @@ public void ActivateVoid()
byte[] buffer = { 0 };
- Memory.WriteProcessMemory((int)processHandle, Rayman2Manager.Off_voidpointer, buffer, buffer.Length, ref bytesReadOrWritten);
+ Memory.WriteProcessMemory((int)processHandle, OffVoidPointer, buffer, buffer.Length, ref bytesReadOrWritten);
}
///
@@ -195,19 +240,17 @@ public void ActivateVoid()
///
public void ReloadLevel()
{
- var manager = new Rayman2Manager();
-
- int processHandle = manager.GetRayman2ProcessHandle();
+ int processHandle = GetRayman2ProcessHandle();
int bytesReadOrWritten = 0;
byte[] currentBufferLevelName = new byte[1];
- Memory.ReadProcessMemory(processHandle, Off_levelName, currentBufferLevelName, currentBufferLevelName.Length, ref bytesReadOrWritten);
+ Memory.ReadProcessMemory(processHandle, OffLevelName, currentBufferLevelName, currentBufferLevelName.Length, ref bytesReadOrWritten);
if (currentBufferLevelName[0] == 0)
{
byte[] bufferLevelNameMenu = Encoding.ASCII.GetBytes("menu" + Char.MinValue); // null-terminated
- Memory.WriteProcessMemory(processHandle, Off_levelName, bufferLevelNameMenu, bufferLevelNameMenu.Length, ref bytesReadOrWritten);
+ Memory.WriteProcessMemory(processHandle, OffLevelName, bufferLevelNameMenu, bufferLevelNameMenu.Length, ref bytesReadOrWritten);
return;
}
@@ -216,7 +259,7 @@ public void ReloadLevel()
6
};
- Memory.WriteProcessMemory(processHandle, Off_engineMode, buffer, buffer.Length, ref bytesReadOrWritten);
+ Memory.WriteProcessMemory(processHandle, OffEngineMode, buffer, buffer.Length, ref bytesReadOrWritten);
}
///
@@ -225,21 +268,20 @@ public void ReloadLevel()
///
public void ChangeLevel(string levelName)
{
- var manager = new Rayman2Manager();
-
- int processHandle = manager.GetRayman2ProcessHandle();
+ int processHandle = GetRayman2ProcessHandle();
int bytesReadOrWritten = 0;
var buffer = Encoding.ASCII.GetBytes(levelName + Char.MinValue);
- Memory.WriteProcessMemory(processHandle, Off_levelName, buffer, buffer.Length, ref bytesReadOrWritten);
+ Memory.WriteProcessMemory(processHandle, OffLevelName, buffer, buffer.Length, ref bytesReadOrWritten);
buffer = new byte[]
{
6
};
- Memory.WriteProcessMemory(processHandle, Off_engineMode, buffer, buffer.Length, ref bytesReadOrWritten);
+ Memory.WriteProcessMemory(processHandle, OffEngineMode, buffer, buffer.Length, ref bytesReadOrWritten);
}
+
}
}
\ No newline at end of file
diff --git a/Rayman2LevelSwitcher/Helpers/Memory.cs b/Rayman2LevelSwitcher/Helpers/Memory.cs
index cdbde02..d684cca 100644
--- a/Rayman2LevelSwitcher/Helpers/Memory.cs
+++ b/Rayman2LevelSwitcher/Helpers/Memory.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
@@ -36,8 +37,15 @@ public static int GetPointerPath(int processHandle, int baseAddress, params int[
foreach (int offset in offsets)
{
- ReadProcessMemory(processHandle, currentAddress + offset, buffer, buffer.Length, ref bytesReadOrWritten);
- currentAddress = BitConverter.ToInt32(buffer, 0);
+ if (offset == offsets.Last())
+ {
+ currentAddress += offset;
+ }
+ else
+ {
+ ReadProcessMemory(processHandle, currentAddress + offset, buffer, buffer.Length, ref bytesReadOrWritten);
+ currentAddress = BitConverter.ToInt32(buffer, 0);
+ }
}
return currentAddress;
diff --git a/Rayman2LevelSwitcher/Properties/AssemblyInfo.cs b/Rayman2LevelSwitcher/Properties/AssemblyInfo.cs
index f2e835e..f6f1d1f 100644
--- a/Rayman2LevelSwitcher/Properties/AssemblyInfo.cs
+++ b/Rayman2LevelSwitcher/Properties/AssemblyInfo.cs
@@ -49,5 +49,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.1.1.0")]
-[assembly: AssemblyFileVersion("2.1.1.0")]
+[assembly: AssemblyVersion("2.2.0.0")]
+[assembly: AssemblyFileVersion("2.2.0.0")]
diff --git a/Rayman2LevelSwitcher/Rayman2LevelSwitcher.csproj b/Rayman2LevelSwitcher/Rayman2LevelSwitcher.csproj
index 4a16cdf..29184d3 100644
--- a/Rayman2LevelSwitcher/Rayman2LevelSwitcher.csproj
+++ b/Rayman2LevelSwitcher/Rayman2LevelSwitcher.csproj
@@ -16,6 +16,21 @@
true
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
AnyCPU
@@ -70,14 +85,22 @@
+
+
+ GlmWindow.xaml
+
RenameDialog.xaml
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
@@ -121,10 +144,25 @@
3.0.1
+
+ 4.5.0
+
+
+
+ False
+ Microsoft .NET Framework 4.5.2 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+