mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Full protocol adaptation for Minecraft 1.21.5: - Protocol version mapping: 770 -> 1.21.5 - Packet palette: AddExperienceOrb removed (S2C), TestInstanceBlockStatus added (S2C), SetTestBlock and TestInstanceBlockAction added (C2S) - Entity metadata palette: 5 new serializer types (OptionalLivingEntityReference, CowVariant, WolfSoundVariant, PigVariant, ChickenVariant), OPTIONAL_UUID replaced by OPTIONAL_LIVING_ENTITY_REFERENCE - Item palette: 11 new items (Bush, FireflyBush, DryShortGrass, DryTallGrass, Wildflowers, LeafLitter, CactusFlower, TestBlock, TestInstanceBlock, BlueEgg, BrownEgg) - Entity palette: Potion split into SplashPotion and LingeringPotion - Block palette: 9 new blocks (bush, cactus_flower, firefly_bush, leaf_litter, short_dry_grass, tall_dry_grass, test_block, test_instance_block, wildflowers) - Structured components: 31 new components including tooltip_display, weapon, blocks_attacks, potion_duration_scale, provides_trim_material, provides_banner_patterns, break_sound, and 25 entity variant components; unbreakable changed from Bool to Unit; instrument changed to EitherHolder Made-with: Cursor
112 lines
3.5 KiB
Python
112 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Generate Palette1214.cs from vanilla reports/blocks.json (1.21.4).
|
|
|
|
Obtain blocks.json:
|
|
java -DbundlerMainClass=net.minecraft.data.Main -jar server.jar --reports --output <dir>
|
|
-> <dir>/reports/blocks.json
|
|
|
|
Default input: /tmp/mc1214_reports/reports/blocks.json (run this script after generating reports).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import re
|
|
import sys
|
|
from collections import defaultdict
|
|
from pathlib import Path
|
|
|
|
ROOT = Path("/home/ryan/Minecraft/Minecraft-Console-Client-milutinke")
|
|
DEFAULT_JSON = Path("/tmp/mc1214_reports/reports/blocks.json")
|
|
OUT = ROOT / "MinecraftClient/Mapping/BlockPalettes/Palette1214.cs"
|
|
|
|
|
|
def snake_to_material_pascal(snake: str) -> str:
|
|
return "".join(part.capitalize() for part in snake.split("_"))
|
|
|
|
|
|
def merge_ranges(sorted_ids: list[int]) -> list[tuple[int, int]]:
|
|
if not sorted_ids:
|
|
return []
|
|
ids = sorted(sorted_ids)
|
|
out: list[tuple[int, int]] = []
|
|
s = e = ids[0]
|
|
for x in ids[1:]:
|
|
if x == e + 1:
|
|
e = x
|
|
else:
|
|
out.append((s, e))
|
|
s = e = x
|
|
out.append((s, e))
|
|
return out
|
|
|
|
|
|
def emit_palette(assignments: list[tuple[str, list[tuple[int, int]]]]) -> str:
|
|
lines = [
|
|
"using System.Collections.Generic;",
|
|
"",
|
|
"namespace MinecraftClient.Mapping.BlockPalettes",
|
|
"{",
|
|
" public class Palette1214 : BlockPalette",
|
|
" {",
|
|
" private static readonly Dictionary<int, Material> materials = new();",
|
|
"",
|
|
" static Palette1214()",
|
|
" {",
|
|
]
|
|
for mat, ranges in sorted(assignments, key=lambda x: x[0]):
|
|
for start, end in ranges:
|
|
if start == end:
|
|
lines.append(f" materials[{start}] = Material.{mat};")
|
|
else:
|
|
lines.append(f" for (int i = {start}; i <= {end}; i++)")
|
|
lines.append(f" materials[i] = Material.{mat};")
|
|
lines.extend(
|
|
[
|
|
" }",
|
|
"",
|
|
" protected override Dictionary<int, Material> GetDict()",
|
|
" {",
|
|
" return materials;",
|
|
" }",
|
|
" }",
|
|
"}",
|
|
]
|
|
)
|
|
return "\n".join(lines) + "\n"
|
|
|
|
|
|
def main() -> None:
|
|
json_path = Path(sys.argv[1]) if len(sys.argv) > 1 else DEFAULT_JSON
|
|
if not json_path.is_file():
|
|
raise SystemExit(f"Missing {json_path} — generate with server.jar --reports")
|
|
|
|
data = json.loads(json_path.read_text(encoding="utf-8"))
|
|
ids_by_material: dict[str, list[int]] = defaultdict(list)
|
|
known: set[int] = set()
|
|
max_id = -1
|
|
|
|
for key, val in data.items():
|
|
if not key.startswith("minecraft:"):
|
|
raise SystemExit(f"Unexpected block key: {key}")
|
|
name = key.split(":", 1)[1]
|
|
mat = snake_to_material_pascal(name)
|
|
for st in val["states"]:
|
|
sid = int(st["id"])
|
|
if sid in known:
|
|
raise SystemExit(f"Duplicate state id {sid}")
|
|
known.add(sid)
|
|
max_id = max(max_id, sid)
|
|
ids_by_material[mat].append(sid)
|
|
|
|
expected = max_id + 1
|
|
if len(known) != expected:
|
|
raise SystemExit(f"Non-contiguous state IDs: have {len(known)}, expected 0..{max_id}")
|
|
|
|
assignments = [(m, merge_ranges(ids)) for m, ids in ids_by_material.items()]
|
|
OUT.write_text(emit_palette(assignments), encoding="utf-8")
|
|
print(f"Wrote {OUT} ({expected} states, {len(data)} block types)")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|