#minecraft #execute-command #minecraft-mod #command-output #vanilla #log-file #connection

minect

A library that allows a Rust program to connect to a running Minecraft instance without requiring any Minecraft mods

5 releases

0.2.1 Dec 30, 2023
0.2.0 Jun 29, 2023
0.1.2 Apr 2, 2023
0.1.1 Mar 27, 2023
0.1.0 Jan 29, 2023

#33 in Games

31 downloads per month
Used in 2 crates

GPL-3.0-or-later

140KB
2.5K SLoC

Minecraft: Java Edition 1.14.1 - 1.20.4 Minecraft: Bedrock Edition unsupported
crates.io Build Status

Minect

Minect (pronounced maɪnɛkt as in Minecraft connection) 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.

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

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::<QueryScoreboardOutput>().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:

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.

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

Dependencies

~8–20MB
~301K SLoC