From f599e0907694c03cc4f287777f56fc01303e1197 Mon Sep 17 00:00:00 2001 From: spitfirex86 Date: Mon, 5 Aug 2019 18:32:55 +0200 Subject: [PATCH] 2.2.0 - Added GLM Monitor 2000 - Simplified writing/reading coordinates - Fixed pointer path calculation - Minor codestyle fixes --- Rayman2LevelSwitcher.sln | 7 +- Rayman2LevelSwitcher/Game/Rayman2Manager.cs | 112 ++++++++++----- Rayman2LevelSwitcher/Helpers/Memory.cs | 12 +- .../Properties/AssemblyInfo.cs | 4 +- .../Rayman2LevelSwitcher.csproj | 38 +++++ .../ViewModels/AppViewModel.cs | 1 - .../Bookmarks/BookmarkItemViewModel.cs | 2 +- .../Bookmarks/BookmarksViewModel.cs | 35 ++--- .../ViewModels/GameManagerViewModel.cs | 44 +++--- .../ViewModels/GlmWindowViewModel.cs | 133 ++++++++++++++++++ Rayman2LevelSwitcher/Windows/GlmWindow.xaml | 113 +++++++++++++++ .../Windows/GlmWindow.xaml.cs | 24 ++++ Rayman2LevelSwitcher/Windows/MainWindow.xaml | 11 +- 13 files changed, 450 insertions(+), 86 deletions(-) create mode 100644 Rayman2LevelSwitcher/ViewModels/GlmWindowViewModel.cs create mode 100644 Rayman2LevelSwitcher/Windows/GlmWindow.xaml create mode 100644 Rayman2LevelSwitcher/Windows/GlmWindow.xaml.cs 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 + +