fix: guard Windows-only imports for Linux compatibility (pywin32, mouse._winmouse, mss, rapidfuzz)

This commit is contained in:
Alex
2026-05-17 17:56:29 +02:00
parent 5ab9d1c68a
commit 329b7e77d9
7 changed files with 73 additions and 13 deletions

View File

@@ -250,7 +250,7 @@ dia_b_layout_bold=1129,148, 1129,148, 1129,148, 1129,148, 1129,148, 1129,148
dia_c_layout_bold=1112,503, 1112,503, 1112,503, 1112,503, 1112,503, 1112,503, 1112,503, 1112,503
; Andariel (A1 Catacombs) - placeholder, fill in real coords later
a1_andy_level3_enter=0,0
a1_andy_level4_enter=0,0,0
a1_andy_level4_enter=0,0
a1_andy_safe_dist=0,0
; Countess (A1 Forgotten Tower) - placeholder, fill in real coords later
a1_tower_level2_enter=0,0

View File

@@ -138,7 +138,6 @@ atk_len_cs_trashmobs=2.0
atk_len_diablo_deseis=5.0
atk_len_diablo_infector=4.0
atk_len_diablo_vizier=2.0
atk_len_diablo=3.0
cs_mob_detect=0
; cs_town_visits is currently broken, ignore for now
cs_town_visits=0

View File

@@ -16,7 +16,10 @@ from bnip.BNipExceptions import BNipSyntaxError
from enum import Enum
import re
from rapidfuzz.string_metric import levenshtein
try:
from rapidfuzz.string_metric import levenshtein
except ImportError:
from rapidfuzz.distance import Levenshtein as levenshtein
WHITESPACE = " \t\n\r\v\f"
DIGITS = "0123456789.-" # ! Put % back in here when ready to use percentages.

View File

@@ -2,7 +2,10 @@ from d2r_image.d2data_lookup import find_base_item_from_magic_item_text, find_pa
from d2r_image.data_models import HoveredItem, ItemQuality
from d2r_image.bnip_data import BNIP_ALIAS_STAT_PATTERNS, NTIP_ALIAS_QUALITY_MAP, PROPS_TO_SKILLID, BNIP_ALIAS_STAT_PATTERNS_NO_INTS, BNIP_ITEM_TYPE_DATA
from d2r_image.processing_data import Runeword
from rapidfuzz.string_metric import levenshtein
try:
from rapidfuzz.string_metric import levenshtein
except ImportError:
from rapidfuzz.distance import Levenshtein as levenshtein
from bnip.NTIPAliasType import NTIPAliasType as NTIP_TYPES
from bnip.NTIPAliasStat import NTIPAliasStat as NTIP_STATS
from logger import Logger

View File

@@ -1,13 +1,15 @@
import numpy as np
from mss import mss
import os
from logger import Logger
from utils.misc import WindowSpec, find_d2r_window, wait
from config import Config
import threading
import time
sct = mss()
monitor_roi = sct.monitors[0]
# Defer mss() and monitor setup until first grab() so the module can import
# on headless Linux (no X display) without crashing.
sct = None
monitor_roi = {"top": 0, "left": 0, "width": 1280, "height": 720}
found_offsets = False
monitor_x_range = None
monitor_y_range = None
@@ -72,6 +74,15 @@ def grab(force_new: bool = False) -> np.ndarray:
global monitor_roi
global cached_img
global last_grab
global sct
if sct is None:
from mss import mss as mss_factory
sct = mss_factory()
m0 = sct.monitors[0]
monitor_roi["left"] = m0["left"]
monitor_roi["top"] = m0["top"]
monitor_roi["width"] = m0["width"]
monitor_roi["height"] = m0["height"]
# with 25fps we have 40ms per frame. If we check for 20ms range to make sure we can still get each frame if we want.
with cached_img_lock:
if not force_new and cached_img is not None and last_grab is not None and (time.perf_counter() - last_grab) < 0.02:

View File

@@ -1,6 +1,14 @@
# Mostly copied from: https://github.com/patrikoss/pyclick
import mouse as _mouse
from mouse import _winmouse
import os
if os.name == 'nt':
from mouse import _winmouse
else:
# Linux stub — _winmouse is only used in _move_to() which wraps calls in os.name checks
class _winmouse:
@staticmethod
def move_to(x, y):
_mouse.move(x, y)
import pytweening
import numpy as np
import random

View File

@@ -15,14 +15,50 @@ import cv2
import os
from math import cos, sin, dist
import subprocess
from win32con import HWND_TOPMOST, SWP_NOMOVE, SWP_NOSIZE, HWND_NOTOPMOST
from win32gui import GetWindowText, SetWindowPos, EnumWindows, GetClientRect, ClientToScreen
from win32api import GetMonitorInfo, MonitorFromWindow
from win32process import GetWindowThreadProcessId
import psutil
if os.name == 'nt':
from win32con import HWND_TOPMOST, SWP_NOMOVE, SWP_NOSIZE, HWND_NOTOPMOST
from win32gui import GetWindowText, SetWindowPos, EnumWindows, GetClientRect, ClientToScreen
from win32api import GetMonitorInfo, MonitorFromWindow
from win32process import GetWindowThreadProcessId
else:
# Linux stubs — these functions are never called outside os.name == 'nt' blocks,
# but they must exist for the module to import cleanly on non-Windows systems.
HWND_TOPMOST = None
SWP_NOMOVE = None
SWP_NOSIZE = None
HWND_NOTOPMOST = None
def GetWindowText(hwnd):
return None
def SetWindowPos(hwnd, flags, x, y, w, h, extra):
pass
def EnumWindows(callback, lParam):
pass
def GetClientRect(hwnd):
return (0, 0, 0, 0)
def ClientToScreen(hwnd, pt):
return pt
def GetMonitorInfo(hwnd, info):
return None
def MonitorFromWindow(hwnd, flags):
return None
def GetWindowThreadProcessId(hwnd):
return (0, 0)
from rapidfuzz.process import extractOne
from rapidfuzz.string_metric import levenshtein
try:
from rapidfuzz.string_metric import levenshtein
except ImportError:
from rapidfuzz.distance import Levenshtein as levenshtein
def close_down_d2():
subprocess.call(["taskkill","/F","/IM","D2R.exe"], stderr=subprocess.DEVNULL)