#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ẽ ; Khai báo biến của bạn Local $game_cap_x02 = 720 Local $game_cap_y02 = 530 ; ---> BẮT ĐẦU BẤM GIỜ <--- $hTimer01 = TimerInit() ; Chụp ảnh lấy dữ liệu RAM $stream02 = WinCapture_cs04new($control01, $vtmem_autoit_screenX, 0, 1, $game_cap_x02, $game_cap_y02, $g_x, $g_y) ;$stream02 = WinCapture_cs03new($control01, $vtmem_autoit_screenX, $hGUI, 1,$game_cap_x02,$game_cap_y02,$g_x,$g_y) ; $hGUI kiêm tra ten gui ton tai Global $aPos = MouseGetPos() ;ClipPut($stream02[1]) Global $mouse_x_get_colo01 = $aPos[0] Global $mouse_y_get_colo01 = $aPos[1] ;Sleep(500) ; Sleep to give tooltip time to display WinCapture_cs04_draw_memory($stream02[1], $stream02[8], $stream02[9], $hGUI, 0, 0) ; VẼ TỪ BỘ NHỚ RA GUI (Để xem màu RAM có đúng không) $stream02[1] = $Scan0 $stream02[8] = Width $stream02[9] = Height ; Gọi hàm lấy màu điểm (553, 25) ; Lưu ý: Tham số thứ 3 lấy $vtmem_autoit_screenX (hoặc $stream02[1]), tham số thứ 4 lấy Stride $stream02[15] ;Local $sColorResult = _GetPixelColor_XY($stream02[8], $stream02[9], $stream02[1], $stream02[15], $mouse_x_get_colo01, $mouse_y_get_colo01) ; 2. Gọi hàm vẽ lại toàn bộ màu RAM ra GUI để quan sát ;_DrawFull_720x530($stream02[1], $stream02[15]) WinCapture_ce04new($stream02[3], $stream02[4], $stream02[5], $stream02[6], $stream02[7], $stream02[0], $stream02[13]) ;WinCapture_cs03new($control01, $vtmem_autoit_screenX, $hGUI, 1,$game_cap_x02,$game_cap_y02,$g_x,$g_y) ; $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 ; ==================================================================================================== ; VẼ NGUYÊN KHUNG HÌNH FULL 720x530 TỪ BỘ NHỚ RAM LÊN GUI ; ==================================================================================================== Func _DrawFull_720x530($Scan0, $stride) If $Scan0 = 0 Or $stride = 0 Then Return 0 Local $iWidth = 720 Local $iHeight = 530 ; 1. Khởi tạo Struct đọc bộ nhớ Dword cho toàn bộ 720x530 Local $iStrideDwords = Int($stride / 4) Local $iTotalDwords = $iStrideDwords * $iHeight Local $v_LargeBuffer = DllStructCreate("dword[" & $iTotalDwords & "]", $Scan0) ; 2. Tạo Handle vẽ Local $hGfx = _GDIPlus_GraphicsCreateFromHWND($hGUI) Local $iRawColor = 0 Local $hBrush = 0 ; 3. QUÉT NGUYÊN KHUNG HÌNH (0,0) ĐẾN (720, 530) For $j = 0 To $iHeight - 1 Local $iCurrentRowOffset = $j * $iStrideDwords For $i = 0 To $iWidth - 1 ; Đọc giá trị Dword thô từ RAM $iRawColor = DllStructGetData($v_LargeBuffer, 1, $iCurrentRowOffset + $i + 1) ; Ép Alpha = FF để đục 100% Local $iARGB = BitOR(0xFF000000, BitAND($iRawColor, 0x00FFFFFF)) $hBrush = _GDIPlus_BrushCreateSolid($iARGB) ; Vẽ thẳng 1 pixel lên tọa độ (i, j) của GUI _GDIPlus_GraphicsFillRect($hGfx, $i, $j, 1, 1, $hBrush) _GDIPlus_BrushDispose($hBrush) Next Next _GDIPlus_GraphicsDispose($hGfx) Return 1 EndFunc ; ==================================================================================================== ; HÀM TÌM VÀ TRẢ VỀ MÃ MÀU HEX CỦA 1 TỌA ĐỘ (X, Y) TỪ BỘ NHỚ RAM ; Khởi tạo DllStructCreate chuẩn xác 100% theo _CheckMapColor của bạn ; ==================================================================================================== Func _GetPixelColor_XY($iWidth, $iHeight, $Scan0, $stride, $x, $y) ; 1. Kiểm tra an toàn biến đầu vào If $iWidth = 0 Or $iHeight = 0 Or $Scan0 = 0 Then Return "ERR_INVALID_DATA" If $x < 0 Or $x >= $iWidth Or $y < 0 Or $y >= $iHeight Then Return "ERR_OUT_OF_BOUNDS" ; 2. Khởi tạo Struct chính xác y hệt _CheckMapColor của bạn Local $iStrideDwords = Int($stride / 4) Local $iTotalDwords = $iStrideDwords * $iHeight Local $tPixel = DllStructCreate("dword[" & $iTotalDwords & "]", $Scan0) ; 3. Tính toán vị trí Offset của tọa độ (X, Y) trong mảng 1D Local $iCurrentRowOffset = $y * $iStrideDwords Local $iPixelIndex = $iCurrentRowOffset + $x + 1 ; 4. Rút dữ liệu Dword thô và đổi sang chuỗi Hex 6 ký tự Local $iRawColor = DllStructGetData($tPixel, 1, $iPixelIndex) Local $sHexColor = Hex($iRawColor, 6) Return $sHexColor EndFunc ; ==================================================================================================== ; HÀM TEST VẼ ẢNH TỪ BỘ NHỚ RAM (DEBUG MÀU SẮC) ; Lấy dữ liệu thô từ $Scan0 và render ra GUI ; $stream02 = WinCapture_cs04new($control01, $vtmem_autoit_screenX, 0, 1, $game_cap_x02, $game_cap_y02, $g_x, $g_y) ; WinCapture_cs04_draw_memory($stream02[1], $stream02[8], $stream02[9], $hGUI, 0, 0) ; VẼ TỪ BỘ NHỚ RA GUI (Để xem màu RAM có đúng không) $stream02[1] = $Scan0 $stream02[8] = Width $stream02[9] = Height ; WinCapture_ce04new($stream02[3], $stream02[4], $stream02[5], $stream02[6], $stream02[7], $stream02[0], $stream02[13]) ; ==================================================================================================== Func WinCapture_cs04_draw_memory($Scan0, $iWidth, $iHeight, $hGUI, $x_Pos = 0, $y_Pos = 0) ; Kiểm tra xem dữ liệu có hợp lệ và GUI có tồn tại không If $Scan0 = 0 Or $iWidth <= 0 Or $iHeight <= 0 Or Not WinExists($hGUI) Then Return 0 ; Khởi tạo khung vẽ lên GUI Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ; Thiết lập thông số để đọc đúng bộ nhớ: ; 32-bit màu (ARGB) -> Mỗi pixel 4 bytes -> Stride = Width * 4 Local $iStride = $iWidth * 4 Local $GDIP_PXF32ARGB = 0x0026200A ; Tạo một bức ảnh GDI+ ĐỌC TRỰC TIẾP TỪ BỘ NHỚ RAM ($Scan0) Local $hBmpFromRAM = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight, $GDIP_PXF32ARGB, $iStride, $Scan0) ; Vẽ bức ảnh đó lên GUI _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBmpFromRAM, $x_Pos, $y_Pos, $iWidth, $iHeight) ; Dọn dẹp rác lập tức để chống tràn RAM _GDIPlus_BitmapDispose($hBmpFromRAM) _GDIPlus_GraphicsDispose($hGraphics) Return 1 EndFunc ; ==================================================================================================== ; HÀM CAPTURE & FILTER - ĐÃ FIX LỖI $gdi_plus01 = 0 ; ==================================================================================================== Func WinCapture_cs04new($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 Local $g_x0 = $g_x Local $g_y0 = $g_y Local $gdi_plus01 = 0 ; Thay đổi 1 hoặc 0 tùy thích, không lo lỗi nữa ; 1. LẤY HÌNH GAME (GDI) Local $hDDC = _WinAPI_GetDC($hWnd) Local $hCDC = _WinAPI_CreateCompatibleDC($hDDC) Local $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iWidth, $iHeight) Local $hOldBMP = _WinAPI_SelectObject($hCDC, $hBMP) DllCall("User32.dll", "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) _WinAPI_SelectObject($hCDC, $hOldBMP) ; Nhả mỏ neo ; 2. CHUYỂN GDI+ TRUNG GIAN ĐỂ ÉP MÀU HOẶC XUẤT RAM Local $BMP = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) Local $hSrc, $hBitmap, $g_hBitmap ; 3. KIỂM TRA: BẬT HAY TẮT LỌC MÀU? If $gdi_plus01 = 1 Then ; === BẬT FILTER (KÉO SÁNG THEO UZE) === Local $CA_LOG_FILTER = 2 Local $HALFTONE = 4 $g_aDefault[9] = BitOR($g_aDefault[9], $CA_LOG_FILTER) $hSrc = _GDIPlus_BitmapCreateHBITMAPFromBitmap($BMP) _GDIPlus_BitmapDispose($BMP) ; Xóa ảnh GDI+ trung gian Local $tAdjust = 0 If IsArray($g_aDefault) Then $tAdjust = _WinAPI_CreateColorAdjustment($g_aDefault[9], $g_aDefault[10], $g_aDefault[0], $g_aDefault[1], $g_aDefault[2], $g_aDefault[3], $g_aDefault[4], $g_aDefault[5], $g_aDefault[6], $g_aDefault[7], $g_aDefault[8]) EndIf $hBitmap = _WinAPI_AdjustBitmap($hSrc, -1, -1, $HALFTONE, $tAdjust) ; Tạo ra ảnh GDI+ đã lọc $g_hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap) ; Dọn rác _WinAPI_DeleteObject($hSrc) _WinAPI_DeleteObject($hBitmap) Else ; === TẮT FILTER (LẤY ẢNH GỐC) === ; Gán trực tiếp ảnh GDI+ vừa tạo ở bước 2 cho $g_hBitmap để đi tiếp $g_hBitmap = $BMP EndIf ; 4. LOCKBITS VÀ ĐỔ THẲNG VÀO RAM ASM Local $x0 = 0, $y0 = 0 Local $tBitmapData = _GDIPlus_BitmapLockBits($g_hBitmap, $x0, $y0, $iWidth, $iHeight, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) Local $width = DllStructGetData($tBitmapData, "width") Local $height = DllStructGetData($tBitmapData, "height") Local $stride = DllStructGetData($tBitmapData, "stride") Local $Scan0 = DllStructGetData($tBitmapData, "Scan0") Local $tPixel = DllStructCreate("byte[" & $height * $width * 4 & "]", $Scan0) If $vtmem_autoit_screenX <> 0 And $Scan0 <> 0 Then _WinAPI_MoveMemory($vtmem_autoit_screenX, $tPixel, $height * $width * 4) EndIf Local $wincapture00on = 1 If $width = 0 and $height = 0 and $Scan0 = 0 Then $wincapture00on = 0 EndIf ; 5. TRẢ VỀ CHO HÀM CE DỌN RÁC Local $stream_var[18] = [$hBMP, $Scan0, $tPixel, $g_hBitmap, $tBitmapData, $hWnd, $hDDC, $hCDC, $iWidth, $iHeight, $g_x0, $g_y0, "", $g_hBitmap, $wincapture00on, $stride, 0, ""] Return $stream_var EndFunc ; ==================================================================================================== ; HÀM DỌN RÁC - GIẢI PHÓNG TOÀN BỘ DC & BITMAP ; ==================================================================================================== Func WinCapture_ce04new($pBitmap, $tBitmapData, $hWnd, $hDDC, $hCDC, $hBMP, $pBitmap_Duplicate) ; 1. Mở khóa vùng nhớ của ảnh If $pBitmap <> 0 And $tBitmapData <> 0 Then _GDIPlus_BitmapUnlockBits($pBitmap, $tBitmapData) EndIf ; 2. Xóa ảnh GDI+ If $pBitmap <> 0 Then _GDIPlus_BitmapDispose($pBitmap) ; Xóa ảnh Duplicate nếu nó khác ảnh gốc (Tránh lỗi giải phóng 2 lần) If $pBitmap_Duplicate <> 0 And $pBitmap_Duplicate <> $pBitmap Then _GDIPlus_BitmapDispose($pBitmap_Duplicate) EndIf ; 3. Giải phóng DC của Game If $hWnd <> 0 And $hDDC <> 0 Then _WinAPI_ReleaseDC($hWnd, $hDDC) EndIf ; 4. Xóa DC tạm If $hCDC <> 0 Then _WinAPI_DeleteDC($hCDC) EndIf ; 5. Xóa khung ảnh HBITMAP gốc If $hBMP <> 0 Then _WinAPI_DeleteObject($hBMP) EndIf EndFunc ; ==================================================================================================== ; HÀM CAPTURE TỐI ƯU SIÊU TỐC - GDI THUẦN (ĐÃ BỔ SUNG $STRIDE VÀ MẢNG 18 PHẦN TỬ) ; ==================================================================================================== Func WinCapture_cs03new($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 Local $g_x0 = $g_x Local $g_y0 = $g_y ; 1. TÍNH KÍCH THƯỚC VÀ STRIDE SAU KHAI SCALE (32-bit ARGB = 4 bytes/pixel) Local $iIW = Int($iWidth / $scale0) Local $iIH = Int($iHeight / $scale0) Local $stride = $iIW * 4 ; <<-- THÊM TÍNH STRIDE TẠI ĐÂY ; 2. 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) ; Chụp cửa sổ game DllCall($g_hUser32_DLL, "int", "PrintWindow", "hwnd", $hWnd, "hwnd", $hCDC, "int", $nFlags) ; Mặc định target sẽ lấy từ DC gốc Local $hTargetDC = $hCDC Local $hTargetBMP = $hBMP ; 3. 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: Thu nhỏ cực nhanh bằng cách bỏ pixel thừa DllCall($g_hGDI32_DLL, "int", "SetStretchBltMode", "handle", $hScaledDC, "int", 3) ; Co giãn ảnh từ $hCDC sang $hScaledDC _WinAPI_StretchBlt($hScaledDC, 0, 0, $iIW, $iIH, $hCDC, 0, 0, $iWidth, $iHeight, 0x00CC0020) ; $SRCCOPY ; Trỏ Target sang DC đã Scale $hTargetDC = $hScaledDC $hTargetBMP = $hScaledBMP EndIf ; 4. ĐỔ THẲNG PIXEL TỪ GDI VÀO BASE RAM ($vtmem_autoit_screenX) 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 DllCall($g_hGDI32_DLL, "int", "GetDIBits", "hwnd", $hTargetDC, "hwnd", $hTargetBMP, "uint", 0, "uint", $iIH, "ptr", $vtmem_autoit_screenX, "ptr", DllStructGetPtr($tBMI), "uint", 0) EndIf ; 5. 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, $stride, $vtmem_autoit_screenX) _GDIPlus_GraphicsDrawImageRect($hGraphics, $hBmpFromRAM, 10, 10, $iIW, $iIH) _GDIPlus_BitmapDispose($hBmpFromRAM) _GDIPlus_GraphicsDispose($hGraphics) EndIf ; 6. CLEAN UP DC & BITMAP If $hScaledDC Then _WinAPI_DeleteDC($hScaledDC) _WinAPI_DeleteObject($hScaledBMP) EndIf _WinAPI_DeleteDC($hCDC) _WinAPI_ReleaseDC($hWnd, $hDDC) _WinAPI_DeleteObject($hBMP) ; 7. KHỞI TẠO BIẾN KẾT QUẢ Local $iScan0 = $vtmem_autoit_screenX Local $tPixel = DllStructCreate("int[" & $iIW * $iIH & "];", $iScan0) Local $wincapture00on = ($iScan0 <> 0 And $iIW > 0 And $iIH > 0) ? 1 : 0 ; TRẢ VỀ CHUẨN MẢNG 18 PHẦN TỬ ; Index 8, 9 : $iIW, $iIH (Chiều rộng/cao thực tế trong RAM) ; Index 14 : $wincapture00on (Trạng thái thành công) ; Index 15 : $stride (Bước nhảy bộ nhớ = $iIW * 4) Local $stream_var[18] = [0, $iScan0, $tPixel, 0, 0, $hWnd, 0, 0, $iIW, $iIH, $g_x0, $g_y0, "", 0, $wincapture00on, $stride, 0, ""] Return $stream_var EndFunc 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