Phần 2 : Hàm Click ẩn trong C# Và Xử lý đa luồng

0

Ở bài trước mình đã hướng dẫn cách check load game, bài này mình sẽ hướng dẫn sử dụng 1 hàm rất hay để dùng auto (không bị chiếm chuột) giống như bên AutoIT và AutoHotkey, mình custom lại 1 chút với tên ControlClick

Sở dĩ mình khuyên tất cả các bạn nên học lập trình auto bằng C#  là vì nó là ngôn ngữ lớn được hỗ trợ bởi MicroSoft  và nhiều thư viện hỗ trợ. riêng các bạn mới bắt tay vào học và có ý định Học nghành CNTT thì C# là ngôn ngữ giúp bạn trở thành 1 lập trình viên giỏi, và xuyên suốt quá trình học đại học bạn sẽ chạm chán với nó rất nhiều  cho đến khi Thi tốt nghiệp đại học.

1/Bắt đầu
Để click được vào cửa sổ game thì chúng ta cần tìm được handle của cửa sổ game đó và sau đó chỉ việc truyền tọa độ vào là xong
Vd1: như khi bạn trong phim Ỷ Thiên Đồ Long ký chỉ cần có trong tay Đồ Long Đao là có thể xưng bá thiên hạ.
  áp dụng thực tế trong lập trình thì  :
hanlde là  Đồ Long Đao
Xưng bá thiên hạ:  là có thể điều khiển cả thiên hạ rồi.
vd2 : bạn muốn khi bấm vào 1 nút button nó sẽ tự click vào ô kỹ năng 1 thì ta cần tìm được hanlde của cửa sổ đó và vị trí kỹ năng 1

Click vào ô kỹ năng 1 không bị chiếm chuột có khó ?
Các bạn mở giao diện Visual Studio lên vào tạo 1 button trên from2(xem lại bài 1) và nhấp đúp vào nút button để tạo sự kiện khi click.
Tạo 1 nút button

Tiếp theo sẽ lấy pid để tìm handle.
Mở taskmanager lên.
Pid của game  là 5968
Nếu như các phần mềm nhỏ chúng ta có thể dễ dàng lấy được  tọa độ kèm hanlde con của nó , nhưng đối với các loại game online , nhất là game 3D các công cụ như spy++ hoặc AutoIt Window Infor  không thể nào lấy được tọa độ 1 cách chính xác. ban đầu mình rất thất vọng vì tính năng này nhưng sau đó mình đã tìm ra cách chính xác đến 1000% 

Ví dụ ở hình dưới chỉnh độ phân giải cửa sổ là 800x600, vì kích thước này phụ hợp cho việc log nhiều account và dể quản lý.
Mình sẽ chụp màn hình lại và dùng công cụ paint để cắt toàn bộ cửa sổ game(phần màu vàng),sau đó dán vào 1 tab paint mới.
dùng Paint chụp hình và cắt sát phần viền game
mở tab paint mới và dán vào
Tab pain mới sẽ hiển thị đúng tọa độ cần click
Vậy trong code hiện giờ như sau: Hàm ControlClick để click ẩn không bị chiếm chuột, với các tham số, pid là id của cửa xổgame, x,y là tọa độ cần click trong cửa xổ
      void ControlClick(int pid, int x, int y)
        {
                IntPtr hWnd = IntPtr.Zero;
                hWnd = Process.GetProcessById(pid).MainWindowHandle;
                AutoControl.SendClickOnPosition(hWnd, x, y);
        }

Vậy trong nút button xử lý code của chúng ta sẽ như thế này :
 private void button1_Click(object sender, EventArgs e)
        {
            ControlClick(5968, 310, 577);
        }

Trong giao diện visual Studio bấm F5 và test ứng dụng click nào.
Đã click thành công và mình thêm 1 checkbox để check click được hay không
Nhưng nếu click  nhiều tọa độ  mà bị không chiếm chuột thì làm sao biết được nó đang click?
Cách đơn giản là thêm vào  dòng code  trong hàm ControlClick:
 AutoControl.BringToFront(Handle); 
hàm này để show cửa sổ khi ta thực hiện 1 thao tác click, khi nào test ổn thì ta xóa dòng đó đi hoặc dùng checkbox để check.
Code trong hàm ControlClick sẽ như sau :
        void ControlClick(int pid, int x, int y)
        {
            if (checkBox1.Checked)
            {
                IntPtr hWnd = IntPtr.Zero;
                hWnd = Process.GetProcessById(pid).MainWindowHandle;
                AutoControl.BringToFront(hWnd);
                AutoControl.SendClickOnPosition(hWnd, x, y);
            }
            else
            {
                IntPtr hWnd = IntPtr.Zero;
                hWnd = Process.GetProcessById(pid).MainWindowHandle;
                AutoControl.SendClickOnPosition(hWnd, x, y);
            }
        }

Nhấn F5 để test lại và sẽ thấy điều khác biệt.
Các bước trên vẫn còn quá đơn giản, nhưng cũng đủ để thực hiện được các thao tác click trong game, mình sẽ tạo thêm 1 ô checkbox để xử lý giao diện auto luôn nằm trên cùng (Topmost) và 1 button xử lý nhận mail trong game
thiết kế Gui Thêm checkbox và 1 button

Xem qua thao tác nhận mail trong game.
Gồm 6 thao tác :lúc mở mail[1] - lúc tắt giao diện[6]
+1 mở mail
+2,3 Trong giao diện mail có 12 dòng  cùng 1 vị trí là X , tọa độ y giãn cách mỗi dòng là 20,vậy sau khi xác định được tọa độ X,Y ở bước 2, thì sẽ xử lý Y+20 và X giữ nguyên tọa độ. và thực hiện  thao tác 2 , 3 đến 12 lần xem kẽ.
+4 chọn tất cả thư đã nhận

