Ejemplo n.º 1
0
def download_minecraft_server(version_id: str, target: str) -> str:
    """
    Downloads the minecraft server for version `version_id` and returns the full path.

    Args:
        version_id: the id for the version
        target: the target directory

    Returns:
        The full file path to `server.jar`

    """
    url = getVersionUrl(version_id)

    Logger.info(f"[Assets] Downloading minecraft server json at {url}")

    version = json.load(_get(url))

    Logger.info("[Assets] Downloaded version.json")
    Logger.debug(version)

    server_url = version["downloads"]["server"]["url"]
    Logger.info(f"[Assets] Starting to download server {version['id']}...")
    with _get(server_url) as server:
        download_size = server.length
        with click.progressbar(length=download_size,
                               label="Downloading server jar") as bar:
            fpath = join(target, "server.jar")
            with open(fpath, "wb+") as f:
                while chunk := server.read(16384):
                    f.write(chunk)
                    bar.update(len(chunk))
        Logger.info(f"[Assets] Downloaded {download_size / 1000000:.2f} mb")
        Logger.info(f"[Assets] Created server.jar at {fpath}")
Ejemplo n.º 2
0
def makeData(version: str) -> str:
    """
    writes all important minecraft data to a file and returns the path
    Note that this wil crash if the version is below 1.14.
    """

    version = version or get_latest_version()

    # first test if the file already exists
    directory = getVersionDir(version)
    file = join(directory, "data.json")
    if exists(file):
        with open(file) as f:
            try:
                data = json.load(f)
                if data.get("version", 0) != assets.__version__:
                    Logger.warn(
                        f"File '{file}' uses old version format {data.get('version', 0)} "
                        f"(Required {assets.__version__})")
                else:
                    Logger.debug(f"Already got data for version {version}")
                    return file
            except json.JSONDecodeError:
                pass

    contents = getDataJson(version)
    contents["version"] = assets.__version__
    with open(file, "w+") as f:
        json.dump(contents, f)
    Logger.info(f"Create data file {file}")
    return file
Ejemplo n.º 3
0
def downloadVersionManifest() -> Dict:
    """
    Downloads the minecraft version manifest and returns it parsed as a dictionary

    Format:
        {
            "latest": {
                "release": str
                "snapshot": str
            },
            "versions": [
                {
                    "id": str,
                    "type": str,
                    "url": str,
                    "time": str,
                    "releaseTime": str
                }
            ]
        }

    Returns:
        The version manifest
    """
    Logger.info("[Assets] Fetching version manifest...")
    request = _get(VERSION_MANIFEST_URL)
    manifest = json.load(request)
    Logger.info("[Assets] Successfully fetched version manifest")
    Logger.debug(manifest)
    return manifest
Ejemplo n.º 4
0
def runDataGenerator(version: str, fpath: str) -> str:
    """ Downloads the versions, runs the data generator and returns the full path to the generated data"""
    path, file = split(download_minecraft_server(version, fpath))
    Logger.info("[Assets] generating minecraft data...")

    # test if java is installed
    process = run(["java", "-version"], cwd=path)
    Logger.info("Process java version result: {}".format(process.returncode))

    completedProcess = run(
        ["java", "-cp", file, "net.minecraft.data.Main", "-all"], cwd=path)
    completedProcess.check_returncode()

    return join(path, "generated")
Ejemplo n.º 5
0
def compileMcScript(config: Config, callback: Callable = None) -> Datapack:
    """
    compiles a mcscript string and returns the generated datapack.

    Args:
        callback: a callback function that accepts the current state, the progress and the temporary object
        config: the config. Should contain the input file and the target path

    Returns:
        A datapack
    """
    steps = (
        (_parseCode, "Parsing"),
        (lambda tree: Analyzer().analyze(tree), "Analyzing context"),
        (lambda tree: get_compiler().compile(tree[0], tree[1], text, config), "Compiling"),
        (lambda ir_master: get_default_backend()(config, ir_master).generate(), "Running ir backend")
    )

    text = config.input_string

    if Logger.isEnabledFor(DEBUG):
        debug_log_text(text, "[Compile] parsing the following code: ")

    global_start_time = perf_counter()

    arg = text
    for index, step in enumerate(steps):
        if callback is not None:
            callback(step[1], index / len(steps), arg)
        start_time = perf_counter()
        try:
            arg = step[0](arg)
        except Exception as e:
            if not isinstance(e, McScriptError):
                Logger.critical(f"Internal compiler error occurred: {repr(e)}")
            raise e
        Logger.info(f"{step[1]} finished in {perf_counter() - start_time:.4f} seconds")
        if isinstance(arg, Tree):
            _debug_log_tree(arg)

    if callback is not None:
        callback("Done", 1, arg)

    Logger.info(f"Run all steps in {perf_counter() - global_start_time:.4f} seconds")

    # noinspection PyTypeChecker
    return arg
Ejemplo n.º 6
0
    def __init__(self, path: str = None):
        if Config.currentConfig:
            Config.currentConfig = self
            Logger.warning("[Config] currentConfig already exists!")
        Config.currentConfig = self
        self.path = path
        self.config = configparser.ConfigParser()

        self._input_string: Optional[str] = None
        self._world: Optional[MCWorld] = None
        self._output_dir: Optional[str] = None
        self._data_manager: DataManager = DataManager()

        self.config["main"] = {
            "release": "False",
            "minecraft_version": "",
            "name": "mcscript"
        }

        self.config["scores"] = {
            "format_string": ".exp_{block}_{index}"
        }

        # maximum scoreboard name has 16 chars so `name` must contain 12 chars at most
        self.config["scoreboards"] = {
            "main": self["main"]["name"]
        }

        self.config["storage"] = {
            "name": "main",
            "stack": "state.stack",
            "temp": "state.temp"
        }

        if path:
            if not exists(path):
                Logger.info("[Config] Write default config")
                with open(path, "w+") as f:
                    self.config.write(f)
            self.config.read(path)
            Logger.info("[Config] loaded from file")

        if not self.checkData():
            raise ValueError("Invalid values for config detected!")
Ejemplo n.º 7
0
def run_code(rcon: MCRcon, test_world: MCWorld,
             code: str) -> Tuple[Optional[int], str]:
    config = Config()
    config.output_dir = Path(test_world.getDatapackPath()) / "mcscript"
    config.input_string = TEST_TEMPLATE.format(code)
    datapack = compileMcScript(config)
    Logger.info(datapack.getMainDirectory().getPath("functions").files)
    generate_datapack(config, datapack)

    rcon.command("reload")
    result = rcon.command(f"scoreboard players get result mcscript_test")

    match = RESULT_PATTERN.match(result)
    if match is not None:
        value = int(match.group(1))
    else:
        value = None

    return value, result
Ejemplo n.º 8
0
                    current_x += x_step
                    j += 1.0
                }
                
                current_y += y_step
                i += 1.0
            }
        }
        
        execute("kill @e[tag=$marker_name]")
    }
}
"""

if __name__ == '__main__':
    mcDir = join(getcwd(), "server")
    world = getWorld("McScript", mcDir)

    config = Config("config.ini")
    config.world = world

    code = code_temp
    # code = getScript("mandelbrot")
    config.input_string = code

    datapack = compileMcScript(
        config,
        lambda a, b, c: Logger.info(f"[compile] {a}: {round(b * 100, 2)}%"))
    generate_datapack(config, datapack)
    rcon.send("reload")