2016-02-19 107 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