[![Minecraft: Java Edition 1.14.1 - 1.20.4](https://img.shields.io/badge/Minecraft%3A%20Java%20Edition-1.14.1%20--%201.20.4-informational)](https://www.minecraft.net/store/minecraft-java-edition) ![Minecraft: Bedrock Edition unsupported](https://img.shields.io/badge/Minecraft%3A%20Bedrock%20Edition-unsupported-critical)\ [![crates.io](https://img.shields.io/crates/v/minect)](https://crates.io/crates/minect) [![Build Status](https://ci.codeberg.org/api/badges/12945/status.svg)](https://ci.codeberg.org/repos/12945) # Minect Minect (pronounced maɪnɛkt as in **Mine**craft con**nect**ion) is a library that allows a Rust program to connect to a running Minecraft instance without requiring any Minecraft mods. The idea originated in the Java library [Vanilla Injection](https://github.com/Energyxxer/Vanilla-Injection). Using Minect a Rust program can execute commands in Minecraft and listen for command output. This way a Rust program can control or be controlled by Minecraft. The connection requires a building in Minecraft which continuously loads structure files that contain the commands generated by the Rust program. Listening for their output works by polling Minecraft's log file. ## Example ```rust let identifier = "MyProgram"; let world_dir = "C:/Users/Herobrine/AppData/Roaming/.minecraft/saves/New World"; let mut connection = MinecraftConnection::builder(identifier, world_dir).build(); println!("If you are connecting for the first time please execute /reload in Minecraft."); connection.connect().await?; let events = connection.add_listener(); connection.execute_commands([ Command::new("scoreboard objectives add example dummy"), Command::new("scoreboard players set Herobrine example 42"), Command::new(query_scoreboard_command("Herobrine", "example")), ])?; let output = events .filter_map(|event| event.output.parse::().ok()) .next() .await .expect("Minecraft connection was closed unexpectedly"); println!("{}'s score is {}", output.entity, output.score); ``` ## Install In order to set up the building in Minecraft, Minect provides the function `MinecraftConnection::connect`. While blocked in this function, a player can execute `/reload` in Minecraft to start an interactive installer. ## Configuration By default connections operate at the maximum rate of 20 executions per second (1 execution per gametick). For slower computers this can be configured by increasing the score `update_delay` in the scoreboard `minect_config`. For example to update all connections once per second (once per 20 gameticks) execute the following command: ```mcfunction scoreboard players set update_delay minect_config 20 ``` ## Connection Identifier Minect supports operating multiple connection buildings in parallel, each with a unique identifier. A single connection building can be shared between any number of Rust programs, but it is limited to one execution every `update_delay` gameticks. For optimal performance every Rust program can use a different connection identifier. ## Read the Log File When executing commands that should log their output the following gamerules must be considered: 1. `logAdminCommands`: This must be `true` for Minecraft to write the output of commands to the log file. 2. `commandBlockOutput`: This must be `true` for command blocks and command block minecarts to broadcast the output of their commands. 3. `sendCommandFeedback`: This should be set to `false` to prevent the output to also be written to the chat which would likely annoy players. To make things easy, Minect provides the function `enable_logging_command()` to generate a command that sets these gamerules accordingly and `reset_logging_command()` to reset them to their previous values. By default these two commands are automatically executed before/after all commands passed to `execute_commands`. For full control, this can be disabled when building a `MinecraftConnection`. ### Datapacks The output of commands in a datapack (in mcfunction files) is never logged, even if the above mentioned gamerules are set correctly. Minect provides two ways to work around this limitation: you can use the function `logged_block_commands(command)` to spawn a command block or the function `logged_cart_command(command)` to spawn a command block minecart, which will then execute the supplied command. The command is executed with a slight delay after the datapack function finishes. ```rust let mut commands = Vec::new(); commands.push("say querying scoreboard ...".to_string()); commands.extend(logged_block_commands(query_scoreboard_command("@p", "my_scoreboard"))); let my_function = commands.join("\n"); // Generate datapack containing my_function ... // Call my_function (could also be done in Minecraft) connection.execute_commands(["function my_namespace:my_function"])?; ``` ## Remove Connection To remove a connection building in Minecraft a player can execute `function minect:disconnect` to select a connection to remove. ## Uninstall To completely uninstall Minect in Minecraft a player can execute `function minect:uninstall` to start an interactive uninstaller. Alternatively `function minect:uninstall_completely` will uninstall Minect unconditionally. Uninstalling Minect in Minecraft will remove scoreboards, connections and disable the datapack. After doing so the following directories still need to be removed from the world directory manually: * datapacks/minect * generated/minect