Minecraft-Console-Client/tools/gen_entity_palette.py

112 lines
3.3 KiB
Python
Raw Permalink Normal View History

#!/usr/bin/env python3
"""
Generate an MCC EntityPalette C# file from server-generated registries.json.
The registries.json file is generated by running:
java -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports
Usage:
python3 tools/gen_entity_palette.py <registries.json> <suffix>
Example:
python3 tools/gen_entity_palette.py /tmp/mc_reports/reports/registries.json 1219
# Generates EntityPalette1219.cs
"""
import json
import re
import sys
from pathlib import Path
OUTPUT_DIR = (Path(__file__).resolve().parent.parent /
"MinecraftClient" / "Mapping" / "EntityPalettes")
ENTITY_TYPE_CS = OUTPUT_DIR.parent / "EntityType.cs"
def mc_name_to_csharp(mc_name: str) -> str:
"""Convert minecraft:snake_case to PascalCase C# enum name."""
name = mc_name.removeprefix("minecraft:")
return "".join(word.capitalize() for word in name.split("_"))
def load_known_entity_types() -> set[str]:
known = set()
if ENTITY_TYPE_CS.exists():
with open(ENTITY_TYPE_CS) as f:
for line in f:
m = re.match(r'\s+(\w+),?\s*$', line)
if m:
known.add(m.group(1))
return known
def main():
if len(sys.argv) != 3:
print(__doc__)
sys.exit(1)
registry_path = Path(sys.argv[1])
class_suffix = sys.argv[2]
if not registry_path.exists():
print(f"Error: {registry_path} not found")
sys.exit(1)
with open(registry_path) as f:
data = json.load(f)
entities_reg = data.get("minecraft:entity_type", {}).get("entries", {})
mappings = []
for entity_key, info in entities_reg.items():
pid = info["protocol_id"]
cs_name = mc_name_to_csharp(entity_key)
mappings.append((pid, cs_name))
mappings.sort(key=lambda x: x[0])
print(f"Loaded {len(mappings)} entity types from {registry_path}")
known = load_known_entity_types()
missing = [cs for _, cs in mappings if known and cs not in known]
if missing:
print(f"\nWARNING: {len(missing)} entity types not found in EntityType.cs enum:")
for cs_name in missing:
print(f" {cs_name}")
print("\nYou need to add these to EntityType.cs before the palette will compile.")
print("Insert them in alphabetical order within the enum.")
class_name = f"EntityPalette{class_suffix}"
output_path = OUTPUT_DIR / f"{class_name}.cs"
lines = [
"using System.Collections.Generic;",
"",
"namespace MinecraftClient.Mapping.EntityPalettes",
"{",
f" public class {class_name} : EntityPalette",
" {",
" private static readonly Dictionary<int, EntityType> mappings = new();",
"",
f" static {class_name}()",
" {",
]
for pid, cs_name in mappings:
lines.append(f" mappings[{pid}] = EntityType.{cs_name};")
lines += [
" }",
"",
" protected override Dictionary<int, EntityType> GetDict()",
" {",
" return mappings;",
" }",
" }",
"}",
"",
]
output_path.write_text("\n".join(lines))
print(f"Generated {output_path} with {len(mappings)} entity types")
if __name__ == "__main__":
main()