62 lines
1.8 KiB
Python
62 lines
1.8 KiB
Python
import bsdiff4
|
|
import yaml
|
|
from typing import Optional
|
|
import Utils
|
|
from Patch import APDeltaPatch
|
|
|
|
|
|
USHASH = '6e9c94511d04fac6e0a1e582c170be3a'
|
|
|
|
|
|
class SoEDeltaPatch(APDeltaPatch):
|
|
hash = USHASH
|
|
game = "Secret of Evermore"
|
|
patch_file_ending = ".apsoe"
|
|
|
|
@classmethod
|
|
def get_source_data(cls) -> bytes:
|
|
with open(get_base_rom_path(), "rb") as stream:
|
|
return read_rom(stream)
|
|
|
|
|
|
def get_base_rom_path() -> str:
|
|
return Utils.get_options()['soe_options']['rom_file']
|
|
|
|
|
|
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:
|
|
"""Generate old (<4) apbp format yaml"""
|
|
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": 2,
|
|
"base_checksum": USHASH})
|
|
return patch.encode(encoding="utf-8-sig")
|
|
|
|
|
|
def generate_patch(vanilla_file, randomized_file, metadata: Optional[dict] = None) -> bytes:
|
|
"""Generate old (<4) apbp format patch data. Run through lzma to get a complete apbp file."""
|
|
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 sys
|
|
print('Please use ../../Patch.py', file=sys.stderr)
|
|
sys.exit(1)
|