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 |
#61 in Games
82 downloads per month
Used in 2 crates
140KB
2.5K
SLoC
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:
logAdminCommands
: This must betrue
for Minecraft to write the output of commands to the log file.commandBlockOutput
: This must betrue
for command blocks and command block minecarts to broadcast the output of their commands.sendCommandFeedback
: This should be set tofalse
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–18MB
~298K SLoC