简体   繁体   中英

Threading not working properly c#

I am making a little program that will read stats from a game, like health, mana, etc... I want to make a tool in the future that will calculate statistics later on. And I came to the part that the program reads Health, but after some time the value in the label will just turn to 0 and I have to restart my program for it to show correctly again, what did I do wrong?

This is my code, in my main form:

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());
                }));

            }

        }

    }

And this is from my memory class:

public static string SetCurrentHP()
{
    return Convert.ToString(ReadInt32(gameBaseAddress + HpAdr, Handle));
    //return "WORKING";
}

Added my memory class:

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();





    }
}

Use your SetText method to make sure the update is occurring on the UI Thread.

/*STATS*/
public void stats()
{
  while (botrunning == true) {
    Thread.Sleep(100);

    SetText(HPLabel, Memory.SetCurrentHP());
  }
}

Also, perhaps something is overwriting the value in memory else where. Like someone mentioned in a comment:

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

  return Convert.ToString(hpValue);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM