mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
SoE: implement everything else
This commit is contained in:
52
worlds/soe/Patch.py
Normal file
52
worlds/soe/Patch.py
Normal file
@@ -0,0 +1,52 @@
|
||||
import bsdiff4
|
||||
import yaml
|
||||
from typing import Optional
|
||||
import Utils
|
||||
|
||||
|
||||
def read_rom(stream, strip_header=True) -> bytes:
|
||||
"""Reads rom into bytearray and optionally strips off any smc header"""
|
||||
data = stream.read()
|
||||
if strip_header and len(data) % 0x400 == 0x200:
|
||||
return data[0x200:]
|
||||
return data
|
||||
|
||||
|
||||
def generate_yaml(patch: bytes, metadata: Optional[dict] = None) -> bytes:
|
||||
patch = yaml.dump({"meta": metadata,
|
||||
"patch": patch,
|
||||
"game": "Secret of Evermore",
|
||||
# minimum version of patch system expected for patching to be successful
|
||||
"compatible_version": 1,
|
||||
"version": 1})
|
||||
return patch.encode(encoding="utf-8-sig")
|
||||
|
||||
|
||||
def generate_patch(vanilla_file, randomized_file, metadata: Optional[dict] = None) -> bytes:
|
||||
with open(vanilla_file, "rb") as f:
|
||||
vanilla = read_rom(f)
|
||||
with open(randomized_file, "rb") as f:
|
||||
randomized = read_rom(f)
|
||||
if metadata is None:
|
||||
metadata = {}
|
||||
patch = bsdiff4.diff(vanilla, randomized)
|
||||
return generate_yaml(patch, metadata)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import argparse
|
||||
import pathlib
|
||||
import lzma
|
||||
parser = argparse.ArgumentParser(description='Apply patch to Secret of Evermore.')
|
||||
parser.add_argument('patch', type=pathlib.Path, help='path to .absoe file')
|
||||
args = parser.parse_args()
|
||||
with open(args.patch, "rb") as f:
|
||||
data = Utils.parse_yaml(lzma.decompress(f.read()).decode("utf-8-sig"))
|
||||
if data['game'] != 'Secret of Evermore':
|
||||
raise RuntimeError('Patch is not for Secret of Evermore')
|
||||
with open(Utils.get_options()['soe_options']['rom_file'], 'rb') as f:
|
||||
vanilla_data = read_rom(f)
|
||||
patched_data = bsdiff4.patch(vanilla_data, data["patch"])
|
||||
with open(args.patch.parent / (args.patch.stem + '.sfc'), 'wb') as f:
|
||||
f.write(patched_data)
|
||||
|
||||
Reference in New Issue
Block a user