Files
GaCy-GO/tools/sync_protocol_commands.py
T

45 lines
2.2 KiB
Python
Raw Normal View History

"""Generate current command names from a local PearlSR checkout; no network I/O."""
import argparse
import pathlib
import re
import subprocess
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("upstream", type=pathlib.Path)
args = parser.parse_args()
checkout = args.upstream.resolve()
revision = subprocess.check_output(
["git", "-C", str(checkout), "rev-parse", "HEAD"], text=True
).strip()
source = (checkout / "protocol/src/root.zig").read_text(encoding="utf-8")
enum = source.split("pub const CmdID = enum(u16) {", 1)[1].split("};", 1)[0]
commands = re.findall(r"\bCmd(\w+)\s*=\s*(\d+)\s*,", enum)
if not commands or len({name for name, _ in commands}) != len(commands):
raise SystemExit("Missing or duplicate upstream command names")
if len({int(value) for _, value in commands}) != len(commands):
raise SystemExit("Duplicate upstream command IDs")
lines = [
"// Code generated by tools/sync_protocol_commands.py. DO NOT EDIT.",
"// Source: https://git.xeondev.com/HonkaiSlopRail/pearl-sr protocol/src/root.zig",
"// Revision: " + revision,
"package proto", "",
'const CommandSourceRevision = "' + revision + '"', "",
"var upstreamCmdIDByName = map[string]uint16{",
]
lines += [f'\t"{name}": {value},' for name, value in commands]
lines += ["}", "", "func init() {",
"\tfor name, id := range upstreamCmdIDByName {",
"\t\tif previous, ok := CmdIDByName[name]; ok && previous != id {",
'\t\t\tpanic("command ID conflict between schema and upstream: " + name)',
"\t\t}", "\t\tCmdIDByName[name] = id", "\t\tNameByCmdID[id] = name",
"\t}", "}", ""]
root = pathlib.Path(__file__).resolve().parents[1]
base_source = (root / "protocol/proto/cmdid.go").read_text(encoding="utf-8")
base_commands = {n: int(v) for n, v in re.findall(r'^\s*"(\w+)":\s*(\d+),', base_source, re.M)}
conflicts = [n for n, v in commands if n in base_commands and base_commands[n] != int(v)]
if conflicts:
raise SystemExit("Update the base schema command IDs first: " + ", ".join(conflicts))
target = root / "protocol/proto/upstream_cmdids.go"
target.write_text("\n".join(lines), encoding="utf-8")
subprocess.run(["gofmt", "-w", str(target)], check=True)
print(f"Generated {len(commands)} commands from {revision}")