Files
wow/hardware_control.py

204 lines
6.2 KiB
Python

import os
import sys
from ctypes import c_long, c_longlong, windll
import pythoncom
import win32com.client
class HardwareController:
_instance = None
_wyhkm = None
def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super(HardwareController, cls).__new__(cls)
return cls._instance
def _runtime_base_dir(self):
if getattr(sys, "frozen", False):
return os.path.dirname(sys.executable)
return os.path.dirname(os.path.abspath(__file__))
def _resolve_resource_path(self, relative_path):
if os.path.isabs(relative_path):
return relative_path if os.path.exists(relative_path) else None
candidates = []
if getattr(sys, "frozen", False):
exe_dir = os.path.dirname(sys.executable)
if exe_dir:
candidates.append(os.path.join(exe_dir, relative_path))
meipass = getattr(sys, "_MEIPASS", "")
if meipass:
candidates.append(os.path.join(meipass, relative_path))
module_dir = os.path.dirname(os.path.abspath(__file__))
candidates.append(os.path.join(module_dir, relative_path))
candidates.append(os.path.abspath(relative_path))
seen = set()
for candidate in candidates:
candidate = os.path.abspath(candidate)
if candidate in seen:
continue
seen.add(candidate)
if os.path.exists(candidate):
return candidate
return None
def _log(self, message):
print(message)
try:
log_path = os.path.join(self._runtime_base_dir(), "hardware_control.log")
with open(log_path, "a", encoding="utf-8") as f:
f.write(message + "\n")
except Exception:
pass
def __init__(self, dll_path="ddl/wyhkm.dll"):
if self._wyhkm:
return
self.dll_path = self._resolve_resource_path(dll_path)
if not self.dll_path:
self._log(f">>> [hardware_control] DLL not found: {dll_path}")
return
try:
hkmdll = windll.LoadLibrary(self.dll_path)
hkmdll.DllInstall.argtypes = (c_long, c_longlong)
if hkmdll.DllInstall(1, 2) < 0:
self._log(">>> [hardware_control] DllInstall failed")
return
self._log(f">>> [hardware_control] DllInstall ok: {self.dll_path}")
pythoncom.CoInitialize()
try:
self._wyhkm = win32com.client.Dispatch("wyp.hkm")
except Exception as e:
self._log(f">>> [hardware_control] COM Dispatch failed: {e}")
return
dev_id = self._wyhkm.SearchDevice(0x2612, 0x1701, 0)
if dev_id == -1:
self._log(">>> [hardware_control] Device not found (Index 0)")
self._wyhkm = None
return
if not self._wyhkm.Open(dev_id, 0):
self._log(">>> [hardware_control] Open device failed")
self._wyhkm = None
return
self._wyhkm.SetMode(1, 1)
self._wyhkm.SetMode(2, 1)
self._wyhkm.SetKeyInterval(30, 50)
self._wyhkm.SetMouseInterval(30, 50)
self._log(f">>> [hardware_control] Device opened and initialized: {dev_id}")
except Exception as e:
self._log(f">>> [hardware_control] Init failed: {e}")
self._wyhkm = None
def is_available(self):
if not self._wyhkm:
return False
try:
return self._wyhkm.IsOpen(0)
except Exception:
return False
def delay_rnd(self, min_ms, max_ms):
if self.is_available():
try:
self._wyhkm.DelayRnd(int(min_ms), int(max_ms))
except Exception:
pass
def key_down(self, key_str):
if self.is_available():
try:
self._wyhkm.KeyDown(str(key_str).upper())
except Exception:
pass
def key_up(self, key_str):
if self.is_available():
try:
self._wyhkm.KeyUp(str(key_str).upper())
except Exception:
pass
def key_press(self, key_str):
if self.is_available():
try:
self._wyhkm.KeyPress(str(key_str).upper())
except Exception:
pass
def keyDown(self, key_str):
self.key_down(key_str)
def keyUp(self, key_str):
self.key_up(key_str)
def press(self, key_str):
self.key_press(key_str)
def move_to(self, x, y):
if self.is_available():
try:
return bool(self._wyhkm.MoveTo(int(x), int(y)))
except Exception as e:
self._log(f">>> [hardware_control] MoveTo failed ({x}, {y}): {e}")
return False
def move_r(self, dx, dy):
if self.is_available():
try:
return bool(self._wyhkm.MoveR(int(dx), int(dy)))
except Exception as e:
self._log(f">>> [hardware_control] MoveR failed ({dx}, {dy}): {e}")
return False
def MoveR(self, dx, dy):
self.move_r(dx, dy)
def left_click(self):
if self.is_available():
try:
return bool(self._wyhkm.LeftClick())
except Exception as e:
self._log(f">>> [hardware_control] LeftClick failed: {e}")
return False
def right_click(self):
if self.is_available():
try:
return bool(self._wyhkm.RightClick())
except Exception as e:
self._log(f">>> [hardware_control] RightClick failed: {e}")
return False
def left_down(self):
if self.is_available():
try:
return bool(self._wyhkm.LeftDown())
except Exception as e:
self._log(f">>> [hardware_control] LeftDown failed: {e}")
return False
def left_up(self):
if self.is_available():
try:
return bool(self._wyhkm.LeftUp())
except Exception as e:
self._log(f">>> [hardware_control] LeftUp failed: {e}")
return False
hw_ctrl = HardwareController()