diff --git a/worlds/jakanddaxter/agents/memory_reader.py b/worlds/jakanddaxter/agents/memory_reader.py index 493fbde39e4..9b39f18dcb9 100644 --- a/worlds/jakanddaxter/agents/memory_reader.py +++ b/worlds/jakanddaxter/agents/memory_reader.py @@ -4,7 +4,8 @@ import struct import sys from typing import ByteString, Callable import json -from PyMemoryEditor import OpenProcess, ProcessNotFoundError, ProcessIDNotExistsError, ClosedProcess +from PyMemoryEditor import OpenProcess, PyMemoryEditorError + from dataclasses import dataclass import Utils @@ -228,10 +229,8 @@ class JakAndDaxterMemoryReader: if self.connected: try: - # TODO - When PyMemoryEditor issue #15 is resolved, swap out this line for the commented one. - # self.gk_process.read_process_memory(0, bytes, 1) # Ping to see if it's alive. - OpenProcess(process_name=jak1_gk) - except (ProcessNotFoundError, ProcessIDNotExistsError, ClosedProcess): + OpenProcess(name=jak1_gk) # Ping to see if it's alive. + except PyMemoryEditorError as e: msg = (f"Error reading game memory! (Did the game crash?)\n" f"Please close all open windows and reopen the Jak and Daxter Client " f"from the Archipelago Launcher.\n" @@ -241,6 +240,7 @@ class JakAndDaxterMemoryReader: f" Then click Advanced > Open REPL.\n" f" Then close and reopen the Jak and Daxter Client from the Archipelago Launcher.") self.log_error(logger, msg) + logger.error(e) self.connected = False else: return @@ -275,10 +275,11 @@ class JakAndDaxterMemoryReader: async def connect(self): try: - self.gk_process = OpenProcess(process_name=jak1_gk) # The GOAL Kernel + self.gk_process = OpenProcess(name=jak1_gk) # The GOAL Kernel logger.debug(f"Found the gk process: {self.gk_process.pid}") - except ProcessNotFoundError: + except PyMemoryEditorError as e: self.log_error(logger, "Could not find the game process.") + logger.error(e) self.connected = False return @@ -320,7 +321,7 @@ class JakAndDaxterMemoryReader: self.connected = True else: raise Exception(memory_version_offset, sizeof_uint32) - except (ProcessNotFoundError, ProcessIDNotExistsError, ClosedProcess, Exception): + except Exception as e: if memory_version is None: msg = (f"Could not find a version number in the OpenGOAL memory structure!\n" f" Expected Version: {str(expected_memory_version)}\n" @@ -343,6 +344,7 @@ class JakAndDaxterMemoryReader: f" Click Versions and verify the latest version is marked 'Active'.\n" f" Close all launchers, games, clients, and console windows, then restart Archipelago.") self.log_error(logger, msg) + logger.error(e) self.connected = False async def print_status(self): @@ -461,7 +463,7 @@ class JakAndDaxterMemoryReader: self.finished_game = True self.log_success(logger, "Congratulations! You finished the game!") - except (ProcessNotFoundError, ProcessIDNotExistsError, ClosedProcess): + except (PyMemoryEditorError, OSError) as e: msg = (f"Error reading game memory! (Did the game crash?)\n" f"Please close all open windows and reopen the Jak and Daxter Client " f"from the Archipelago Launcher.\n" @@ -471,6 +473,7 @@ class JakAndDaxterMemoryReader: f" Then click Advanced > Open REPL.\n" f" Then close and reopen the Jak and Daxter Client from the Archipelago Launcher.") self.log_error(logger, msg) + logger.error(e) self.connected = False return self.location_outbox diff --git a/worlds/jakanddaxter/agents/repl_client.py b/worlds/jakanddaxter/agents/repl_client.py index 2a624d7f742..73f7a10bfbd 100644 --- a/worlds/jakanddaxter/agents/repl_client.py +++ b/worlds/jakanddaxter/agents/repl_client.py @@ -8,7 +8,7 @@ from dataclasses import dataclass from queue import Queue from typing import Callable -from PyMemoryEditor import OpenProcess, ProcessNotFoundError, ProcessIDNotExistsError, ClosedProcess +from PyMemoryEditor import OpenProcess, PyMemoryEditorError import asyncio from asyncio import StreamReader, StreamWriter, Lock @@ -65,8 +65,8 @@ class JakAndDaxterReplClient: # The REPL client needs the REPL/compiler process running, but that process # also needs the game running. Therefore, the REPL client needs both running. - gk_process: OpenProcess = None - goalc_process: OpenProcess = None + gk_process: OpenProcess | None = None + goalc_process: OpenProcess | None = None item_inbox: dict[int, NetworkItem] = {} inbox_index = 0 @@ -101,10 +101,8 @@ class JakAndDaxterReplClient: if self.connected: try: - # TODO - When PyMemoryEditor issue #15 is resolved, swap out this line for the commented one. - # self.gk_process.read_process_memory(0, bytes, 1) # Ping to see if it's alive. - OpenProcess(process_name=jak1_gk) - except (ProcessNotFoundError, ProcessIDNotExistsError, ClosedProcess): + OpenProcess(name=jak1_gk) + except PyMemoryEditorError as e: msg = (f"Error reading game memory! (Did the game crash?)\n" f"Please close all open windows and reopen the Jak and Daxter Client " f"from the Archipelago Launcher.\n" @@ -114,12 +112,11 @@ class JakAndDaxterReplClient: f" Then click Advanced > Open REPL.\n" f" Then close and reopen the Jak and Daxter Client from the Archipelago Launcher.") self.log_error(logger, msg) + logger.error(e) self.connected = False try: - # TODO - When PyMemoryEditor issue #15 is resolved, swap out this line for the commented one. - # self.goalc_process.read_process_memory(0, bytes, 1) # Ping to see if it's alive. - OpenProcess(process_name=jak1_goalc) - except (ProcessNotFoundError, ProcessIDNotExistsError, ClosedProcess): + OpenProcess(name=jak1_goalc) + except PyMemoryEditorError as e: msg = (f"Error sending data to compiler! (Did the compiler crash?)\n" f"Please close all open windows and reopen the Jak and Daxter Client " f"from the Archipelago Launcher.\n" @@ -129,6 +126,7 @@ class JakAndDaxterReplClient: f" Then click Advanced > Open REPL.\n" f" Then close and reopen the Jak and Daxter Client from the Archipelago Launcher.") self.log_error(logger, msg) + logger.error(e) self.connected = False else: return @@ -180,17 +178,19 @@ class JakAndDaxterReplClient: async def connect(self): try: - self.gk_process = OpenProcess(process_name=jak1_gk) # The GOAL Kernel + self.gk_process = OpenProcess(name=jak1_gk) # The GOAL Kernel logger.debug("Found the gk process: " + str(self.gk_process.pid)) - except ProcessNotFoundError: + except PyMemoryEditorError as e: self.log_error(logger, "Could not find the game process.") + logger.error(e) return try: - self.goalc_process = OpenProcess(process_name=jak1_goalc) # The GOAL Compiler and REPL + self.goalc_process = OpenProcess(name=jak1_goalc) # The GOAL Compiler and REPL logger.debug("Found the goalc process: " + str(self.goalc_process.pid)) - except ProcessNotFoundError: + except PyMemoryEditorError as e: self.log_error(logger, "Could not find the compiler process.") + logger.error(e) return try: diff --git a/worlds/jakanddaxter/client.py b/worlds/jakanddaxter/client.py index 710e0ef89d9..b76e6e70f79 100644 --- a/worlds/jakanddaxter/client.py +++ b/worlds/jakanddaxter/client.py @@ -22,7 +22,7 @@ import ModuleUpdate import Utils from CommonClient import ClientCommandProcessor, CommonContext, server_loop, gui_enabled from NetUtils import ClientStatus -from PyMemoryEditor import OpenProcess, ProcessNotFoundError +from PyMemoryEditor import OpenProcess, ProcessNotFoundError, AmbiguousProcessNameError # Jak imports from .game_id import jak1_name, jak1_gk, jak1_goalc @@ -471,17 +471,25 @@ async def run_game(ctx: JakAndDaxterContext): # These may already be running. If they are not running, try to start them. gk_running = False try: - OpenProcess(process_name=jak1_gk) # The GOAL Kernel + OpenProcess(name=jak1_gk) # The GOAL Kernel gk_running = True except ProcessNotFoundError: ctx.on_log_warn(logger, "Game not running, attempting to start.") + except AmbiguousProcessNameError: + ctx.on_log_error(logger, "Two or more instances of the game were found. " + "Please close one and restart this client.") + return goalc_running = False try: - OpenProcess(process_name=jak1_goalc) # The GOAL Compiler and REPL + OpenProcess(name=jak1_goalc) # The GOAL Compiler and REPL goalc_running = True except ProcessNotFoundError: ctx.on_log_warn(logger, "Compiler not running, attempting to start.") + except AmbiguousProcessNameError: + ctx.on_log_error(logger, "Two or more instances of the compiler were found. " + "Please close one and restart this client.") + return try: auto_detect_root_directory = JakAndDaxterWorld.settings.auto_detect_root_directory diff --git a/worlds/jakanddaxter/requirements.txt b/worlds/jakanddaxter/requirements.txt index 9ec60e8d107..5a5f9919318 100644 --- a/worlds/jakanddaxter/requirements.txt +++ b/worlds/jakanddaxter/requirements.txt @@ -1 +1 @@ -PyMemoryEditor>=1.6.0 +PyMemoryEditor>=2.0.1