using System; using System.Collections.Generic; using System.Linq; using System.IO; namespace MinecraftClient.Mapping.BlockPalettes { /// /// Generator for MCC Block Palette mappings /// public static class BlockPaletteGenerator { /// /// Generate mapping from Minecraft blocks.jsom /// /// path to blocks.json /// output path for blocks.cs /// output path for material.cs /// java -cp minecraft_server.jar net.minecraft.data.Main --reports /// state => block name mappings public static void JsonToClass(string blocksJsonFile, string outputClass, string outputEnum = null) { HashSet knownStates = new HashSet(); Dictionary> blocks = new Dictionary>(); Json.JSONData palette = Json.ParseJson(File.ReadAllText(blocksJsonFile)); foreach (KeyValuePair item in palette.Properties) { //minecraft:item_name => ItemName string blockType = String.Concat( item.Key.Replace("minecraft:", "") .Split('_') .Select(word => char.ToUpper(word[0]) + word.Substring(1)) ); if (blocks.ContainsKey(blockType)) throw new InvalidDataException("Duplicate block type " + blockType + "!?"); blocks[blockType] = new HashSet(); foreach (Json.JSONData state in item.Value.Properties["states"].DataArray) { int id = int.Parse(state.Properties["id"].StringValue); if (knownStates.Contains(id)) throw new InvalidDataException("Duplicate state id " + id + "!?"); knownStates.Add(id); blocks[blockType].Add(id); } } HashSet materials = new HashSet(); List outFile = new List(); outFile.AddRange(new[] { "using System;", "using System.Collections.Generic;", "", "namespace MinecraftClient.Mapping.BlockPalettes", "{", " public class PaletteXXX : PaletteMapping", " {", " private static Dictionary materials = new Dictionary();", "", " static PaletteXXX()", " {", }); foreach (KeyValuePair> blockType in blocks) { if (blockType.Value.Count > 0) { List idList = blockType.Value.ToList(); string materialName = blockType.Key; materials.Add(materialName); if (idList.Count > 1) { idList.Sort(); Queue idQueue = new Queue(idList); while (idQueue.Count > 0) { int startValue = idQueue.Dequeue(); int endValue = startValue; while (idQueue.Count > 0 && idQueue.Peek() == endValue + 1) endValue = idQueue.Dequeue(); if (endValue > startValue) { outFile.Add(" for (int i = " + startValue + "; i <= " + endValue + "; i++)"); outFile.Add(" materials[i] = Material." + materialName + ";"); } else outFile.Add(" materials[" + startValue + "] = Material." + materialName + ";"); } } else outFile.Add(" materials[" + idList[0] + "] = Material." + materialName + ";"); } else throw new InvalidDataException("No state id for block type " + blockType.Key + "!?"); } outFile.AddRange(new[] { " }", "", " protected override Dictionary GetDict()", " {", " return materials;", " }", " }", "}" }); File.WriteAllLines(outputClass, outFile); if (outputEnum != null) { outFile = new List(); outFile.AddRange(new[] { "namespace MinecraftClient.Mapping", "{", " public enum Material", " {" }); foreach (string material in materials) outFile.Add(" " + material + ","); outFile.AddRange(new[] { " }", "}" }); File.WriteAllLines(outputEnum, outFile); } } } }