From 8bdc07d490cfd58f685d0f6cce5ff88e61e8192c Mon Sep 17 00:00:00 2001 From: keoy7am Date: Sat, 23 Nov 2019 06:45:31 +0800 Subject: [PATCH] implement russian roulette mode --- GTA5 Casino Helper.csproj | 23 +++++ GTA5 Casino Helper.sln | 6 ++ MainWindow.xaml.cs | 172 +++++++++++++++++++++++++++++++------ MemoryHelper.cs | 139 ++++++++++++++++++++++++++++++ Properties/AssemblyInfo.cs | 4 +- SimulateHelper.cs | 111 ++++++++++++++++++++++++ 6 files changed, 427 insertions(+), 28 deletions(-) create mode 100644 MemoryHelper.cs create mode 100644 SimulateHelper.cs diff --git a/GTA5 Casino Helper.csproj b/GTA5 Casino Helper.csproj index affc9d1..9ed18e7 100644 --- a/GTA5 Casino Helper.csproj +++ b/GTA5 Casino Helper.csproj @@ -56,6 +56,28 @@ MinimumRecommendedRules.ruleset true + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + 7.3 + prompt + MinimumRecommendedRules.ruleset + true + packages\ControlzEx.3.0.2.4\lib\net45\ControlzEx.dll @@ -88,6 +110,7 @@ MSBuild:Compile Designer + MSBuild:Compile diff --git a/GTA5 Casino Helper.sln b/GTA5 Casino Helper.sln index 2d27962..a987704 100644 --- a/GTA5 Casino Helper.sln +++ b/GTA5 Casino Helper.sln @@ -8,17 +8,23 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Debug|x64.ActiveCfg = Debug|x64 + {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Debug|x64.Build.0 = Debug|x64 {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Debug|x86.ActiveCfg = Debug|x86 {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Debug|x86.Build.0 = Debug|x86 {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Release|Any CPU.ActiveCfg = Release|Any CPU {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Release|Any CPU.Build.0 = Release|Any CPU + {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Release|x64.ActiveCfg = Release|x64 + {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Release|x64.Build.0 = Release|x64 {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Release|x86.ActiveCfg = Release|x86 {0F56EDA9-CF7F-4C49-A67B-3FCD434D4902}.Release|x86.Build.0 = Release|x86 EndGlobalSection diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 00359ee..1928ebc 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -18,6 +18,9 @@ using Process.NET.Memory; using SysProcess = System.Diagnostics.Process; using keyTypes = Process.NET.Native.Types.Keys; +using System.Runtime.InteropServices; +using System.ComponentModel; +using System.Threading; namespace GTA5_Casino_Helper { @@ -27,17 +30,41 @@ namespace GTA5_Casino_Helper public partial class MainWindow : MetroWindow { // TODO Log - // TODO Implement Russian Roulette Mode // TODO Hotkey SysProcess _process { get; set; } ProcessSharp _sharp { get; set; } bool isHB_Running = false; - bool isBR_Running = false; + bool isRR_Running = false; + static readonly IntPtr[] RR_BettingAmout_Offsets = + { + (IntPtr)0x028AA178, + (IntPtr)0x28, + (IntPtr)0x48, + (IntPtr)0x120, + (IntPtr)0xA8, + (IntPtr)0x58, + (IntPtr)0x108, + (IntPtr)0x34 + }; + static readonly IntPtr[] RR_BettingNumber_Offsets = + { + (IntPtr)0x02E18A88, + (IntPtr)0x08, + (IntPtr)0x298, + (IntPtr)0x10, + (IntPtr)0x108, + (IntPtr)0x4D0 + }; + Thread RRWorkerThread; public MainWindow() { InitializeComponent(); - } + RRWorkerThread = new Thread(RRWorker); + RRWorkerThread.IsBackground = true; + RRWorkerThread.Start(); + } + #region Event private async void StatusBar_PreviewMouseDown(object sender, MouseButtonEventArgs e) { try @@ -57,22 +84,125 @@ private async void StatusBar_PreviewMouseDown(object sender, MouseButtonEventArg } private async void btn_EarnMoneyByHB_Click(object sender, RoutedEventArgs e) { - if (isBR_Running) + try + { + #region oooo + if (isRR_Running) + { + MessageBox.Show("You are running russian roulette now."); + return; + } + + + if (isHB_Running) + { + await SetStatus("關閉自動下注"); + isHB_Running = false; + } + else + { + await SetStatus("啟用自動下注"); + isHB_Running = true; + } + #endregion + await HR_ClickBet(); + } + catch (Exception ex) { - MessageBox.Show("You are running russian roulette now."); - return; + MessageBox.Show($"{ex.Message}"); } - await HR_ClickBet(); + } - private void btn_EarnMoneyByRR_Click(object sender, RoutedEventArgs e) + private async void btn_EarnMoneyByRR_Click(object sender, RoutedEventArgs e) { - MessageBox.Show("Non-Support Now."); - if (isHB_Running) + try + { + #region oooo + if (isHB_Running) + { + MessageBox.Show("You are running horse betting now."); + return; + } + + + if (isRR_Running) + { + await SetStatus("關閉自動下注"); + isRR_Running = false; + } + else + { + await SetStatus("啟用自動下注"); + isRR_Running = true; + } + #endregion + await SetStatus("已鎖定俄羅斯輪盤出 0 , 下 0 金額為 50000。"); + isRR_Running = true; + } + catch (Exception ex) { - MessageBox.Show("You are running horse betting now."); - return; + MessageBox.Show($"{ex.Message}"); } } + #endregion + #region RR + private async void RRWorker() + { + while (true) + { + try + { + if (!isRR_Running) + { + Thread.Sleep(TimeSpan.FromSeconds(5)); + continue; + } + SetBettingAmount(); + SetBettingNumber(); + } + catch (Exception ex) + { + await SetStatus($"RRWorker() => {ex.Message}"); + MessageBox.Show($"自動下注已停止,錯誤如下:\n{ex.Message}"); + isRR_Running = false; + } + finally + { + Thread.Sleep(TimeSpan.FromMilliseconds(250)); + } + } + } + private void SetBettingAmount() + { + try + { + IntPtr bettingAmountPtr = MemoryHelper.GetPtr(_process, RR_BettingAmout_Offsets, true); + byte[] bettingAmount = BitConverter.GetBytes(50000); + + _sharp.Memory = new ExternalProcessMemory(_sharp.Handle); + _sharp.Memory.Write((IntPtr)bettingAmountPtr, bettingAmount); + } + catch (Exception ex) + { + throw new Exception($"SetBettingAmount():{ex.Message}"); + } + } + private void SetBettingNumber() + { + try + { + IntPtr bettingNumberPtr = MemoryHelper.GetPtr(_process, RR_BettingNumber_Offsets, true); + byte[] bettingNumber = BitConverter.GetBytes(0); + + _sharp.Memory = new ExternalProcessMemory(_sharp.Handle); + _sharp.Memory.Write((IntPtr)bettingNumberPtr, bettingNumber); + } + catch (Exception ex) + { + throw new Exception($"SetBettingNumber():{ex.Message}"); + } + } + #endregion private async Task SetUIAsync(bool enable) { try @@ -84,7 +214,7 @@ await this.Dispatcher.BeginInvoke(new Action(() => StatusBar.Text = "Status:Game Detected!"; StatusBar.IsEnabled = false; btn_EarnMoneyByHB.IsEnabled = true; - btn_EarnMoneyByBR.IsEnabled = true; + btn_EarnMoneyByRR.IsEnabled = true; })); } else @@ -94,7 +224,7 @@ await this.Dispatcher.BeginInvoke(new Action(() => StatusBar.Text = "Status:Game Detected!"; StatusBar.IsEnabled = true; btn_EarnMoneyByHB.IsEnabled = false; - btn_EarnMoneyByBR.IsEnabled = false; + btn_EarnMoneyByRR.IsEnabled = false; })); } } @@ -120,16 +250,6 @@ await this.StatusBar.Dispatcher.BeginInvoke(new Action(() => private async Task HR_ClickBet() { var window = _sharp.WindowFactory.MainWindow; - if (isHB_Running) - { - await SetStatus("關閉自動下注"); - isHB_Running = false; - } - else - { - await SetStatus("啟用自動下注"); - isHB_Running = true; - } while (isHB_Running) { // TODO 寫成Action @@ -168,10 +288,10 @@ private async Task HR_ClickBet() window.Mouse.MoveTo(950, 1010); SimulateHelper.LeftClick(950, 1010); - for(int i = 500; i > 0; i--) + for (int i = 500; i > 0; i--) { await Task.Delay(1); - await SetStatus($"將在 {i/100} 秒後重新執行下注"); + await SetStatus($"將在 {i / 100} 秒後重新執行下注"); if (!isHB_Running) { await SetStatus($"結束。"); diff --git a/MemoryHelper.cs b/MemoryHelper.cs new file mode 100644 index 0000000..e1c1a35 --- /dev/null +++ b/MemoryHelper.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using SysProcess = System.Diagnostics.Process; + +namespace GTA5_Casino_Helper +{ + public static class MemoryHelper + { + // TODO Support x86 ( Fork me plz,i'm lazy. ) + [DllImport("kernel32.dll")] + public static extern IntPtr ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, + [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead); + public static byte[] ReadBytes(IntPtr Handle, IntPtr Address, uint BytesToRead) + { + IntPtr ptrBytesRead; + byte[] buffer = new byte[BytesToRead]; + ReadProcessMemory(Handle, Address, buffer, BytesToRead, out ptrBytesRead); + return buffer; + } + public static Int64 ReadInt64(IntPtr Address, uint length = 8, IntPtr? Handle = null) + { + return (BitConverter.ToInt64(ReadBytes((IntPtr)Handle, Address, length), 0)); + } + static IntPtr GetBase(SysProcess handle, string module = null) + { + ProcessModuleCollection modules = handle.Modules; + if (module != null) + { + for (int i = 0; i <= modules.Count - 1; i++) + { + if (modules[i].ModuleName == module) + { + return (IntPtr)modules[i].BaseAddress; + } + } + Console.WriteLine("Module Not Found"); + + } + else + { + return (IntPtr)handle.MainModule.BaseAddress; + } + return (IntPtr)0; + } + static IntPtr GetBase(string pname) + { + SysProcess handle = SysProcess.GetProcessesByName(pname)[0]; + return handle.MainModule.BaseAddress; + } + static IntPtr ReadValueByPrt(SysProcess process, IntPtr[] offsets, bool debug = false, string module = null) + { + + IntPtr tmpptr = (IntPtr)0; + IntPtr Base = GetBase(process); + Console.WriteLine("Original base: " + Base); + if (module != null) + { + Base = GetBase(process, module); + Console.WriteLine("Module base: " + Base); + Console.WriteLine(""); + + } + + for (int i = 0; i <= offsets.Length - 1; i++) + { + if (i == 0) + { + if (debug) + Console.Write(Base + "[Base] + " + offsets[i] + "[OFFSET 0]"); + IntPtr ptr = IntPtr.Add(Base, (int)offsets[i]); + tmpptr = (IntPtr)ReadInt64(ptr, 8, process.Handle); + if (debug) + Console.WriteLine(" is " + tmpptr); + } + else + { + if (debug) + Console.Write(tmpptr + " + " + offsets[i] + "[OFFSET " + i + "]"); + IntPtr ptr2 = IntPtr.Add(tmpptr, (int)offsets[i]); + tmpptr = (IntPtr)ReadInt64(ptr2, 8, process.Handle); //last position's value + + if (debug) + Console.WriteLine(" is " + tmpptr); + } + } + + return tmpptr; + } + public static IntPtr GetPtr(SysProcess process, IntPtr[] offsets, bool debug = false, string module = null) + { + IntPtr tmpptr = (IntPtr)0; + IntPtr Base = GetBase(process); + Console.WriteLine("Original base: " + Base); + if (module != null) + { + Base = GetBase(process, module); + Console.WriteLine("Module base: " + Base); + Console.WriteLine(""); + + } + + for (int i = 0; i <= offsets.Length - 1; i++) + { + if (i == 0) + { + if (debug) + Console.Write(Base + "[Base] + " + offsets[i] + "[OFFSET 0]"); + IntPtr ptr = IntPtr.Add(Base, (int)offsets[i]); + tmpptr = (IntPtr)ReadInt64(ptr, 8, process.Handle); + if (debug) + Console.WriteLine(" is " + tmpptr); + } + else + { + if (debug) + Console.Write(tmpptr + " + " + offsets[i] + "[OFFSET " + i + "]"); + IntPtr ptr2 = IntPtr.Add(tmpptr, (int)offsets[i]); + if (i == offsets.Length - 1) + { + if (debug) + Console.WriteLine(" is " + ptr2); + return ptr2; + } + tmpptr = (IntPtr)ReadInt64(ptr2, 8, process.Handle); + + if (debug) + Console.WriteLine(" is " + tmpptr); + } + } + + return tmpptr; + } + } +} diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 2953a42..96c6a95 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -51,5 +51,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("0.0.0.1")] -[assembly: AssemblyFileVersion("0.0.0.1")] +[assembly: AssemblyVersion("0.0.0.2")] +[assembly: AssemblyFileVersion("0.0.0.2")] diff --git a/SimulateHelper.cs b/SimulateHelper.cs new file mode 100644 index 0000000..6c2d32c --- /dev/null +++ b/SimulateHelper.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Shapes; + +namespace GTA5_Casino_Helper +{ + public static class SimulateHelper + { + #region Dll Imports + + [DllImport("User32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern long GetClassName(IntPtr hwnd, StringBuilder lpClassName, long nMaxCount); + [DllImport("user32.dll")] + public static extern Boolean GetWindowRect(IntPtr hWnd, ref Rectangle bounds); + + [DllImport("user32.dll", SetLastError = true)] + + static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + + [DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)] + static extern IntPtr FindWindowEx(IntPtr parent, IntPtr child, string classname, string captionName); + [DllImport("user32.dll")] + public static extern int SendMessage(int hWnd, uint Msg, int wParam, int lParam); + [DllImport("user32.dll", CharSet = CharSet.Auto)] + static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, + IntPtr wParam, string lParam); + [DllImport("User32.dll")] + public static extern Int32 SendMessage(int hWnd, int Msg, int wParam, StringBuilder lParam); + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool SetForegroundWindow(IntPtr hWnd); + [DllImport("user32.dll", SetLastError = true)] + static extern IntPtr SetFocus(IntPtr hWnd); + [DllImport("user32.dll")] + public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam); + + public delegate bool CallBack(IntPtr hwnd, int lParam); + public static IntPtr FindWindowEx(IntPtr hwnd, string lpszWindow, bool searchByTitle, bool bChild) + { + IntPtr iResult = IntPtr.Zero; + iResult = FindWindowEx(hwnd, IntPtr.Zero, null, lpszWindow); + if (iResult != IntPtr.Zero) return iResult; + + if (!bChild) return iResult; + + int i = EnumChildWindows( + hwnd, + (h, l) => + { + IntPtr f1 = IntPtr.Zero; + if (searchByTitle) + { + f1 = FindWindowEx(h, IntPtr.Zero, null, lpszWindow); + } + else + { + f1 = FindWindowEx(h, IntPtr.Zero, lpszWindow, null); + } + if (f1 == IntPtr.Zero) + return true; + else + { + iResult = f1; + return false; + } + }, + 0); + + return iResult; + } + [DllImport("user32.dll")] + static extern bool SetCursorPos(int x, int y); + + [DllImport("user32.dll")] + public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo); + #endregion + #region Const + private const int WM_SYSCOMMAND = 0x0112; + private const int SC_CLOSE = 0xF060; + private const int WM_CLOSE = 16; + private const int BN_CLICKED = 245; + private const int WM_SETTEXT = 0x000C; + private const int WM_GETTEXT = 0x000D; + private const int WM_GETTEXTLENGTH = 0x000E; + private const int MOUSEEVENTF_LEFTDOWN = 0x02; + private const int MOUSEEVENTF_LEFTUP = 0x04; + #endregion + #region Methods + public static void LeftClick(int PositionX, int PositionY) + { + SetCursorPos(PositionX, PositionY); + mouse_event(MOUSEEVENTF_LEFTDOWN, PositionX, PositionY, 0, 0); + System.Threading.Thread.Sleep(50); + mouse_event(MOUSEEVENTF_LEFTUP, PositionX, PositionY, 0, 0); + } + public static void PressLeft(int PositionX, int PositionY) + { + mouse_event(MOUSEEVENTF_LEFTDOWN, PositionX, PositionY, 0, 0); + } + public static void ReleaseLeft(int PositionX, int PositionY) + { + mouse_event(MOUSEEVENTF_LEFTUP, PositionX, PositionY, 0, 0); + } + #endregion + } +}