Ở 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.
á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
Tạo 1 nút button |
Tiếp theo sẽ lấy pid để tìm handle.
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.
mở tab paint mới và dán vào
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ổ
Vậy trong nút button xử lý code của chúng ta sẽ như thế này :
Trong giao diện visual Studio bấm F5 và test ứng dụng click nào.
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);
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 :
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)); }
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)); }
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.
ở bài sau sẽ hướng dẫn về load game vào listview và xử lý các vấn đề liên quan.