Guides
Recipes
On this page
Short, complete answers to common questions. Each one is a manifest line and a hook body. A
Wasm guest answers with the same JSON.
An alias command
To make /day mean /time set day, register the name so it appears in the client's
command list. Then rewrite it before the dispatcher sees it:
Manifest::new("aliases", "1")
.with_command(Command::new("day", "Sets the time to day", 2))
.hooking("command.day", Mode::Prepend)
fn hook(&self, _: &dyn Host, call: HookCall<'_>) -> Reply {
let mut input = call.input.clone();
input.set("name", "time");
input.set("rest", "set day");
Reply::Replace(input)
}
The rewritten command goes through the permission check like any other.
Refuse a command on your server
An override that answers false means the command failed, and the game's own command never
runs:
.hooking("command.seed", Mode::Override)
// in hook(): Reply::Replace(Data::Bool(false))
Drop or rewrite a packet
Every packet is a hook point. To stop sending the boss bar:
.hooking("packet.play.clientbound.boss_event", Mode::Override)
// in hook(): Reply::Replace(Data::List(vec![])) // write nothing
To change a serverbound packet before the server reads it, prepend and replace body (hex).
To answer a serverbound packet yourself, override with
{"handled": false, "reply": [[id, "hex"]]}.
Watch everything in a family
.hooking("packet.play.*", Mode::Append) // every play packet, after the fact
.hooking("*", Mode::Append) // every hook point there is
call.point tells you which point you were called at.
Offer a resource pack without a web host
With pack-host.enabled in rustmc.yml, the server serves the pack itself. Host it, then push
the URL and hash you are handed:
let pack = host.host_pack("myplugin", "main", PackSource::Bytes(&zip))?;
host.push_pack(player, PACK_ID, &pack.url, &pack.sha1, false);
A pack under your plugin's own plugins/<plugin>/ directory is PackSource::File("packs/main.zip");
one the operator put in the served directory is PackSource::Directory, by name. See
the pack host.
Hand a client mod the server's recipes
The game no longer sends a client the full recipe set (only the stonecutter's, and the recipe
book's unlocked displays), so a client mod that shows recipes, such as a recipe viewer, has to be
told. recipes gives you every recipe the
server has loaded, the game's own and every enabled datapack's, as vanilla recipe JSON keyed by id.
It comes a page at a time: offset counts from 0 in id order, and limit is capped at
MAX_RECIPE_PAGE (500).
Each page carries the set's revision and its total. Read pages until you have total, and if
the revision changes part-way, start again: the pages came from different sets.
use rustmc_plugin::MAX_RECIPE_PAGE;
fn all_recipes(host: &dyn Host) -> (String, Vec<(String, String)>) {
'again: loop {
let first = host.recipes(0, MAX_RECIPE_PAGE);
let mut recipes = first.recipes;
while recipes.len() < first.total {
let page = host.recipes(recipes.len(), MAX_RECIPE_PAGE);
if page.revision != first.revision || page.recipes.is_empty() {
continue 'again;
}
recipes.extend(page.recipes);
}
return (first.revision, recipes);
}
}
The set changes only when /reload or /datapack enable|disable changes a recipe, and then
recipes_revision changes too. It is
cheap, so hear tick and compare it with the revision you hold rather than reading the whole set
again:
// .hearing(&["tick"]) in the manifest; `known: Mutex<String>` on the plugin.
fn on(&self, host: &dyn Host, event: &Event) -> Outcome {
if let (Event::Tick { .. }, Ok(mut known)) = (event, self.known.lock()) {
if host.recipes_revision() != *known {
let (revision, recipes) = all_recipes(host);
*known = revision;
// send `recipes` to every player who has the mod
}
}
Outcome::Continue
}
Send them on your mod's channel with send_payload. One message holds at most 32767 bytes, so
split a large set across several.
A Wasm guest makes the same calls by name: call("recipes", json!({"offset": 0, "limit": 500}))
and call("recipes_revision", json!({})). Each recipe in the answer is an [id, json] pair.
From docs/api/guide/recipes.md in the RustMC repository at bbd81209ad.