[C#] KeyPresser for non-bot server

07/29/2020 16:12 confict#1
Hi guys,

I've been developing my own keypresser for a non-bot server to auto buff chars while being AFK.

Right now it works kind of decent, and most features are implemented, however I'm running into the following problem.

[Only registered and activated users can see links. Click Here To Register...]

As you can see on the interface above there is a worker list. I've built it so when I press the "Start" button, a thread will be created for every item in the worker list. However, it keeps happening that threads are overlapping. I've found some possible solutions, but nothing really seems to fit my problem.

The threads are set up like this:

Button_click event:
Code:
        private void btn_Start_Click(object sender, EventArgs e)
        {
            if (btn_Start.Text == "Start")
            {
                btn_Start.Text = "Stop";
                LockGUI();
                foreach(ListViewItem lvitem in lv_Worker.Items)
                {
                    string skillname = lvitem.Text;
                    int delay = Convert.ToInt32(lvitem.SubItems[1].Text);
                    delay *= 1000;
                    string targetslot = lvitem.SubItems[2].Text;
                    string bar = lvitem.SubItems[3].Text;
                    string slot = lvitem.SubItems[4].Text;
                    string targetlocation = "";
                    foreach(ListViewItem xtarget in lv_PartyLoc.Items)
                    {
                        if(xtarget.Text == targetslot)
                        {
                            targetlocation = xtarget.SubItems[1].Text;
                        }
                    }
                    string[] targetArray = targetlocation.Split(',');
                    Point targetLoc = new Point(Convert.ToInt32(targetArray[0]), Convert.ToInt32(targetArray[1]));

                    Thread tWorker = new Thread(() => DoWork(bar, slot, delay, targetLoc));
                    tWorker.Name = skillname;
                    tWorker.Start();
                    WorkerList.Add(tWorker);

                }
            }
            else
            {
                btn_Start.Text = "Start";
                UnlockGUI();
                foreach(Thread worker in WorkerList)
                {
                    worker.Abort();
                    WorkerList.Remove(worker);
                }
            }
        }
The actual worker thread code is:

Code:
 public void DoWork(string bar, string slot, int delay, Point clickloc)
        {
            Random rnd = new Random();
            int startDelay = rnd.Next(200, 9000);
            Thread.Sleep(startDelay);
            TypeConverter converter = TypeDescriptor.GetConverter(typeof(WindowsInput.Native.VirtualKeyCode));
            WindowsInput.InputSimulator Typemachine = new InputSimulator();
            VirtualKeyCode kBar = (VirtualKeyCode)converter.ConvertFromString(bar);

            int i = 0;

            do
            {
                SetCursorPos(clickloc.X, clickloc.Y);
                DoMouseClick();
                DoMouseClick();

                Typemachine.Keyboard.KeyPress(kBar);
                SendKeys.SendWait(slot);
                Thread.Sleep(delay);

            } while (i == 0);
        }
As you can see, I've built the worker thread so it uses a loop and the thread sleeps as long as the user has configured it. In the beginning I've put a random integer so the threads won't start at the same time, however this hasn't fixed my problems.

By the way, I know my coding looks like shit, but I've taught myself how to code, so I've never had a teacher.

If anyone has any tips/tricks I'd like to hear them :)
08/13/2020 21:53 confict#2
Anyone?
08/14/2020 09:16 zeteris#3
Hi,

One possible way of solving this is to use queue. I would suggest You have a look at [Only registered and activated users can see links. Click Here To Register...]

Instead of manipulating cursor/keys directly in the DoWork method You should add the work to the queue like:
Code:
Queue.Add(new Work
{
	X = clickloc.X,
	Y = clickloc.Y
	Key = kBar,
	Slot = slot
});
Then just spawn another thread which processes the work queue and actually manipulates cursor/keys:
Code:
while (true)
{
	var work = Queue.Take();
	SetCursorPos(work.X, work.Y);
	DoMouseClick();
	DoMouseClick();

	Typemachine.Keyboard.KeyPress(work.Key);
	SendKeys.SendWait(work.Slot);
}
This way You can have as many threads as You like asking to manipulate cursor/keys which will be done in another thread one after another without overlapping.

I hope this helps :)
08/14/2020 12:31 confict#4
I'll look into this, thanks a lot @[Only registered and activated users can see links. Click Here To Register...]