#include #include #Include #Include #include ;#include "FastFind.au3" #include #include #RequireAdmin ; ko thong bao khi thieu var co them quyen admin ghi vao bo x32 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "WinHttp.au3" #include "demem.au3" #include #include ;#include "VirtDsktLibrary01.au3" #include #include _WinAPI_SetErrorMode($SEM_FAILCRITICALERRORS Or $SEM_NOGPFAULTERRORBOX) $gamex01 = 720 ; 920 NOX $gamey01 = 530 ; 500 NOX $game_cap_x01 = 0 ; 5 $game_cap_y01 = 0 ; 35 $game_cap_x02 = $gamex01 $game_cap_y02 = $gamey01 $g_x = 0 $g_y = 0 $tab_all01 = 1 ; 1 tab = 0x2B0000 $process_autoit01 = @AutoItPID Global $procHwnd_autoit01 = _Memoryopen($process_autoit01,0x1f0fff,0) Dim $a_op_code[1999] $vtmem_autoitX = _MemVirtualAlloc(0x0, 0x2B0000*$tab_all01, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; khoi tao 1 lan duy nhat khong se bi error memory $vtmem_autoit_screenX = _MemVirtualAlloc(0x0, 0x2B0000*$tab_all01, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; khoi tao 1 lan duy nhat khong se bi error memory $vtmem_autoit_screenXcrop = _MemVirtualAlloc(0x0, 0x2B0000*$tab_all01, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) ; khoi tao 1 lan duy nhat khong se bi error memory $tCodeBuffer = ASM64_opcode01vtmem() ; khoi tao 1 lan duy nhat khong se bi error memory ; Mở sẵn DLL tống vào RAM, không để AutoIt phải tốn thời gian tìm kiếm lại Global $g_hUser32_DLL = DllOpen("user32.dll") ; dùng cho WinCapture_cs01new Global $g_hGDI32_DLL = DllOpen("gdi32.dll") ; dùng cho WinCapture_cs01new ; 2. Lấy TỌA ĐỘ GPS (Địa chỉ RAM) của hàm PrintWindow cất vào biến $g_pPrintWindow ;Local $hModule = _WinAPI_GetModuleHandle("user32.dll") ; dùng cho WinCapture_cs01new ;Global $g_pPrintWindow = _WinAPI_GetProcAddress($hModule, "PrintWindow") ; dùng cho WinCapture_cs01new ; Kiểm tra xem lấy được địa chỉ RAM chưa (Chỉ dùng để test lúc đầu) ; ConsoleWrite("Địa chỉ RAM của PrintWindow: " & $g_pPrintWindow & @CRLF) Func ASM64_opcode01vtmem($bytes0="102400") Local $tCodeBuffer = _DllStructCreate64("byte ASM["&$bytes0&"]") Return $tCodeBuffer EndFunc Func _DllStructCreate64($struct) ;align auf 16-byte adresse Local $temp = DllStructCreate($struct) Local $tempsize = DllStructGetSize($temp) + 64 Local $ptr = DllStructGetPtr($struct) Local $a1 = Mod(Number($ptr), 64) Local $temp = 0 Local $mem = _MemVirtualAlloc($ptr + $a1, $tempsize, $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) Local $a2 = Mod(Number($mem), 64) ;rest div 16 adresse = offset Local $sstruct = DllStructCreate($struct, (Number($mem) - $a2 + 64)) Return $sstruct ;auf 16 alingned pointer EndFunc ;==>_DllStructCreate64_2 $control01 = WinGetHandle("[REGEXPTITLE:\[#\] \["& "a" & "1"&"\] Diablo Immortal \[#\]]") ;$control01 = WinGetHandle("Master Bot Controller - 2 Accounts (a1 & a2)") If Not $control01 Then MsgBox(16, "Lỗi", "Không tìm thấy cửa sổ Game!") Exit EndIf ; 3. TẠO CỬA SỔ GUI ĐỂ HIỂN THỊ MAP PREVIEW Global $hGUI = GUICreate("Scaled Map 106x106", 720, 530) GUISetState(@SW_SHOW, $hGUI) ; 4. Bắt đầu GDI+ 1 lần duy nhất ở ngoài _GDIPlus_Startup() ; Khai báo biến đếm thời gian Local $hTimer, $iTimeCost $iTimeCost01add = 0 $iTimeCost02add = 0 ; 5. VÒNG LẶP CHÍNH CỦA TOOL While 1 ; Xử lý sự kiện GUI (tắt cửa sổ) Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch ; Chạy hàm Capture và Vẽ ; ---> BẮT ĐẦU BẤM GIỜ <--- $hTimer01 = TimerInit() WinCapture_cs02new($control01, $vtmem_autoit_screenX, $hGUI, 1,$game_cap_x02,$game_cap_y02,$g_x,$g_y) ; $hGUI kiêm tra ten gui ton tai ;WinCapture_cs02new($control01, $vtmem_autoit_screenX, $hGUI, 1,$game_cap_x02,$game_cap_y02) ; $hGUI kiêm tra ten gui ton tai ;WinCapture_cs01new($control01, $vtmem_autoit_screenX, $hGUI, 1,$game_cap_x02,$game_cap_y02) ; $hGUI kiêm tra ten gui ton tai $iTimeCost01 = TimerDiff($hTimer01) $hTimer02 = TimerInit() ;WinCapture_ScaleAndWrite03($control01, $vtmem_autoit_screenX, $hGUI, 1,$game_cap_x02,$game_cap_y02) ;WinCapture_ScaleAndWrite02($control01, $vtmem_autoit_screenX, $hGUI, 1) $iTimeCost02 = TimerDiff($hTimer02) ;$iTimeCost01add += Round($iTimeCost01, 2) ;$iTimeCost02add += Round($iTimeCost02, 2) $iTimeCost01add = Round($iTimeCost01, 2) $iTimeCost02add = Round($iTimeCost02, 2) $04_iScan0_check0 = _MemoryRead6401($vtmem_autoit_screenX, $procHwnd_autoit01,'byte[8]') ; type = ( byte, float, dword, char[], byte[] ... etc ) $04_iScan0_check0 = Dec(Hex($04_iScan0_check0,16)) $b_game3d01on = 1 ; Truyền vào 3 mã màu: (6,45) - (7,53) - (690,7) $b_game3d01 = asm_all_pixel04new(1, $b_game3d01on, $04_iScan0_check0, $vtmem_autoit_screenX, $game_cap_x02, $game_cap_y02, 26, 5, 5, 1, "6, 45, 040403, 7, 53, 821013, 690, 7, 472624") ; Cập nhật thời gian chạy lên thanh Title của GUI để dễ soi WinSetTitle($hGUI, "", "$b_game3d01[0]="&$b_game3d01[0] &" $iTimeCost01: " & $iTimeCost01add & " ms"&" $iTimeCost02: " & $iTimeCost02add & " ms") ; Nghỉ một chút nhường CPU Sleep(10) WEnd ; Dọn dẹp khi thoát _GDIPlus_Shutdown() _MemVirtualFree($vtmem_autoit_screenX, 0, $MEM_RELEASE) ;$WinCapture_cs01new_on = 0 Func _MemoryRead6401($ivAddress, $ahHandle, $sType = "dword", $value_type00="not_hex") If Not IsArray($ahHandle) Then SetError(1, 0, "") Return "" EndIf Local $vReadData = DllStructCreate("dword_ptr") Local $vReadData01 = DllStructCreate($sType) Local $vNumberOfBytesRead = DllStructCreate("ulong_ptr lpNumberOfBytesRead") Local $ahCall = DllCall($ahHandle[0], "bool", "ReadProcessMemory", _ "handle", $ahHandle[1], _ "dword_ptr", $ivAddress, _ "ptr", DllStructGetPtr($vReadData01), _ "ulong_ptr", DllStructGetSize($vReadData01), _ "ptr", DllStructGetPtr($vNumberOfBytesRead)) ; Nếu API đọc lỗi, trả về chuỗi rỗng "" sạch sẽ If (Not $ahCall[0]) Or (DllStructGetData($vNumberOfBytesRead, "lpNumberOfBytesRead") <> DllStructGetSize($vReadData01)) Then SetError(2, 0, "") Return "" EndIf If $value_type00 <> "Hex" Then Local $DllStructGetData_fix01 = DllStructGetData($vReadData01, 1) ; Chặn đứng việc AutoIt tự ép vùng nhớ trống/lỗi thành chữ "False" dạng String If $DllStructGetData_fix01 = False Or $DllStructGetData_fix01 = "False" Then Return "" ; Trả lại nguyên bản hàm StringRegExpReplace dọn rác huyền thoại của bạn (Không lo bị mất chữ ở đuôi) If StringInStr($sType, 'wchar') > 0 Then $DllStructGetData_fix01 = StringRegExpReplace($DllStructGetData_fix01, "[^\x20-\x7E]", "") EndIf Return $DllStructGetData_fix01 EndIf Return Hex("0x" & (DllStructGetData($vReadData01, 1))) EndFunc ;====================================================================================== ; HÀM TẠO OPCODE ASM (ĐÃ NÂNG CẤP DÙNG MẢNG - HỖ TRỢ MAX 12 CHECK HOẶC HƠN) ; FIX CỨNG TÂM 3X3 GIÚP CHỐNG BẮT NHẦM VÀ TĂNG TỐC ĐỘ! ;====================================================================================== Func ASM64_all_pixel04_3x3_12($iScan0, $iWidth, $r0, $a_mxy, $max_points) Local $op_code01 = "" ; ================================================================= ; PROLOGUE (Khởi tạo) ; ================================================================= ; push rdi | push rsi | push rbx | push rbp ; mov rsi,rcx | mov rdi,rdx | mov rbx,r8 | mov r13, 100 $op_code01 &= "57 56 53 55 48 8B F1 48 8B FA 49 8B D8 49 BD 00 01 00 00 00 00 00 00" ; ================================================================= ; VÒNG LẶP NỐI CHUỖI OPCODE TỰ ĐỘNG THEO SỐ LƯỢNG MÃ CẦN CHECK ; ================================================================= For $lp1 = 1 To $max_points ; Lấy tọa độ từ mảng StringSplit (Mảng $a_mxy tính từ index 1) Local $idx = ($lp1 - 1) * 3 Local $x0 = Number($a_mxy[$idx + 1]) Local $y0 = Number($a_mxy[$idx + 2]) Local $c0 = $a_mxy[$idx + 3] ; CHỈNH TÂM 3x3 (Ép tọa độ lùi lên góc trái trên của ô vuông 9 pixel) $x0 -= 1 $y0 -= 1 Local $iRowOffset = ($y0) * $iWidth + 1 Local $iRowOffset02 = "0x" & Hex(($iRowOffset + $x0) * 4) ; mov rax, <Địa chỉ Pixel> $op_code01 &= "48 B8 " & _ReadF("0x" & Hex($iScan0 + $iRowOffset02, 16), 0) ; mov r11, 9 (Chỉ lặp 9 pixel cho cấu trúc 3x3) $op_code01 &= "49 BB 09 00 00 00 00 00 00 00" ; mov [rdi+20], 0 (Reset biến đếm cột X) $op_code01 &= "C7 47 20 00 00 00 00" ; ----------------------------------------------------------- ; LOGIC NHẢY HÀNG (Dành riêng cho 3x3) ; ----------------------------------------------------------- Local $y_asm2 = _ReadF("0x" & Hex(($iWidth + 1) * 4, 8), 0) Local $x_asm2 = _ReadF("0x" & Hex(3 * 4, 8), 0) ; 3 Cột ngang * 4 byte ; cmp byte ptr [rdi+20], 2 (Check xem đã hết 3 cột chưa) ; jb if_pixel02xy ; add rax, $y_asm2 (Xuống hàng dưới) ; sub rax, $x_asm2 (Kéo X về đầu cột) ; mov [rdi+20], 0 $op_code01 &= "80 7F 20 02 72 17 90 90 90 90 48 05 " & $y_asm2 & " 48 2D " & $x_asm2 & " C7 47 20 00 00 00 00" ; ----------------------------------------------------------- ; CHECK DUNG SAI MÀU (SHADE COLOR) ; ----------------------------------------------------------- Local $return_c0 = ASM64_color01new($c0, $r0) Local $FF0000min = $return_c0[0], $FF0000max = $return_c0[1] Local $00FF00min = $return_c0[2], $00FF00max = $return_c0[3] Local $0000FFmin = $return_c0[4], $0000FFmax = $return_c0[5] $op_code01 &= "80 38 " & $FF0000min & " 72 44 90 90 90 90 80 38 " & $FF0000max & " 77 3B 90 90 90 90 " $op_code01 &= "80 78 01 " & $00FF00min & " 72 31 90 90 90 90 80 78 01 " & $00FF00max & " 77 27 90 90 90 90 " $op_code01 &= "80 78 02 " & $0000FFmin & " 72 1D 90 90 90 90 80 78 02 " & $0000FFmax & " 77 13 90 90 90 90" ; ----------------------------------------------------------- ; LƯU ĐỊA CHỈ NẾU TÌM THẤY & THOÁT KHỎI 9 PIXEL CHECK ; ----------------------------------------------------------- ; Lưu ra struct ở offset (8 * $lp1) $op_code01 &= "4A 89 44 2F " & Hex(8 * $lp1, 2) ; mov r11, 1 (Ép vòng lặp 9 pixel kết thúc ngay lập tức) $op_code01 &= "49 BB 01 00 00 00 00 00 00 00" ; ----------------------------------------------------------- ; TĂNG BỘ ĐẾM, QUA PIXEL KẾ TIẾP (JA loop2) ; ----------------------------------------------------------- $op_code01 &= "48 83 C0 04 83 47 20 01 49 83 EB 01 77 8C" Next ; ================================================================= ; EPILOGUE (Kết thúc, trả RAM) ; ================================================================= ; pop rbp | pop rbx | pop rsi | pop rdi | ret $op_code01 &= "5D 5B 5E 5F C3" Return StringReplace($op_code01, " ", "") EndFunc ;====================================================================================== ; HÀM GỌI BAO BỌC BÊN NGOÀI (ĐÃ FIX LỖI ĐỦ 11 THAM SỐ) ;====================================================================================== Func asm_all_pixel04new($a_opcode_num, $on=1, $iScan0_check0=0x0, $iScan0="$stream[1]", $iWidth0=999, $iHeight0=999, $r0=20, $xr0=5, $yr0=5, $count_color0=1, $xyc0="330,105,DCBB39") Local $return[13] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ; Check chốt chặn crash 1 lần If $on = 0 Or $iScan0_check0 = 0x0 Then Return $return $vtmem_ASM64_pixel01 = $vtmem_autoitX + 0x1000 ; Cắt chuỗi nạp vào mảng (Ví dụ có 12 mã màu -> Array dài 36) $xyc0 = StringReplace($xyc0, " ", "") Local $mxy = StringSplit($xyc0, ',') Local $max_points = Int($mxy[0] / 3) ; Chia 3 ra đúng số lượng mã cần check ; Chỉ tạo Opcode 1 lần duy nhất If $a_op_code[$a_opcode_num] = "" Then ; Truyền $iScan0 (RAM màn hình) vào tạo Code, ép chạy 3x3 (Bỏ qua $xr0, $yr0 của hàm gốc) $a_op_code[$a_opcode_num] = ASM64_all_pixel04_3x3_12($iScan0, $iWidth0, $r0, $mxy, $max_points) EndIf Local $op_code00 = $a_op_code[$a_opcode_num] ; Tính địa chỉ Pixel của cụm gốc (Dựa vào check đầu tiên làm mỏ neo) Local $x_min = Number($mxy[1]) Local $y_min = Number($mxy[2]) Local $iRowOffset = $y_min * $iWidth0 + 1 Local $iRowOffset02 = "0x" & Hex(($iRowOffset + $x_min) * 4) ; Chạy ASM (Sử dụng hàm run đã tối ưu _MemoryRead64) Return ASM64_all_pixel04new_run($x_min, $y_min, $tCodeBuffer, $iScan0 + $iRowOffset02, "0x" & Hex($vtmem_ASM64_pixel01, 16), 1, $op_code00, $max_points) EndFunc Func ASM64_all_pixel04new_run($x0=0, $y0=0, $tCodeBuffer0="_DllStructCreate64", $address_pixel0=0x0, $address_check0=0x0, $address_loop0=10, $op_code00="90909090", $max0=0, $view0=0 ) Local $iResult[10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] $check_color01 = 0 $op_code00 = StringReplace($op_code00, " ", "") $tCodeBuffer0.ASM = "0x"&$op_code00 _MemoryWrite64($address_check0+0x0, $procHwnd_autoit01, ptr(0),'byte[40]') ; reset value = 0 _MemoryWrite64($address_check0+0x100, $procHwnd_autoit01, ptr(0),'byte[400]') ; reset value = 0 If $view0=1 Then ClipPut( $check_color01&@CRLF&$address_loop0&@CRLF&DllStructGetPtr($tCodeBuffer0)&@CRLF&$address_pixel0&@CRLF&$address_check0 ) DllCallAddress("uint:cdecl", DllStructGetPtr($tCodeBuffer0), "ptr", $address_pixel0, "ptr", $address_check0, "int", $address_loop0) $get_data0 = _MemoryRead64($address_check0+0x10, $procHwnd_autoit01,'byte[4]', "Dec") $xy_split01num = 0 $xy_split01 = "" ; ========================================================= ; SỬA LỖI TẠI ĐÂY: Cho mảng co giãn theo biến $max0 ; (Tạo mảng có số phần tử = $max0 + 1) ; ========================================================= ; Khai báo thẳng mảng 15 phần tử (từ 0 đến 14), mặc định bằng 0 hết. ; Nhanh, gọn, đéo cần vòng lặp! Local $g_all_color01[15] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ; ========================================================= For $lp = 1 to $max0 $get_data0x = _MemoryRead64($address_check0+0x100+0x8*$lp, $procHwnd_autoit01,'byte[8]',"dec") If $get_data0x <> 0 Then $g_all_color01[$lp] = 1 $xy_split01num += 1 EndIf Next If $xy_split01num = $max0 And $max0 > 0 Then $g_all_color01[0] = 1 If $get_data0 > 0 Then $check_color01 = $get_data0 ; (Mấy dòng $iResult giữ nguyên kệ nó vì hàm chỉ return $g_all_color01) Return $g_all_color01 EndFunc Func ASM64_color01new($c0="506070",$r0=20) Local $return[10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] $FF0000 = Dec(StringMid($c0, 5, 2)) $00FF00 = Dec(StringMid($c0, 3, 2)) $0000FF = Dec(StringMid($c0, 1, 2)) $FF0000min = $FF0000-$r0 If $FF0000min < 0 Then $FF0000min = 0 $FF0000min = Hex($FF0000min,2) Else $FF0000min = Hex($FF0000min,2) EndIf $FF0000max = $FF0000+$r0 If $FF0000max > 255 Then $FF0000max = 255 $FF0000max = Hex($FF0000max,2) Else $FF0000max = Hex($FF0000max,2) EndIf $00FF00min = $00FF00-$r0 If $00FF00min < 0 Then $00FF00min = 0 $00FF00min = Hex($00FF00min,2) Else $00FF00min = Hex($00FF00min,2) EndIf $00FF00max = $00FF00+$r0 If $00FF00max > 255 Then $00FF00max = 255 $00FF00max = Hex($00FF00max,2) Else $00FF00max = Hex($00FF00max,2) EndIf $0000FFmin = $0000FF-$r0 If $0000FFmin < 0 Then $0000FFmin = 0 $0000FFmin = Hex($0000FFmin,2) Else $0000FFmin = Hex($0000FFmin,2) EndIf $0000FFmax = $0000FF+$r0 If $0000FFmax > 255 Then $0000FFmax = 255 $0000FFmax = Hex($0000FFmax,2) Else $0000FFmax = Hex($0000FFmax,2) EndIf ; "FCFBE3" ;ConsoleWrite(" ms" & @CRLF&$FF0000min&@CRLF&$FF0000max&@CRLF&$00FF00min&@CRLF&$00FF00max&@CRLF&$0000FFmin&@CRLF&$0000FFmax&@CRLF) $return[0] = $FF0000min $return[1] = $FF0000max $return[2] = $00FF00min $return[3] = $00FF00max $return[4] = $0000FFmin $return[5] = $0000FFmax Return $return EndFunc ;WinCapture_cs02new($control01, $vtmem_autoit_screenX, $hGUI, 1,$gamex01,$gamey01) ; $hGUI kiêm tra ten gui ton tai ; ==================================================================================================== ; HÀM CAPTURE TỐI ƯU SIÊU TỐC - GDI THUẦN (GETDIBITS + STRETCHBLT SCALE ~1MS) ; ==================================================================================================== Func WinCapture_cs02new($hWnd, $vtmem_autoit_screenX, $g_hGUI = 0, $scale0 = 1,$iWidth0=720,$iHeigh0=530,$g_x = 0,$g_y = 0) Local $iWidth = $iWidth0 Local $iHeight = $iHeigh0 Local $nFlags = 3 $g_x0 = $g_x $g_y0 = $g_y ; Tính kích thước sau khi Scale Local $iIW = Int($iWidth / $scale0) Local $iIH = Int($iHeight / $scale0) ; 1. LẤY IMAGE GAME VÀO MEMORY Local $hDDC = _WinAPI_GetDC($hWnd) Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC) Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight) _WinAPI_SelectObject($hCDC, $hBMP) ; ---> [SỬA LỖI TẠI ĐÂY]: Không xóa $hBMP trước khi PrintWindow (Xóa ở đây sẽ bị màn hình đen) ; _WinAPI_DeleteObject($hBMP) ; Xóa ko hiển thị hình gui nhưng vẫn có trong memory ;DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) DllCall($g_hUser32_DLL, "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) ;DllCallAddress("int", $g_pPrintWindow, "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) ; Mặc định target sẽ lấy từ DC gốc Local $hTargetDC = $hCDC Local $hTargetBMP = $hBMP ; 2. XỬ LÝ SCALE BẰNG STRETCHBLT (NẾU $scale0 <> 1) Local $hScaledDC = 0, $hScaledBMP = 0 If $scale0 <> 1 Then $hScaledDC = _WinAPI_CreateCompatibleDC($hDDC) $hScaledBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iIW, $iIH) _WinAPI_SelectObject($hScaledDC, $hScaledBMP) ; Mode 3 (COLORONCOLOR / STRETCH_DELETESCANS): Thu nhỏ cực nhanh bằng cách bỏ pixel thừa, tối ưu nhất cho AutoIt soi màu ;DllCall("gdi32.dll", "int", "SetStretchBltMode", "handle", $hScaledDC, "int", 3) DllCall($g_hGDI32_DLL, "int", "SetStretchBltMode", "handle", $hScaledDC, "int", 3) ; Co giãn ảnh từ $hCDC (720x530) sang $hScaledDC ($iIW x $iIH) _WinAPI_StretchBlt($hScaledDC, 0, 0, $iIW, $iIH, $hCDC, 0, 0, $iWidth, $iHeight, 0x00CC0020) ; 0x00CC0020 = $SRCCOPY ; Trỏ Target sang DC đã Scale $hTargetDC = $hScaledDC $hTargetBMP = $hScaledBMP EndIf ; 3. ĐỔ THẲNG PIXEL TỪ GDI VÀO BASE RAM ($vtmem_autoit_screenX) BẰNG GetDIBits If $vtmem_autoit_screenX <> 0 Then Local $tBMI = DllStructCreate("dword Size; long Width; long Height; word Planes; word BitCount; dword Compression; dword SizeImage; long XPelsPerMeter; long YPelsPerMeter; dword ClrUsed; dword ClrImportant") DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI)) DllStructSetData($tBMI, "Width", $iIW) DllStructSetData($tBMI, "Height", -$iIH) ; Dấu âm (-) ép GDI xuất kiểu Top-Down DllStructSetData($tBMI, "Planes", 1) DllStructSetData($tBMI, "BitCount", 32) DllStructSetData($tBMI, "Compression", 0) ; BI_RGB ; Lấy mảng byte từ $hTargetDC ghi thẳng trực tiếp vào con trỏ $vtmem_autoit_screenX ;DllCall("gdi32.dll", "int", "GetDIBits", "hwnd", $hTargetDC, "hwnd", $hTargetBMP, "uint", 0, "uint", $iIH, "ptr", $vtmem_autoit_screenX, "ptr", DllStructGetPtr($tBMI), "uint", 0) DllCall($g_hGDI32_DLL, "int", "GetDIBits", "hwnd", $hTargetDC, "hwnd", $hTargetBMP, "uint", 0, "uint", $iIH, "ptr", $vtmem_autoit_screenX, "ptr", DllStructGetPtr($tBMI), "uint", 0) EndIf ; 4. VẼ PREVIEW LÊN GUI (NẾU CÓ TRUYỀN $g_hGUI) If WinExists($g_hGUI) Then Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI) Local $hBmpFromRAM = _GDIPlus_BitmapCreateFromScan0($iIW, $iIH, $GDIP_PXF32ARGB, $iIW * 4, $vtmem_autoit_screenX) _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBmpFromRAM, 10, 10, $iIW, $iIH) _GDIPlus_BitmapDispose($hBmpFromRAM) _GDIPlus_GraphicsDispose($hGraphics) EndIf ; 5. CLEAN UP DC & BITMAP If $hScaledDC Then _WinAPI_DeleteDC($hScaledDC) _WinAPI_DeleteObject($hScaledBMP) EndIf ; ---> [SỬA LỖI TẠI ĐÂY]: Không xóa ở đây vì hàm WinCapture_ce01 sẽ gọi để xóa. Xóa 2 lần = Crash Bot. ; _WinAPI_DeleteDC($hCDC) ; _WinAPI_ReleaseDC($hWnd, $hDDC) ; ---> [SỬA LỖI TẠI ĐÂY]: Khai báo các biến bị thiếu để hàm trả về bộ form chuẩn 100% giống WinCapture_cs01 cũ Local $iScan0 = $vtmem_autoit_screenX ; Lấy RAM VTMEM làm Scan0 Local $tPixel = DllStructCreate("int[" & $iWidth * $iHeight & "];", $iScan0) ; Cấu trúc để bot đọc màu Local $BMP = 0, $tBitmapData = 0 ; Báo cho ce01 biết đây là GDI thuần ; ---> [SỬA LỖI TẠI ĐÂY]: Gỡ bỏ dấu ngoặc kép "" để trả về GIÁ TRỊ BIẾN thật sự. Local $stream_var[13] = [$hBMP, $iScan0, $tPixel, $BMP, $tBitmapData, $hWnd, $hDDC, $hCDC, $iWidth, $iHeight, $g_x0, $g_y0 &@CRLF& _ ""] ;$x01 = 555 ;$y01 = 394 ;$iRowOffset = $y01 * $iWidth+1 ; $iRowOffset = $iY * $iWidth + 1 ;$acolor01 = Hex(DllStructGetData($stream_var[2], 1, $iRowOffset + $x01),6) ;get pixel color ;MsgBox("","check","01 = "&$acolor01&" 02 = "&$acolor01,0) ; Local $stream_var[0] = $hBMP ; Local $stream_var[1] = $iScan0 ; Local $stream_var[2] = $tPixel ; Local $stream_var[3] = $BMP ; Local $stream_var[4] = $tBitmapData ; Local $stream_var[5] = $WinHandle ; Local $stream_var[6] = $hDDC ; Local $stream_var[7] = $hCDC ; Local $stream_var[8] = $iWidth ; Local $stream_var[9] = $iHeight ; Local $stream_var[10] = $g_x0 ; Local $stream_var[11] = $g_y0 Return $stream_var EndFunc ;WinCapture_cs01new($control01, $vtmem_autoit_screenX, $hGUI, 1,$gamex01,$gamey01) ; $hGUI kiêm tra ten gui ton tai ; ==================================================================================================== ; HÀM CAPTURE TỐI ƯU SIÊU TỐC - GDI THUẦN (GETDIBITS + STRETCHBLT SCALE ~1MS) ; ==================================================================================================== Func WinCapture_cs01new($hWnd, $vtmem_autoit_screenX, $g_hGUI = 0, $scale0 = 1,$iWidth0=720,$iHeigh0=530) Local $iWidth = $iWidth0 Local $iHeight = $iHeigh0 Local $nFlags = 3 ; Tính kích thước sau khi Scale Local $iIW = Int($iWidth / $scale0) Local $iIH = Int($iHeight / $scale0) ; 1. LẤY IMAGE GAME VÀO MEMORY Local $hDDC = _WinAPI_GetDC($hWnd) Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC) Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight) _WinAPI_SelectObject($hCDC, $hBMP) _WinAPI_DeleteObject($hBMP) ; Xóa ko hiển thị hình gui nhưng vẫn có trong memory DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) ;DllCall($g_hUser32_DLL, "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) ;DllCallAddress("int", $g_pPrintWindow, "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) ; Mặc định target sẽ lấy từ DC gốc Local $hTargetDC = $hCDC Local $hTargetBMP = $hBMP ; 2. XỬ LÝ SCALE BẰNG STRETCHBLT (NẾU $scale0 <> 1) Local $hScaledDC = 0, $hScaledBMP = 0 If $scale0 <> 1 Then $hScaledDC = _WinAPI_CreateCompatibleDC($hDDC) $hScaledBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iIW, $iIH) _WinAPI_SelectObject($hScaledDC, $hScaledBMP) ; Mode 3 (COLORONCOLOR / STRETCH_DELETESCANS): Thu nhỏ cực nhanh bằng cách bỏ pixel thừa, tối ưu nhất cho AutoIt soi màu DllCall("gdi32.dll", "int", "SetStretchBltMode", "handle", $hScaledDC, "int", 3) ;DllCall($g_hGDI32_DLL, "int", "SetStretchBltMode", "handle", $hScaledDC, "int", 3) ; Co giãn ảnh từ $hCDC (720x530) sang $hScaledDC ($iIW x $iIH) _WinAPI_StretchBlt($hScaledDC, 0, 0, $iIW, $iIH, $hCDC, 0, 0, $iWidth, $iHeight, 0x00CC0020) ; 0x00CC0020 = $SRCCOPY ; Trỏ Target sang DC đã Scale $hTargetDC = $hScaledDC $hTargetBMP = $hScaledBMP EndIf ; 3. ĐỔ THẲNG PIXEL TỪ GDI VÀO BASE RAM ($vtmem_autoit_screenX) BẰNG GetDIBits If $vtmem_autoit_screenX <> 0 Then Local $tBMI = DllStructCreate("dword Size; long Width; long Height; word Planes; word BitCount; dword Compression; dword SizeImage; long XPelsPerMeter; long YPelsPerMeter; dword ClrUsed; dword ClrImportant") DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI)) DllStructSetData($tBMI, "Width", $iIW) DllStructSetData($tBMI, "Height", -$iIH) ; Dấu âm (-) ép GDI xuất kiểu Top-Down DllStructSetData($tBMI, "Planes", 1) DllStructSetData($tBMI, "BitCount", 32) DllStructSetData($tBMI, "Compression", 0) ; BI_RGB ; Lấy mảng byte từ $hTargetDC ghi thẳng trực tiếp vào con trỏ $vtmem_autoit_screenX DllCall("gdi32.dll", "int", "GetDIBits", "hwnd", $hTargetDC, "hwnd", $hTargetBMP, "uint", 0, "uint", $iIH, "ptr", $vtmem_autoit_screenX, "ptr", DllStructGetPtr($tBMI), "uint", 0) ;DllCall($g_hGDI32_DLL, "int", "GetDIBits", "hwnd", $hTargetDC, "hwnd", $hTargetBMP, "uint", 0, "uint", $iIH, "ptr", $vtmem_autoit_screenX, "ptr", DllStructGetPtr($tBMI), "uint", 0) EndIf ; 4. VẼ PREVIEW LÊN GUI (NẾU CÓ TRUYỀN $g_hGUI) If WinExists($g_hGUI) Then Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI) Local $hBmpFromRAM = _GDIPlus_BitmapCreateFromScan0($iIW, $iIH, $GDIP_PXF32ARGB, $iIW * 4, $vtmem_autoit_screenX) _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBmpFromRAM, 10, 10, $iIW, $iIH) _GDIPlus_BitmapDispose($hBmpFromRAM) _GDIPlus_GraphicsDispose($hGraphics) EndIf ; 5. CLEAN UP DC & BITMAP If $hScaledDC Then _WinAPI_DeleteDC($hScaledDC) _WinAPI_DeleteObject($hScaledBMP) EndIf _WinAPI_DeleteDC($hCDC) _WinAPI_ReleaseDC($hWnd, $hDDC) Local $stream_var[13] = ["$hBMP", "$iScan0", "$tPixel", "$BMP", "$tBitmapData", "$hWnd", "$hDDC", "$hCDC", $iWidth, $iHeight, "$g_x0", "$g_y0" &@CRLF& _ ""] ;$x01 = 555 ;$y01 = 394 ;$iRowOffset = $y01 * $iWidth+1 ; $iRowOffset = $iY * $iWidth + 1 ;$acolor01 = Hex(DllStructGetData($stream_var[2], 1, $iRowOffset + $x01),6) ;get pixel color ;MsgBox("","check","01 = "&$acolor01&" 02 = "&$acolor01,0) ; Local $stream_var[0] = $hBMP ; Local $stream_var[1] = $iScan0 ; Local $stream_var[2] = $tPixel ; Local $stream_var[3] = $BMP ; Local $stream_var[4] = $tBitmapData ; Local $stream_var[5] = $WinHandle ; Local $stream_var[6] = $hDDC ; Local $stream_var[7] = $hCDC ; Local $stream_var[8] = $iWidth ; Local $stream_var[9] = $iHeight ; Local $stream_var[10] = $g_x0 ; Local $stream_var[11] = $g_y0 Return $stream_var EndFunc ; ==================================================================================================== ; HÀM CAPTURE TỐI ƯU SIÊU TỐC - DÙNG GDI THUẦN (GETDIBITS) ; ==================================================================================================== Func WinCapture_ScaleAndWrite03($hWnd, $vtmem_autoit_screenX, $g_hGUI = 0, $scale0 = 1,$iWidth0=720,$iHeigh0=530) Local $iWidth = $iWidth0 Local $iHeight = $iHeigh0 Local $nFlags = 3 ; 1. LẤY IMAGE GAME VÀO MEMORY Local $hDDC = _WinAPI_GetDC($hWnd) Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC) Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight) _WinAPI_SelectObject($hCDC, $hBMP) _WinAPI_DeleteObject($hBMP) ; Xóa ko hiển thị hình gui nhưng vẫn có trong memory DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) ; 2. ĐỔ THẲNG PIXEL TỪ GDI VÀO BASE RAM ($vtmem_autoit_screenX) BẰNG GetDIBits If $vtmem_autoit_screenX <> 0 Then Local $tBMI = DllStructCreate("dword Size; long Width; long Height; word Planes; word BitCount; dword Compression; dword SizeImage; long XPelsPerMeter; long YPelsPerMeter; dword ClrUsed; dword ClrImportant") DllStructSetData($tBMI, "Size", DllStructGetSize($tBMI)) DllStructSetData($tBMI, "Width", $iWidth) DllStructSetData($tBMI, "Height", -$iHeight) ; Dấu âm (-) ép GDI xuất kiểu Top-Down, ảnh không bị ngược DllStructSetData($tBMI, "Planes", 1) DllStructSetData($tBMI, "BitCount", 32) DllStructSetData($tBMI, "Compression", 0) ; BI_RGB ; Lấy mảng byte ghi thẳng trực tiếp vào con trỏ $vtmem_autoit_screenX DllCall("gdi32.dll", "int", "GetDIBits", "hwnd", $hCDC, "hwnd", $hBMP, "uint", 0, "uint", $iHeight, "ptr", $vtmem_autoit_screenX, "ptr", DllStructGetPtr($tBMI), "uint", 0) EndIf ; 3. VẼ PREVIEW LÊN GUI (NẾU CÓ TRUYỀN $g_hGUI) If WinExists($g_hGUI) Then Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI) Local $hBmpFromRAM = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $GDIP_PXF32ARGB, $iWidth * 4, $vtmem_autoit_screenX) _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBmpFromRAM, 10, 10, $iWidth, $iHeight) _GDIPlus_BitmapDispose($hBmpFromRAM) _GDIPlus_GraphicsDispose($hGraphics) EndIf ; 4. CLEAN UP DC & BITMAP _WinAPI_DeleteDC($hCDC) _WinAPI_ReleaseDC($hWnd, $hDDC) Return 1 EndFunc ; ==================================================================================================== ; HÀM CAPTURE & BỎ RESIZE (GIỮ NGUYÊN CÁC ĐOẠN KHÁC ACCORDING TO YOUR REQUEST) ; ==================================================================================================== Func WinCapture_ScaleAndWrite02($hWnd, $vtmem_autoit_screenX, $g_hGUI = 0, $scale0 = 1) ; không scale do bị chậm Local $iWidth = 720 Local $iHeight = 530 Local $nFlags = 3 ; Tính kích thước Scale giống y xì mã cũ của bạn Local $iIW = Int($iWidth / $scale0) Local $iIH = Int($iHeight / $scale0) Local $iTotalBytes = ($iIH * $iIW) * 4 ; 1. LẤY IMAGE GAME VÀO MEMORY (Giữ nguyên trò DeleteObject kinh điển của bạn) Local $hDDC = _WinAPI_GetDC($hWnd) Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC) Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight) _WinAPI_SelectObject($hCDC, $hBMP) _WinAPI_DeleteObject($hBMP) ; Xóa ko hiển thị hình gui nhưng vẫn có trong memory DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) ; Tạo GDI+ Bitmap từ hBMP đã chụp Local $BMP = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) ; Dọn dẹp DC _WinAPI_DeleteDC($hCDC) _WinAPI_ReleaseDC($hWnd, $hDDC) If Not $BMP Then Return 0 ; Gán trực tiếp $BMP cho $g_hBitmap02 thay vì gọi _GDIPlus_ImageResize Local $g_hBitmap02 = $BMP ; 3. LOCK BITS VÀ TẠO STRUCT PIXEL ĐỂ ĐẨY VÀO RAM Local $tBitmapData = _GDIPlus_BitmapLockBits($g_hBitmap02, 0, 0, $iIW, $iIH, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) Local $Scan0 = DllStructGetData($tBitmapData, "Scan0") ; Create DLL structure for all pixels chuẩn bài của bạn Local $tPixel = DllStructCreate("byte[" & $iTotalBytes & "]", $Scan0) ; 4. MOVE MEMORY VÀO BASE RAM If $vtmem_autoit_screenX <> 0 Then _WinAPI_MoveMemory($vtmem_autoit_screenX, $tPixel, $iTotalBytes) EndIf ; 5. VẼ PREVIEW LÊN GUI TRỰC TIẾP TỪ BASE ADDRESS ($vtmem_autoit_screenX) If WinExists($g_hGUI) Then Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI) ; Tạo một Bitmap MỚI TINH đọc trực tiếp từ con trỏ Base Local $hBmpFromRAM = _GDIPlus_BitmapCreateFromScan0($iIW, $iIH, $GDIP_PXF32ARGB, $iIW * 4, $vtmem_autoit_screenX) ; Vẽ cái hình bốc từ RAM đó lên GUI _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBmpFromRAM, 10, 10, $iIW, $iIH) ; Vẽ xong thì giải phóng cái bitmap tạm này _GDIPlus_BitmapDispose($hBmpFromRAM) _GDIPlus_GraphicsDispose($hGraphics) EndIf ; ClipPut($vtmem_autoit_screenX) ; 6. CLEAN UP _GDIPlus_BitmapUnlockBits($g_hBitmap02, $tBitmapData) _GDIPlus_BitmapDispose($g_hBitmap02) Return 1 EndFunc ; ==================================================================================================== ; HÀM CAPTURE & TỰ ĐỘNG SCALE BẰNG _GDIPlus_ImageResize (CHUẨN LOGIC MÃ CŨ CỦA BẠN) ; ==================================================================================================== ; Thêm tham số $scale0 vào khai báo hàm (Mặc định = 1 là giữ nguyên kích cỡ gốc) Func WinCapture_ScaleAndWrite01($hWnd, $vtmem_autoit_screenX, $g_hGUI = 0, $scale0 = 1) Local $iWidth = 720 Local $iHeight = 530 Local $nFlags = 3 ; Tính kích thước Scale giống y xì mã cũ của bạn Local $iIW = Int($iWidth / $scale0) Local $iIH = Int($iHeight / $scale0) Local $iTotalBytes = ($iIH * $iIW) * 4 ; 1. LẤY IMAGE GAME VÀO MEMORY (Giữ nguyên trò DeleteObject kinh điển của bạn) Local $hDDC = _WinAPI_GetDC($hWnd) Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC) Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight) _WinAPI_SelectObject($hCDC, $hBMP) _WinAPI_DeleteObject($hBMP) ; Xóa ko hiển thị hình gui nhưng vẫn có trong memory DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) ; Tạo GDI+ Bitmap từ hBMP đã chụp Local $BMP = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) ; Dọn dẹp DC _WinAPI_DeleteDC($hCDC) _WinAPI_ReleaseDC($hWnd, $hDDC) If Not $BMP Then Return 0 ; 2. SCALE IMAGE BẰNG HÀM NATIVE CỦA AUTOIT ; Nếu $scale0 = 1 thì bản chất nó resize bằng đúng kích thước cũ Local $g_hBitmap02 = _GDIPlus_ImageResize($BMP, $iIW, $iIH) _GDIPlus_BitmapDispose($BMP) ; Xóa bản gốc 720x530 cho nhẹ RAM ; 3. LOCK BITS VÀ TẠO STRUCT PIXEL ĐỂ ĐẨY VÀO RAM Local $tBitmapData = _GDIPlus_BitmapLockBits($g_hBitmap02, 0, 0, $iIW, $iIH, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) Local $Scan0 = DllStructGetData($tBitmapData, "Scan0") ; Create DLL structure for all pixels chuẩn bài của bạn Local $tPixel = DllStructCreate("byte[" & $iTotalBytes & "]", $Scan0) ; 4. MOVE MEMORY VÀO BASE RAM If $vtmem_autoit_screenX <> 0 Then _WinAPI_MoveMemory($vtmem_autoit_screenX, $tPixel, $iTotalBytes) EndIf ; 5. VẼ PREVIEW LÊN GUI TRỰC TIẾP TỪ BASE ADDRESS ($vtmem_autoit_screenX) If WinExists($g_hGUI) Then Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI) ; Tạo một Bitmap MỚI TINH đọc trực tiếp từ con trỏ Base Local $hBmpFromRAM = _GDIPlus_BitmapCreateFromScan0($iIW, $iIH, $GDIP_PXF32ARGB, $iIW * 4, $vtmem_autoit_screenX) ; Vẽ cái hình bốc từ RAM đó lên GUI _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBmpFromRAM, 10, 10, $iIW, $iIH) ; Vẽ xong thì giải phóng cái bitmap tạm này _GDIPlus_BitmapDispose($hBmpFromRAM) _GDIPlus_GraphicsDispose($hGraphics) EndIf ; ClipPut($vtmem_autoit_screenX) ; 6. CLEAN UP _GDIPlus_BitmapUnlockBits($g_hBitmap02, $tBitmapData) _GDIPlus_BitmapDispose($g_hBitmap02) Return 1 EndFunc