2016-02-19 66 views
0

我正在制作一个小程序,用于读取游戏中的统计数据,如健康,法力等......我想在未来制作一个工具,以便稍后计算统计数据。我来到程序读取健康的部分,但过了一段时间,标签中的值将变为0,并且必须重新启动我的程序才能再次正确显示,我做错了什么?线程无法正常工作c#

这是我的代码,在我的主要形式有:

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

我建议不要每秒设置一次标签文本100次......如果将睡眠改变为200ms会发生什么? –

+0

应该是100而不是10,我的不好,是什么导致它发生故障? – mheonyae

+0

那么它可能会堆放事件消息。 –

回答

1

使用您的SetText方法来确保更新发生在UI线程上。

​​

此外,也许有什么东西会覆盖内存中的值,否则在哪里。就像有人在评论中提到的那样:

public static string SetCurrentHP() 
{ 
    var hpValue = ReadInt32(gameBaseAddress + HpAdr, Handle); 
    Trace.WriteLine(hpValue.ToString()); 

    return Convert.ToString(hpValue); 
} 
+0

是的迹线显示其0,但我不明白如何......它不应该是.. – mheonyae