Skip to main content

yog_core/
server.rs

1//! The handle Rust mods use to act on the running server — the Rust → Minecraft
2//! path.
3
4use crate::BlockPos;
5
6/// Low-level capabilities the Yog runtime exposes to mods (the engine contract).
7///
8/// The runtime provides the concrete implementation, backed by JNI calls into
9/// the Java host; this crate stays JVM-free. Higher-level, ergonomic wrappers
10/// live in the domain crates (e.g. `yog-world`'s `World`).
11///
12/// Dimensions are identified by their registry id string, e.g.
13/// `"minecraft:overworld"`.
14pub trait Server {
15    /// Broadcast a chat message to all players on the server.
16    fn broadcast(&self, message: &str);
17
18    /// Registry id of the block at `pos` in `dimension`
19    /// (e.g. `"minecraft:stone"`), or `None` if the dimension/position is
20    /// unavailable. Call from the server thread (e.g. an event handler).
21    fn get_block(&self, dimension: &str, pos: BlockPos) -> Option<String>;
22
23    /// Set the block at `pos` in `dimension` to `block_id`. Returns whether the
24    /// change was applied. Call from the server thread.
25    fn set_block(&self, dimension: &str, pos: BlockPos, block_id: &str) -> bool;
26
27    /// Give `count` of `item_id` to the named player. Returns whether it worked
28    /// (player online, item valid). Call from the server thread.
29    fn give_item(&self, player: &str, item_id: &str, count: u32) -> bool;
30
31    /// Teleport the named player to `(x, y, z)` in their current world. Returns
32    /// whether it worked. Call from the server thread.
33    fn teleport(&self, player: &str, x: f64, y: f64, z: f64) -> bool;
34
35    /// Send a raw-byte packet to the named player on `channel` (server → client).
36    /// Returns whether the player was online. Payload is opaque bytes — no NBT.
37    fn send_to_player(&self, player: &str, channel: &str, payload: &[u8]) -> bool;
38
39    /// Send a raw-byte packet to the server on `channel` (client → server).
40    /// Only works in a client context; returns whether it was sent.
41    fn send_to_server(&self, channel: &str, payload: &[u8]) -> bool;
42
43    // ── entity (universal, by UUID) ─────────────────────────────────────────
44
45    /// Teleport any entity (by UUID) within its current world.
46    fn entity_teleport(&self, uuid: &str, x: f64, y: f64, z: f64) -> bool;
47
48    /// Position of an entity, or `None` if not loaded.
49    fn entity_position(&self, uuid: &str) -> Option<(f64, f64, f64)>;
50
51    /// Health of a living entity, or `None`.
52    fn entity_health(&self, uuid: &str) -> Option<f32>;
53
54    /// Set a living entity's health; returns whether it applied.
55    fn entity_set_health(&self, uuid: &str, health: f32) -> bool;
56
57    /// Remove/kill an entity.
58    fn entity_kill(&self, uuid: &str) -> bool;
59
60    /// Spawn an entity of `entity_type` (e.g. `minecraft:pig`) at a position;
61    /// returns its UUID, or `None` on failure.
62    fn spawn_entity(
63        &self,
64        entity_type: &str,
65        dimension: &str,
66        x: f64,
67        y: f64,
68        z: f64,
69    ) -> Option<String>;
70
71    // ── status effects ──────────────────────────────────────────────────────
72
73    /// Apply a status effect to a living entity. `effect_id` is a registry id
74    /// such as `"minecraft:speed"` or `"minecraft:regeneration"`. `amplifier` is
75    /// 0-based (0 = level I). Returns `false` if the entity or effect is unknown.
76    fn entity_add_effect(
77        &self,
78        uuid: &str,
79        effect_id: &str,
80        duration_ticks: i32,
81        amplifier: u8,
82        show_particles: bool,
83    ) -> bool;
84
85    /// Remove a single status effect from a living entity.
86    fn entity_remove_effect(&self, uuid: &str, effect_id: &str) -> bool;
87
88    /// Clear all active status effects from a living entity.
89    fn entity_clear_effects(&self, uuid: &str) -> bool;
90
91    // ── loot tables ─────────────────────────────────────────────────────────
92
93    /// Roll a loot table and spawn the resulting item entities in the world.
94    /// `table_id` is the namespaced id, e.g. `"minecraft:entities/zombie"`.
95    fn drop_loot(&self, table_id: &str, dimension: &str, x: f64, y: f64, z: f64) -> bool;
96
97    // ── tag queries ─────────────────────────────────────────────────────────
98
99    /// Returns whether `item_id` (e.g. `"minecraft:stone"`) belongs to `tag_id`
100    /// (e.g. `"minecraft:planks"`).
101    fn has_item_tag(&self, item_id: &str, tag_id: &str) -> bool;
102
103    /// Returns whether `block_id` belongs to `tag_id`.
104    fn has_block_tag(&self, block_id: &str, tag_id: &str) -> bool;
105
106    // ── world state ─────────────────────────────────────────────────────────
107
108    /// Game time in ticks since world creation (never wraps, keeps counting).
109    fn world_time(&self, dimension: &str) -> Option<i64>;
110
111    /// Set the time-of-day (0 = dawn, 6000 = noon, 12000 = dusk, 18000 = midnight).
112    /// Only changes the visual time, not the absolute world age.
113    fn world_set_time(&self, dimension: &str, time: i64) -> bool;
114
115    /// Whether it is currently raining in the given dimension.
116    fn world_is_raining(&self, dimension: &str) -> bool;
117
118    /// Start or stop rain. `duration_ticks` controls how long the weather lasts
119    /// (use 0 for a server-chosen default duration).
120    fn world_set_weather(&self, dimension: &str, raining: bool, duration_ticks: i32) -> bool;
121
122    // ── entity velocity ─────────────────────────────────────────────────────
123
124    /// Current velocity `(vx, vy, vz)` of any entity, or `None` if not loaded.
125    fn entity_velocity(&self, uuid: &str) -> Option<(f64, f64, f64)>;
126
127    /// Set the velocity of any entity. Returns `false` if not loaded.
128    fn entity_set_velocity(&self, uuid: &str, vx: f64, vy: f64, vz: f64) -> bool;
129
130    /// Add a velocity impulse (cumulative with existing velocity).
131    fn entity_add_velocity(&self, uuid: &str, vx: f64, vy: f64, vz: f64) -> bool;
132
133    // ── scoreboard ──────────────────────────────────────────────────────────
134
135    /// Score of `player` on `objective`, or `None` if the objective doesn't exist.
136    fn scoreboard_get(&self, objective: &str, player: &str) -> Option<i32>;
137
138    /// Set the score; returns `false` if the objective doesn't exist.
139    fn scoreboard_set(&self, objective: &str, player: &str, score: i32) -> bool;
140
141    /// Add `delta` to the score (negative = subtract). Returns the new score,
142    /// or `None` if the objective doesn't exist.
143    fn scoreboard_add(&self, objective: &str, player: &str, delta: i32) -> Option<i32>;
144
145    // ── sound ───────────────────────────────────────────────────────────────
146
147    /// Play a sound at `(x, y, z)` in `dimension`. `sound_id` is a registry id
148    /// (e.g. `"minecraft:entity.player.levelup"`). All players within range hear
149    /// it. Returns `false` if the dimension is unknown.
150    fn play_sound(
151        &self,
152        dimension: &str,
153        x: f64,
154        y: f64,
155        z: f64,
156        sound_id: &str,
157        volume: f32,
158        pitch: f32,
159    ) -> bool;
160
161    /// Play a sound at the named player's current position. All players nearby
162    /// (including the target) hear it. Returns `false` if the player is offline.
163    fn play_sound_to_player(
164        &self,
165        player: &str,
166        sound_id: &str,
167        volume: f32,
168        pitch: f32,
169    ) -> bool;
170
171    // ── title / actionbar ───────────────────────────────────────────────────
172
173    /// Send a title+subtitle screen to a player. Pass empty strings to omit
174    /// either line. Timings are in ticks (20 ticks = 1 second).
175    fn send_title(
176        &self,
177        player: &str,
178        title: &str,
179        subtitle: &str,
180        fadein: i32,
181        stay: i32,
182        fadeout: i32,
183    ) -> bool;
184
185    /// Send a short message to the action-bar (the line just above the hotbar).
186    fn send_actionbar(&self, player: &str, message: &str) -> bool;
187
188    // ── player management ───────────────────────────────────────────────────
189
190    /// Disconnect `player` with the given `reason` message.
191    fn kick_player(&self, player: &str, reason: &str) -> bool;
192
193    /// Change a player's game mode. `gamemode` is one of `"survival"`,
194    /// `"creative"`, `"adventure"`, `"spectator"` (or the abbreviations
195    /// `"s"`, `"c"`, `"a"`, `"sp"`). Returns `false` if the player is offline
196    /// or `gamemode` is unrecognised.
197    fn set_gamemode(&self, player: &str, gamemode: &str) -> bool;
198
199    // ── boss bar ────────────────────────────────────────────────────────────
200
201    /// Create a new boss bar identified by `id` (a namespaced id such as
202    /// `"mymod:progress"`). `color`: `"pink"` / `"blue"` / `"red"` / `"green"` /
203    /// `"yellow"` / `"purple"` / `"white"`. `style`: `"progress"` /
204    /// `"notched_6"` / `"notched_10"` / `"notched_12"` / `"notched_20"`.
205    /// Returns `false` if a bar with that id already exists.
206    fn bossbar_create(&self, id: &str, title: &str, color: &str, style: &str) -> bool;
207
208    /// Remove a boss bar (also removes it from all players). Returns `false` if
209    /// the bar doesn't exist.
210    fn bossbar_remove(&self, id: &str) -> bool;
211
212    /// Update the displayed title of a boss bar.
213    fn bossbar_set_title(&self, id: &str, title: &str) -> bool;
214
215    /// Set the fill level of a boss bar (0.0 = empty, 1.0 = full).
216    fn bossbar_set_progress(&self, id: &str, progress: f32) -> bool;
217
218    /// Change the color of a boss bar (same color names as [`bossbar_create`]).
219    fn bossbar_set_color(&self, id: &str, color: &str) -> bool;
220
221    /// Add an online player to the boss bar's audience.
222    fn bossbar_add_player(&self, id: &str, player: &str) -> bool;
223
224    /// Remove a player from the boss bar's audience.
225    fn bossbar_remove_player(&self, id: &str, player: &str) -> bool;
226
227    /// Show or hide a boss bar for all its current audience members.
228    fn bossbar_set_visible(&self, id: &str, visible: bool) -> bool;
229
230    // ── misc ────────────────────────────────────────────────────────────────
231
232    /// Absolute path of the game / server root directory.
233    fn game_dir(&self) -> String;
234
235    /// Names of all currently connected players.
236    fn online_players(&self) -> Vec<String>;
237
238    // ── block entity ─────────────────────────────────────────────────────────
239
240    /// SNBT string of the block entity at `pos` (e.g. chest contents, furnace
241    /// state, sign text). Returns `None` if there is no block entity there.
242    fn get_block_nbt(&self, dimension: &str, pos: BlockPos) -> Option<String>;
243
244    /// Write `snbt` data into the block entity at `pos` and mark it dirty.
245    /// Returns `false` if there is no block entity at that position.
246    fn set_block_nbt(&self, dimension: &str, pos: BlockPos, snbt: &str) -> bool;
247
248    // ── inventory ────────────────────────────────────────────────────────────
249
250    /// All occupied inventory slots of an online player.
251    /// Returns one entry per occupied slot: `(slot_index, item_id, count)`.
252    fn player_inventory(&self, player: &str) -> Vec<(u32, String, u32)>;
253
254    /// Set (or clear when `count == 0`) one inventory slot of an online player.
255    fn player_set_slot(&self, player: &str, slot: u32, item_id: &str, count: u32) -> bool;
256
257    // ── cross-dimension teleport ─────────────────────────────────────────────
258
259    /// Teleport a player to `(x, y, z)` in a different (or same) dimension.
260    fn teleport_to_dim(&self, player: &str, dimension: &str, x: f64, y: f64, z: f64) -> bool;
261
262    /// Teleport any entity (by UUID) to `(x, y, z)` in `dimension`.
263    fn entity_teleport_to_dim(&self, uuid: &str, dimension: &str, x: f64, y: f64, z: f64) -> bool;
264
265    // ── entity query ─────────────────────────────────────────────────────────
266
267    /// Number of loaded entities of `entity_type` (e.g. `"minecraft:zombie"`)
268    /// in `dimension`. Returns `-1` if the dimension or entity type is unknown.
269    fn world_entity_count(&self, dimension: &str, entity_type: &str) -> i32;
270
271    // ── entity NBT ───────────────────────────────────────────────────────────
272
273    /// SNBT string of the entity's persistent NBT, or `None` if not found.
274    fn entity_get_nbt(&self, uuid: &str) -> Option<String>;
275
276    /// Merge SNBT data into the entity's persistent NBT. Returns `false` if not found.
277    fn entity_set_nbt(&self, uuid: &str, snbt: &str) -> bool;
278
279    // ── particles ────────────────────────────────────────────────────────────
280
281    /// Spawn `count` particles at `(x, y, z)` in `dimension`.
282    /// `dx/dy/dz` control the spatial spread; `speed` controls particle velocity.
283    fn spawn_particles(
284        &self,
285        dimension: &str,
286        x: f64, y: f64, z: f64,
287        particle_type: &str,
288        count: i32,
289        dx: f64, dy: f64, dz: f64,
290        speed: f64,
291    ) -> bool;
292
293    // ── attributes ───────────────────────────────────────────────────────────
294
295    /// Get the base value of an attribute on a living entity.
296    /// `attribute_id` e.g. `"minecraft:generic.max_health"`.
297    /// Returns `None` if the entity or attribute is not found.
298    fn entity_attribute_get(&self, uuid: &str, attribute_id: &str) -> Option<f64>;
299
300    /// Set the base value of an attribute. Returns false if not found.
301    fn entity_attribute_set(&self, uuid: &str, attribute_id: &str, value: f64) -> bool;
302
303    // ── held item NBT (ABI minor 11) ─────────────────────────────────────────
304
305    /// SNBT string of the item currently held in the player's main hand.
306    /// Returns `None` if the player is offline or holding air.
307    fn get_held_item_nbt(&self, player: &str) -> Option<String>;
308
309    /// Merge `snbt` data into the NBT of the item in the player's main hand.
310    /// Returns `false` if the player is offline or holding air.
311    fn set_held_item_nbt(&self, player: &str, snbt: &str) -> bool;
312
313    // ── item stack query (ABI minor 12) ──────────────────────────────────────
314
315    /// SNBT of the item in the player's off hand.
316    /// Returns `None` if offline or holding air.
317    fn get_offhand_item_nbt(&self, player: &str) -> Option<String>;
318
319    /// Merge `snbt` into the NBT of the player's off-hand item.
320    /// Returns `false` if offline or holding air.
321    fn set_offhand_item_nbt(&self, player: &str, snbt: &str) -> bool;
322
323    /// Full item stack at inventory `slot`: `(item_id, count, nbt_snbt)`.
324    /// `nbt_snbt` is `"{}"` when the item has no NBT.
325    /// Returns `None` if the player is offline or the slot is empty.
326    fn get_slot_item(&self, player: &str, slot: u32) -> Option<(String, u32, String)>;
327
328    /// Replace inventory `slot`. Pass `count == 0` to clear the slot.
329    /// `snbt` is merged into the new item's NBT (pass `""` for no NBT).
330    fn set_slot_item(&self, player: &str, slot: u32, item_id: &str, count: u32, snbt: &str) -> bool;
331}