diff --git a/data/lua/connector_bizhawk_generic.lua b/data/lua/connector_bizhawk_generic.lua index 6c5af87e..c2e8f91c 100644 --- a/data/lua/connector_bizhawk_generic.lua +++ b/data/lua/connector_bizhawk_generic.lua @@ -121,6 +121,14 @@ Response: Expected Response Type: `HASH_RESPONSE` +- `MEMORY_SIZE` + Returns the size in bytes of the specified memory domain. + + Expected Response Type: `MEMORY_SIZE_RESPONSE` + + Additional Fields: + - `domain` (`string`): The name of the memory domain to check + - `GUARD` Checks a section of memory against `expected_data`. If the bytes starting at `address` do not match `expected_data`, the response will have `value` @@ -216,6 +224,12 @@ Response: Additional Fields: - `value` (`string`): The returned hash +- `MEMORY_SIZE_RESPONSE` + Contains the size in bytes of the specified memory domain. + + Additional Fields: + - `value` (`number`): The size of the domain in bytes + - `GUARD_RESPONSE` The result of an attempted `GUARD` request. @@ -376,6 +390,15 @@ request_handlers = { return res end, + ["MEMORY_SIZE"] = function (req) + local res = {} + + res["type"] = "MEMORY_SIZE_RESPONSE" + res["value"] = memory.getmemorydomainsize(req["domain"]) + + return res + end, + ["GUARD"] = function (req) local res = {} local expected_data = base64.decode(req["expected_data"]) diff --git a/worlds/_bizhawk/__init__.py b/worlds/_bizhawk/__init__.py index 3627f385..e7b8edc0 100644 --- a/worlds/_bizhawk/__init__.py +++ b/worlds/_bizhawk/__init__.py @@ -151,7 +151,7 @@ async def ping(ctx: BizHawkContext) -> None: async def get_hash(ctx: BizHawkContext) -> str: - """Gets the system name for the currently loaded ROM""" + """Gets the hash value of the currently loaded ROM""" res = (await send_requests(ctx, [{"type": "HASH"}]))[0] if res["type"] != "HASH_RESPONSE": @@ -160,6 +160,16 @@ async def get_hash(ctx: BizHawkContext) -> str: return res["value"] +async def get_memory_size(ctx: BizHawkContext, domain: str) -> int: + """Gets the size in bytes of the specified memory domain""" + res = (await send_requests(ctx, [{"type": "MEMORY_SIZE", "domain": domain}]))[0] + + if res["type"] != "MEMORY_SIZE_RESPONSE": + raise SyncError(f"Expected response of type MEMORY_SIZE_RESPONSE but got {res['type']}") + + return res["value"] + + async def get_system(ctx: BizHawkContext) -> str: """Gets the system name for the currently loaded ROM""" res = (await send_requests(ctx, [{"type": "SYSTEM"}]))[0] diff --git a/worlds/mm2/client.py b/worlds/mm2/client.py index aaa0813c..96c47775 100644 --- a/worlds/mm2/client.py +++ b/worlds/mm2/client.py @@ -214,10 +214,19 @@ class MegaMan2Client(BizHawkClient): last_wily: Optional[int] = None # default to wily 1 async def validate_rom(self, ctx: "BizHawkClientContext") -> bool: - from worlds._bizhawk import RequestFailedError, read + from worlds._bizhawk import RequestFailedError, read, get_memory_size from . import MM2World try: + if (await get_memory_size(ctx.bizhawk_ctx, "PRG ROM")) < 0x3FFB0: + if "pool" in ctx.command_processor.commands: + ctx.command_processor.commands.pop("pool") + if "request" in ctx.command_processor.commands: + ctx.command_processor.commands.pop("request") + if "autoheal" in ctx.command_processor.commands: + ctx.command_processor.commands.pop("autoheal") + return False + game_name, version = (await read(ctx.bizhawk_ctx, [(0x3FFB0, 21, "PRG ROM"), (0x3FFC8, 3, "PRG ROM")])) if game_name[:3] != b"MM2" or version != bytes(MM2World.world_version):