- Implementation of centralized cooperative shutdown mechanism (C10) to replace dangerous thread killing. - Consolidation of all timing signatures through jittered wait() for anti-cheat stealth (C1). - Enhanced HealthManager reactivity with smart mana potion fallback and premature panel-closing protection. - Refactored waypoint stealth logic to simulate human-like mis-aim instead of area-breaking misclicks. - Implementation of stateless 'garbage item' filtering in PickIt to eliminate ghost item loops and OCR artifacts. - Optimization of inventory management to automatically stash protected items that cannot be sold. - Suppression of individual game failure notifications on Discord; alerts now trigger on 5+ consecutive fails.
102 lines
3.4 KiB
Python
102 lines
3.4 KiB
Python
from utils.misc import wait
|
|
from screen import grab
|
|
from config import Config
|
|
from input_layer import mouse
|
|
from input_layer import keyboard
|
|
import cv2
|
|
from logger import Logger
|
|
from utils.log_rotation import safe_imwrite
|
|
import time
|
|
from ui_manager import ScreenObjects, is_visible
|
|
|
|
|
|
import threading
|
|
|
|
class DeathManager:
|
|
def __init__(self):
|
|
self._died = False
|
|
self._do_monitor = False
|
|
self._loop_delay = 0.5
|
|
self._callback = None
|
|
self._last_death_screenshot = None
|
|
self._state_lock = threading.Lock()
|
|
|
|
def get_loop_delay(self):
|
|
return self._loop_delay
|
|
|
|
def stop_monitor(self):
|
|
with self._state_lock:
|
|
self._do_monitor = False
|
|
|
|
def set_callback(self, callback):
|
|
self._callback = callback
|
|
|
|
def reset_death_flag(self):
|
|
with self._state_lock:
|
|
self._died = False
|
|
|
|
def died(self):
|
|
with self._state_lock:
|
|
return self._died
|
|
|
|
def handle_death_screen(self):
|
|
img = grab()
|
|
if is_visible(ScreenObjects.YouHaveDied, img):
|
|
Logger.warning("You have died!")
|
|
if Config().general["info_screenshots"]:
|
|
self._last_death_screenshot = "./log/screenshots/info/info_debug_death_" + time.strftime("%Y%m%d_%H%M%S") + ".png"
|
|
safe_imwrite(self._last_death_screenshot, img)
|
|
# first wait a bit to make sure health manager is done with its chicken stuff which obviously failed
|
|
if self._callback is not None:
|
|
self._callback()
|
|
# clean up key presses that might be pressed
|
|
keyboard.release(Config().char["stand_still"])
|
|
wait(0.1, 0.2)
|
|
keyboard.release(Config().char["show_items"])
|
|
wait(0.1, 0.2)
|
|
mouse.release(button="right")
|
|
wait(0.1, 0.2)
|
|
mouse.release(button="left")
|
|
wait(1, 1.5)
|
|
if is_visible(ScreenObjects.MainMenu):
|
|
# in this case chicken executed and left the game, but we were still dead.
|
|
return True
|
|
keyboard.send("esc")
|
|
with self._state_lock:
|
|
self._died = True
|
|
return True
|
|
return False
|
|
|
|
def start_monitor(self):
|
|
from utils.misc import register_stop_condition, unregister_stop_condition
|
|
register_stop_condition(threading.get_ident(), lambda: not self._do_monitor)
|
|
try:
|
|
with self._state_lock:
|
|
self._do_monitor = True
|
|
self._died = False
|
|
Logger.info("Start Death monitoring")
|
|
while True:
|
|
with self._state_lock:
|
|
if not self._do_monitor:
|
|
break
|
|
if self._died:
|
|
monitor_active = True
|
|
else:
|
|
monitor_active = False
|
|
|
|
if monitor_active:
|
|
wait(0.5)
|
|
continue
|
|
|
|
wait(self._loop_delay, self._loop_delay * 1.5) # no need to do this too frequent, when we died we are not in a hurry...
|
|
self.handle_death_screen()
|
|
finally:
|
|
unregister_stop_condition(threading.get_ident())
|
|
Logger.debug("Stop death monitoring")
|
|
|
|
# Testing:
|
|
if __name__ == "__main__":
|
|
keyboard.wait("f11")
|
|
manager = DeathManager()
|
|
manager.pickup_corpse()
|