+5 xóa
+6 thoát
Mô phỏng các bước thao tác khi click

Trong code mình sẽ viết thêm 3  hàm đó là xử lý checkbox Topmost, Sleep, Getmail
Topmost
        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                this.TopMost = true;
                label2.Text = "Kích hoạt OnTop";
            }
            else
            {
                this.TopMost = false;
                label2.Text = "Hủy kích hoạt OnTop";
            }
        }
Sleep
  public void Sleep(double delay)
        {
            double delayTime = 0;
            while (delayTime < delay)
            {
                Thread.Sleep(TimeSpan.FromSeconds(1));
                delayTime++;
            }
        }
Tiếp theo là code xử lý nhận mail
 void GetMail(int Pid)
        {
            ControlClick(Pid, 784, 527); //1
            Sleep(0.1);
            ControlClick(Pid, 260, 195);//2
            int num = 12;//12 dòng
            int Posy = 195;//tọa độ y 
            for (int i = 0; i < num; i++)
            {
                Posy = Posy + 20; //sau mỗi lần y sẽ + thêm 20
                ControlClick(Pid, 260, Posy); //2
                ControlClick(Pid, 543, 413); //3
            }
            Sleep(0.1);
            ControlClick(Pid, 260, 453); //4
            Sleep(0.1);
            ControlClick(Pid, 324, 453); //5
            Sleep(0.1);
            ControlClick(Pid, 784, 527);//6
        }
Trong hàm xử lý button code sẽ như sau: truyền vào pid của game là 5968
    private void button2_Click(object sender, EventArgs e)
        {
            GetMail(5968));
        }

Done test thử nào


3/Xử lý đa luồng
Nhìn giao diện chạy mượt đấy nhưng mà nó chỉ thực hiện chạy ở luồng chính là trong game, còn giao diện auto bạn sẽ không thể điều khiển được, để giải quyết vấn đề này  mình  bỏ hàm Getmail trong Task.
code  :
  private void button2_Click(object sender, EventArgs e)
        {
            Task.Run(() => GetMail(5968));
        }

Vậy là auto đã xử lý các tác vụ 1 cách mượt mà. và bạn cũng có thể tự viết cho mình các hàm đăng kí chiến trường, hoạt động liên quan đến click.
Full code :
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using KAutoHelper;
using System.Threading;
using System.Threading.Tasks;

namespace AutoControlAppPC
{
    public partial class Form2 : Form
    {
        public Process[] myProcess;
        public Form2()
        {
            InitializeComponent();
        }
        #region CheckLoadGame
        public bool IsGameAvailable(string name)
        {
            myProcess = Process.GetProcessesByName(name);
            if (myProcess.Length != 0) { return true; } else { return false; }
        }
        public void CheckLoadGame(string name)
        {
            if (IsGameAvailable(name))
            {
                try
                {
                    Process[] processlist = Process.GetProcessesByName(name); // 
                    Console.WriteLine(processlist.ToString());
                    foreach (Process process in processlist) // 2
                    {
                        label1.Text = "Loa Game Thành Công";
                    }
                }
                catch (Exception)
                {
                    label1.Text = "Loa Game Thất Bại";
                }
            }
            else
            {
                label1.Text = "Không tìm thấy Game";
            }
        }
        #endregion
        private void Form2_Load(object sender, EventArgs e)
        {
            CheckLoadGame("dj2");
        }
        //Hàm chính của chúng ta để click ẩn.
        void ControlClick(int pid, int x, int y)
        {
            if (checkBox1.Checked)
            {
                IntPtr hWnd = IntPtr.Zero;
                hWnd = Process.GetProcessById(pid).MainWindowHandle;
                AutoControl.BringToFront(hWnd);
                AutoControl.SendClickOnPosition(hWnd, x, y);
            }
            else
            {
                IntPtr hWnd = IntPtr.Zero;
                hWnd = Process.GetProcessById(pid).MainWindowHandle;
                AutoControl.SendClickOnPosition(hWnd, x, y);
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            ControlClick(5968, 538, 579);
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Task.Run(() => GetMail(5968));
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                this.TopMost = true;
                label2.Text = "Kích hoạt OnTop";
            }
            else
            {
                this.TopMost = false;
                label2.Text = "Hủy kích hoạt OnTop";
            }
        }
        public void Sleep(double delay)
        {
            double delayTime = 0;
            while (delayTime < delay)
            {
                Thread.Sleep(TimeSpan.FromSeconds(1));
                delayTime++;
            }
        }
        void GetMail(int Pid)
        {
            ControlClick(Pid, 784, 527); //1
            Sleep(0.1);
            ControlClick(Pid, 260, 195);//2
            int num = 12;//12 dòng
            int Posy = 195;//tọa độ y 
            for (int i = 0; i < num; i++)
            {
                Posy = Posy + 20; //sau mỗi lần y sẽ + thêm 20
                ControlClick(Pid, 260, Posy); //2
                ControlClick(Pid, 543, 413); //3
            }
            Sleep(0.1);
            ControlClick(Pid, 260, 453); //4
            Sleep(0.1);
            ControlClick(Pid, 324, 453); //5
            Sleep(0.1);
            ControlClick(Pid, 784, 527);//6
        }
    }
}
Nếu bạn cảm thấy hay thì hãy click vào quảng cáo để ủng hộ giúp mình nhé.
ở bài sau sẽ hướng dẫn về load game vào listview và xử lý các vấn đề liên quan.

Post a Comment

0Comments
Post a Comment (0)