我正在编写一个小程序来读取游戏中的统计数据,比如健康,法力等等......我想在未来制作一个工具,以便稍后计算统计数据。我来到程序读取Health的部分,但是经过一段时间后,标签中的值将变为0,我必须重新启动程序才能再次正确显示,我做错了什么?
这是我的代码,以我的主要形式:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace RMBot
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
static bool botrunning = false;
private void OnOff_Click(object sender, EventArgs e)
{
if (botrunning == false)
{
OnOff.Text = "STOP";
botrunning = true;
//Thread t = new Thread(new ThreadStart(CombatInit));
//t.Start();
Thread b = new Thread(new ThreadStart(stats));
b.Start();
}
else {
OnOff.Text = "START";
botrunning = false;
}
}
private void SetText(Control control, string text)
{
if (control.InvokeRequired)
this.Invoke(new Action<Control>((c) => c.Text = text), control);
else
control.Text = text;
}
/*STATS*/
public void stats()
{
while (botrunning == true) {
// update label approximately 10 times every second
Thread.Sleep(100);
HPLabel.BeginInvoke(new Action(() =>
{
HPLabel.Text = string.Format(Memory.SetCurrentHP());
}));
}
}
}
这是我的记忆课:
public static string SetCurrentHP()
{
return Convert.ToString(ReadInt32(gameBaseAddress + HpAdr, Handle));
//return "WORKING";
}
添加了我的记忆课:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
namespace RMBot
{
class Memory
{
[DllImport("kernel32.dll")]
public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
public static byte[] ReadBytes(IntPtr Handle, Int64 Address, uint BytesToRead)
{
IntPtr bytesRead;
byte[] buffer = new byte[BytesToRead];
ReadProcessMemory(Handle, new IntPtr(Address), buffer, BytesToRead, out bytesRead);
return buffer;
}
/* READ INT */
public static int ReadInt32(Int64 Address, IntPtr Handle)
{
return BitConverter.ToInt32(ReadBytes(Handle, Address, 4), 0);
}
/* READ STRING */
public static string ReadString(long Address, IntPtr Handle, uint length = 32)
{
return ASCIIEncoding.Default.GetString(ReadBytes(Handle, Address, length)).Split('\0')[0];
}
public static void GetClient()
{
Process Aion = Process.GetProcessesByName("aion.bin")[0];
UInt32 winBase = (UInt32)Aion.MainModule.BaseAddress.ToInt32();
//seznam vseh modulov
ProcessModuleCollection myProcessModuleCollection = Aion.Modules;
//iskani modul
ProcessModule myProcessModule;
UInt32 gameBase = 0;
for (int x = 0; x < myProcessModuleCollection.Count; x++)
{
myProcessModule = myProcessModuleCollection[x];
if (myProcessModuleCollection[x].ModuleName == "Game.dll")
{
gameBase = (UInt32)myProcessModule.BaseAddress.ToInt32();
//Console.WriteLine("The moduleName is " + myProcessModule.ModuleName);
//Console.WriteLine("The " + myProcessModule.ModuleName + "'s File Name is: " + myProcessModule.FileName);
//Console.WriteLine("The " + myProcessModule.ModuleName + "'s base address is: " + myProcessModule.BaseAddress);
//Console.WriteLine("For " + myProcessModule.ModuleName + " Entry point address is: " + myProcessModule.EntryPointAddress);
}
}
IntPtr Handle = Aion.Handle;
//Console.WriteLine("Base Address : " + Convert.ToString(gameBase));
/*OFFSETS*/
//Current HP
//UInt32 HpAdr = 0xEB5AB0;
//String Hp = Convert.ToString(ReadInt32(gameBase + HpAdr, Handle));
//Console.WriteLine("Health: " + Convert.ToString(ReadInt32(gameBase + HpAdr, Handle)));
//Console.ReadLine();
}
//Gets the base address of the game
public static int GetGameBase()
{
Process Aion = Process.GetProcessesByName("aion.bin")[0];
UInt32 winBase = (UInt32)Aion.MainModule.BaseAddress.ToInt32();
//seznam vseh modulov
ProcessModuleCollection myProcessModuleCollection = Aion.Modules;
//iskani modul
ProcessModule myProcessModule;
UInt32 gameBase = 0;
for (int x = 0; x < myProcessModuleCollection.Count; x++)
{
myProcessModule = myProcessModuleCollection[x];
if (myProcessModuleCollection[x].ModuleName == "Game.dll")
{
gameBase = (UInt32)myProcessModule.BaseAddress.ToInt32();
//Console.WriteLine("The moduleName is " + myProcessModule.ModuleName);
//Console.WriteLine("The " + myProcessModule.ModuleName + "'s File Name is: " + myProcessModule.FileName);
//Console.WriteLine("The " + myProcessModule.ModuleName + "'s base address is: " + myProcessModule.BaseAddress);
//Console.WriteLine("For " + myProcessModule.ModuleName + " Entry point address is: " + myProcessModule.EntryPointAddress);
}
}
IntPtr Handle = Aion.Handle;
return Convert.ToInt32(gameBase);
}
//Gets the game handle ptr
public static IntPtr GetGameHandle()
{
Process Aion = Process.GetProcessesByName("aion.bin")[0];
UInt32 winBase = (UInt32)Aion.MainModule.BaseAddress.ToInt32();
//seznam vseh modulov
ProcessModuleCollection myProcessModuleCollection = Aion.Modules;
//iskani modul
ProcessModule myProcessModule;
UInt32 gameBase = 0;
for (int x = 0; x < myProcessModuleCollection.Count; x++)
{
myProcessModule = myProcessModuleCollection[x];
if (myProcessModuleCollection[x].ModuleName == "Game.dll")
{
gameBase = (UInt32)myProcessModule.BaseAddress.ToInt32();
//Console.WriteLine("The moduleName is " + myProcessModule.ModuleName);
//Console.WriteLine("The " + myProcessModule.ModuleName + "'s File Name is: " + myProcessModule.FileName);
//Console.WriteLine("The " + myProcessModule.ModuleName + "'s base address is: " + myProcessModule.BaseAddress);
//Console.WriteLine("For " + myProcessModule.ModuleName + " Entry point address is: " + myProcessModule.EntryPointAddress);
}
}
IntPtr Handle = Aion.Handle;
return Handle;
}
/*OFFSETS*/
//Current HP
static UInt32 HpAdr = 0xEB5AB0;
static int gameBaseAddress = GetGameBase();
static IntPtr Handle = GetGameHandle();
String Hp = Convert.ToString(ReadInt32(gameBaseAddress + HpAdr, Handle));
public static string SetCurrentHP()
{
var hpValue = ReadInt32(gameBaseAddress + HpAdr, Handle);
Trace.WriteLine(hpValue.ToString());
return Convert.ToString(hpValue);
//return Convert.ToString(ReadInt32(gameBaseAddress + HpAdr, Handle));
//return "WORKING";
}
//Console.WriteLine("Health: " + Convert.ToString(ReadInt32(gameBase + HpAdr, Handle)));
//Console.ReadLine();
}
}
答案 0 :(得分:1)
使用您的SetText方法确保在UI线程上进行更新。
/*STATS*/
public void stats()
{
while (botrunning == true) {
Thread.Sleep(100);
SetText(HPLabel, Memory.SetCurrentHP());
}
}
此外,也许某些东西会覆盖其他地方的内存值。就像评论中提到的人一样:
public static string SetCurrentHP()
{
var hpValue = ReadInt32(gameBaseAddress + HpAdr, Handle);
Trace.WriteLine(hpValue.ToString());
return Convert.ToString(hpValue);
}