#!/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 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 mappings = new();", "", f" static {class_name}()", " {", ] for pid, cs_name in mappings: lines.append(f" mappings[{pid}] = EntityType.{cs_name};") lines += [ " }", "", " protected override Dictionary GetDict()", " {", " return mappings;", " }", " }", "}", "", ] output_path.write_text("\n".join(lines)) print(f"Generated {output_path} with {len(mappings)} entity types") if __name__ == "__main__": main()