- Updated bot behavior to end the game when no TP charges are left, instead of attempting to walk back to town. - Refined item processing logic in `processing_helpers.py` to use identity checks for item comparisons and improved item removal methods. - Enhanced game stats logging to include failure reasons and send Discord notifications for failed games. - Improved health management logic to trigger chicken behavior based on health percentage after rapid rejuvination. - Added error handling for item pickup failures in `pickit.py` to blacklist items that cannot be picked up. - Introduced walking fallback nodes for Countess, Andariel, Mephisto, and Baal runs in `pather.py`. - Implemented path data validation in run scripts for Countess, Andariel, Mephisto, and Baal to ensure paths are correctly defined. - Enhanced item identification and stash processes in `diablo.py` with retry logic for failures. - Updated town management to handle identification failures gracefully and log appropriate warnings. - Improved character selection logic to provide clearer logging messages. - Modified game restart logic to launch the game via PowerShell for better session handling. - Added documentation for recording paths for the Countess run and created a PowerShell script for scheduled task management.
67 lines
2.0 KiB
Python
67 lines
2.0 KiB
Python
import os, sys
|
|
from input_layer import keyboard
|
|
import subprocess
|
|
|
|
import template_finder
|
|
from utils.misc import wait, set_d2r_always_on_top
|
|
from screen import get_offset_state, grab
|
|
from ui.main_menu import MAIN_MENU_MARKERS
|
|
|
|
|
|
def process_exists(process_name):
|
|
call = 'TASKLIST', '/FI', 'imagename eq %s' % process_name
|
|
# use buildin check_output right away
|
|
output = subprocess.check_output(call).decode()
|
|
# check in last line for process name
|
|
last_line = output.strip().split('\r\n')[-1]
|
|
# because Fail message could be translated
|
|
return last_line.lower().startswith(process_name.lower())
|
|
|
|
def safe_exit(error_code=0):
|
|
kill_game()
|
|
os._exit(error_code)
|
|
|
|
def kill_game():
|
|
while process_exists("D2R.exe"):
|
|
os.system("taskkill /f /im BlizzardError.exe")
|
|
os.system("taskkill /f /im D2R.exe")
|
|
wait(1.0, 1.5)
|
|
|
|
def restart_game(d2r_path, launch_options):
|
|
kill_game()
|
|
wait(1.0, 1.5)
|
|
# Launch D2R via PowerShell in the active desktop session (fixes session 0 / service launches)
|
|
d2r_exe = os.path.join(d2r_path, "D2R.exe")
|
|
ps_script = f'$proc = Start-Process -FilePath "{d2r_exe}" -ArgumentList "{launch_options}" -WorkingDirectory "{d2r_path}" -PassThru; $proc.Id'
|
|
subprocess.Popen(
|
|
["powershell", "-NoProfile", "-WindowStyle", "Hidden", "-Command", ps_script],
|
|
creationflags=subprocess.CREATE_NO_WINDOW
|
|
)
|
|
wait(4.4, 5.5)
|
|
for _ in range(20):
|
|
keyboard.send("space")
|
|
wait(0.5, 1.0)
|
|
success = False
|
|
attempts = 0
|
|
set_d2r_always_on_top()
|
|
while not success:
|
|
success = get_offset_state()
|
|
wait(0.5, 1.0)
|
|
|
|
while not template_finder.search(MAIN_MENU_MARKERS, grab(), best_match=True).valid:
|
|
keyboard.send("space")
|
|
wait(2.0, 4.0)
|
|
attempts += 1
|
|
if attempts >= 5:
|
|
return False
|
|
return True
|
|
|
|
# For testing
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) > 1:
|
|
result = restart_game(sys.argv[1])
|
|
print(result)
|
|
else:
|
|
result = restart_game()
|
|
print(result)
|