Source code for version_definitions.definition_manager

from __future__ import annotations

import json
import numpy
import os

import re
from typing import Union

from api.paths import DEFINITIONS_DIR


[docs]class DefinitionManager: """ Handles loading block definitions and mapping them to our internal definitions """ SUPPORTED_FORMAT = 0
[docs] @staticmethod def properties_to_string(props: dict) -> str: """ Converts a dictionary of blockstate properties to a string :param props: The dictionary of blockstate properties :return: The string version of the supplied blockstate properties """ result = [] for key, value in props.items(): result.append("{}={}".format(key, value)) return ",".join(result)
[docs] @staticmethod def string_to_properties(string: str) -> dict: """ Converts a string into a dictionary of blockstate properties :param string: The string of blockstate properties :return: The resulting dictionary of blockstate properties """ result = {} split = string.split(",") for pair in split: key, value = pair.split("=") if not value.isdigit() and not value.isalpha(): value = float(value) elif not value.isalpha(): value = int(value) result[key] = value return result
@property def special_blocks(self): return self._special_blocks def __init__(self, definitions_to_build: str): self.blocks = {} self._definitions = {} self._special_blocks = set() fp = open(os.path.join(DEFINITIONS_DIR, "internal", "blocks.json")) self.defs_internal = json.load(fp) fp.close() if self.defs_internal.get("__format__", -1) != self.SUPPORTED_FORMAT: raise AssertionError( "Internal block definitions format mismatches the supported format version" ) del self.defs_internal["__format__"] self._definitions["internal"] = {"minecraft": self.defs_internal["minecraft"]} if not os.path.exists( "{}.json".format( os.path.join(DEFINITIONS_DIR, definitions_to_build, "blocks") ) ): raise FileNotFoundError() fp = open( "{}.json".format( os.path.join(DEFINITIONS_DIR, definitions_to_build, "blocks") ), "r", ) defs = json.load(fp) fp.close() if defs.get("__format__", -1) != self.SUPPORTED_FORMAT: raise AssertionError( f"{definitions_to_build} block definitions format mismatches the supported format version" ) del defs["__format__"] self._definitions[definitions_to_build] = {"minecraft": {}} for resource_location in defs: for base_block in defs[resource_location]: if base_block not in defs[resource_location]: self._definitions[definitions_to_build]["minecraft"][ base_block ] = {} if ( "map_to" in defs[resource_location][base_block] and "id" in defs[resource_location][base_block] ): map_to = defs[resource_location][base_block]["map_to"] block_idenifier = defs[resource_location][base_block]["id"] self.blocks[map_to[map_to.index(":") + 1 :]] = block_idenifier else: for blockstate in defs[resource_location][base_block]: block_id = defs[resource_location][base_block][blockstate].get( "id", [-1, -1] ) map_to = defs[resource_location][base_block][blockstate].get( "map_to", "internal:minecraft:unknown" ) self.blocks[map_to[map_to.index(":") + 1 :]] = block_id
[docs] def get_internal_block( self, resource_location="minecraft", basename="air", properties=None ) -> dict: """ Returns the versioned definition for the supplied internal block. Internal definitions are loosely based off of the flattened blockstates of Java Edition 1.13 :param resource_location: The resource location to look in :param basename: The basename of the block :param properties: The properties of the blockstate :return: A dictionary representing the versioned definition of the internal block """ if properties: properties = self.properties_to_string(properties) if resource_location in self._definitions["internal"]: if basename in self._definitions["internal"][resource_location]: if ( properties and properties in self._definitions["internal"][resource_location][basename] ): return self._definitions["internal"][resource_location][basename][ properties ] elif properties: raise KeyError( "No blockstate definition found for '{}:{}[{}]'".format( resource_location, basename, properties ) ) else: return self._definitions["internal"][resource_location][basename] raise KeyError( "No blockstate definition found for '{}:{}'".format( resource_location, basename ) )
[docs] def get_block_from_definition( self, block: Union[str, list, tuple], default=None ) -> str: """ Returns the internal name of the supplied versioned block :param block: The versioned block :param default: The default value to return if missing :return: The internal name that is mapped to the versioned block """ if isinstance(block, tuple): block = list(block) if (isinstance(block, str) and ":" in block) or isinstance(block, list): try: return list(self.blocks.keys())[list(self.blocks.values()).index(block)] except ValueError: return default else: raise KeyError()
if __name__ == "__main__": ver = input("Version definitions to build: ") proto = DefinitionManager(ver) matcher = re.compile(r"^(.)+:(.)+$") while True: user_input = input(">> ").lower() if user_input == "quit" or user_input == "q": break elif user_input.startswith("block"): print( "Result: {}".format( proto.blocks.get( user_input.replace("block ", ""), "minecraft:unknown" ) ) ) elif user_input.startswith("reverse"): user_input = user_input.replace("reverse ", "") result = None if matcher.match(user_input): for key, value in proto.blocks.items(): if user_input == value: result = key break else: print(user_input.replace(" ", "")[1:-1]) numerical_ids = map(int, user_input.replace(" ", "")[1:-1].split(",")) numerical_ids = [i for i in numerical_ids] result = None for key, value in proto.blocks.items(): if value == numerical_ids: result = key break if result: print("Result: {}".format(result)) else: print("Block not found") elif user_input.startswith("load"): user_input = user_input.replace("load ", "") proto = DefinitionManager(user_input) print("Successfully loaded '{}' definitions".format(user_input)) elif user_input == "list": print(proto.blocks) else: print("==== Help ====") print( "block <internal name>: Looks up a block from it's internal mapping name (internal -> version)" ) print( "reverse <versioned name>: Looks up a block from it's internal mapping value (version -> internal)" ) print("list: Lists all blocks in the current mapping") print( "load <version>: Loads the specified version of block definitions.rst" )