From 6fc2bd325630b597c0806cf0606fd82d35937d5d Mon Sep 17 00:00:00 2001 From: arismoko <19542195+arismoko@users.noreply.github.com> Date: Mon, 2 Nov 2026 12:37:42 +0000 Subject: [PATCH] A panic in a native mod's hook names the mod and the hook The generated dispatch loops over mod_api::entered, which marks the thread as inside each mod's hook while it runs; the crash handler adds "in native mod , hook " to the panic's message, and the panic goes on unwinding as before. The launcher's generated executable passes the bundles' ids to mod_api::name_mods when the revision has it. Dispatch still takes &[Box]. --- crates/horizon-client-render/src/crash.rs | 99 ++- crates/horizon-client/src/mod_api.rs | 92 +++ .../horizon-client/src/mod_api/generated.rs | 702 +++++++++--------- docs/native-mods.md | 6 + launcher/src/native_mods/api.rs | 47 +- xtask/src/mod_api.rs | 28 +- 6 files changed, 609 insertions(+), 365 deletions(-) diff --git a/crates/horizon-client-render/src/crash.rs b/crates/horizon-client-render/src/crash.rs index 34b0a2b7ea..1c88198c54 100644 --- a/crates/horizon-client-render/src/crash.rs +++ b/crates/horizon-client-render/src/crash.rs @@ -20,6 +20,53 @@ thread_local! { static CONTAINED: Cell = const { Cell::new(0) }; /// The message of the last panic `contain` caught on this thread, from the hook. static CAUGHT: RefCell> = const { RefCell::new(None) }; + /// The native mod hook this thread is inside, for the panic hook to name. + static IN_NATIVE_MOD: Cell> = const { Cell::new(None) }; +} + +/// A call into one hook of a native mod. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct NativeModCall { + /// The mod's `[mod] id`, None in a build that didn't name its mods. + pub id: Option<&'static str>, + /// Its place in dispatch order, which names it then. + pub index: usize, + pub hook: &'static str, +} + +/// Marks this thread as inside `call` until the guard drops, which also happens while a panic +/// unwinds. A hook called from a hook is named by the inner call. +pub fn enter_native_mod(call: NativeModCall) -> NativeModGuard { + NativeModGuard { + outer: IN_NATIVE_MOD.with(|c| c.replace(Some(call))), + } +} + +/// Puts back the call that `enter_native_mod` found. +#[must_use] +pub struct NativeModGuard { + outer: Option, +} + +impl Drop for NativeModGuard { + fn drop(&mut self) { + IN_NATIVE_MOD.with(|c| c.set(self.outer)); + } +} + +/// `message`, with the native mod hook this thread is inside, if any. +fn attributed(message: String) -> String { + match IN_NATIVE_MOD.with(Cell::get) { + Some(NativeModCall { + id: Some(id), hook, .. + }) => format!("{message}\nin native mod {id}, hook {hook}"), + Some(NativeModCall { + id: None, + index, + hook, + }) => format!("{message}\nin native mod #{index}, hook {hook}"), + None => message, + } } /// Runs `f`, and returns a panic in it as an error with the panic's message instead of letting @@ -418,10 +465,10 @@ fn payload_text(payload: &(dyn std::any::Any + Send)) -> String { fn panic_message(info: &std::panic::PanicHookInfo) -> String { let text = payload_text(info.payload()); - match info.location() { + attributed(match info.location() { Some(at) => format!("panicked at {at}:\n{text}"), None => format!("panicked:\n{text}"), - } + }) } /// A `std::backtrace` as one line a frame, `function (file:line:col)`. Captured in a panic hook @@ -537,7 +584,8 @@ pub fn worker_panic_report(info: &std::panic::PanicHookInfo, side: &'static str) /// Reports panics: on the main thread a crash report (the panic then ends the game, exit code /// 101); on a worker thread (`Util.onThreadException`) a crash report too, and the game ends /// with it; on other threads the error goes to the log, as vanilla's uncaught exception handler -/// does. The default hook still prints the panic. A panic inside `contain` is only logged. +/// does. The default hook still prints the panic. A panic inside `contain` is only logged. A +/// panic inside a native mod's hook names the mod and the hook. pub fn install(home: PathBuf, side: &'static str) { let default = std::panic::take_hook(); std::panic::set_hook(Box::new(move |info| { @@ -676,6 +724,25 @@ mod tests { } } + #[test] + fn a_panic_in_a_native_mods_hook_names_it() { + let outer = enter_native_mod(NativeModCall { + id: None, + index: 1, + hook: "render", + }); + let inner = enter_native_mod(NativeModCall { + id: Some("b"), + index: 0, + hook: "tick", + }); + assert!(attributed("boom".into()).ends_with("\nin native mod b, hook tick")); + drop(inner); + assert!(attributed("boom".into()).ends_with("\nin native mod #1, hook render")); + drop(outer); + assert_eq!(attributed("boom".into()), "boom"); + } + fn report() -> Report { Report { time: chrono::TimeZone::with_ymd_and_hms(&Local, 2026, 10, 14, 9, 5, 7).unwrap(), @@ -787,17 +854,37 @@ mod tests { #[test] fn a_panic_becomes_a_report() { // A real panic through a hook, as the game's would be. - let caught = std::sync::Arc::new(Mutex::new(None)); + let caught = std::sync::Arc::new(Mutex::new(Vec::new())); let sink = caught.clone(); let previous = std::panic::take_hook(); std::panic::set_hook(Box::new(move |info| { if panic_message(info).contains("the test crash") { - *sink.lock().unwrap() = Some(panic_report(info, "client")); + sink.lock().unwrap().push(panic_report(info, "client")); } })); let _ = std::panic::catch_unwind(|| panic!("the test crash")); + // The same panic inside a native mod's hook, which the hook sees before the unwind. + let _ = std::panic::catch_unwind(|| { + let _guard = enter_native_mod(NativeModCall { + id: Some("a"), + index: 0, + hook: "tick", + }); + panic!("the test crash") + }); std::panic::set_hook(previous); - let report = caught.lock().unwrap().take().expect("the hook ran"); + // A caught panic leaves the thread as it found it. + assert_eq!(attributed("boom".into()), "boom"); + let mut reports = std::mem::take(&mut *caught.lock().unwrap()); + assert_eq!(reports.len(), 2, "the hook ran for both panics"); + let in_mod = reports.pop().unwrap(); + assert!( + in_mod.error.ends_with("\nin native mod a, hook tick"), + "{}", + in_mod.error + ); + let report = reports.pop().unwrap(); + assert!(!report.error.contains("native mod")); assert!(report.error.contains("the test crash")); assert!(report.error.contains("crash.rs")); // The first frame is the test's own code, not the panic machinery. diff --git a/crates/horizon-client/src/mod_api.rs b/crates/horizon-client/src/mod_api.rs index b31ad3b450..0100e6c28e 100644 --- a/crates/horizon-client/src/mod_api.rs +++ b/crates/horizon-client/src/mod_api.rs @@ -400,6 +400,51 @@ pub fn mods() -> &'static [Box] { MODS.get().map_or(&[], |mods| mods.as_ref()) } +/// The bundles' `[mod] id`s, one a [`mods`] entry in the same order. +static MOD_IDS: OnceLock<&'static [&'static str]> = OnceLock::new(); + +/// Names the entries of [`mods`] by their bundles' `[mod] id`s, so a panic in a hook names its mod. +/// The launcher's generated executable calls it before `entry::main_with`. +pub fn name_mods(ids: &'static [&'static str]) { + if MOD_IDS.set(ids).is_err() { + log::warn!("Trait mods already named; ignoring the second list"); + } +} + +/// `mods` in order, each marked as running `hook` until the next one is (or the loop ends), so a +/// panic in it names the mod. The generated dispatch loops over it. +fn entered<'a>(mods: &'a [Box], hook: &'static str) -> Entered<'a> { + Entered { + mods: mods.iter().enumerate(), + hook, + guard: None, + } +} + +struct Entered<'a> { + mods: std::iter::Enumerate>>, + hook: &'static str, + guard: Option, +} + +impl<'a> Iterator for Entered<'a> { + type Item = &'a Box; + + fn next(&mut self) -> Option { + // The last mod's mark goes first, so the next one's puts back what was there before. + drop(self.guard.take()); + let (index, hooks) = self.mods.next()?; + self.guard = Some(crate::crash::enter_native_mod( + crate::crash::NativeModCall { + id: MOD_IDS.get().and_then(|ids| ids.get(index)).copied(), + index, + hook: self.hook, + }, + )); + Some(hooks) + } +} + /// Whether a mod claims a cancellable hook. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Flow { @@ -492,3 +537,50 @@ mod generated; pub use generated::Hooks; #[doc(hidden)] pub use generated::*; + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::Mutex; + + struct Quiet; + impl Hooks for Quiet {} + + struct Broken; + impl Hooks for Broken { + fn component_types(&self, _event: &mut ComponentTypesEvent<'_>) { + panic!("a broken mod"); + } + } + + #[test] + fn a_panic_in_a_hook_names_the_mod_and_the_hook() { + name_mods(&["quiet", "broken"]); + let mods: Vec> = vec![Box::new(Quiet), Box::new(Broken)]; + let caught = Arc::new(Mutex::new(Vec::new())); + let sink = caught.clone(); + let previous = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |info| { + let error = crate::crash::panic_report(info, "client").error; + if error.contains("a broken mod") { + sink.lock().unwrap().push(error); + } + })); + let unwound = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { + dispatch_component_types(&mods, &mut Vec::new()) + })); + // Once the dispatch has unwound, the thread is in no mod. + let _ = std::panic::catch_unwind(|| panic!("a broken mod's caller")); + std::panic::set_hook(previous); + // The game stops as before: the panic goes on to the dispatch's caller. + assert!(unwound.is_err()); + let errors = caught.lock().unwrap(); + assert_eq!(errors.len(), 2); + assert!( + errors[0].ends_with("\nin native mod broken, hook component_types"), + "{}", + errors[0] + ); + assert!(!errors[1].contains("in native mod"), "{}", errors[1]); + } +} diff --git a/crates/horizon-client/src/mod_api/generated.rs b/crates/horizon-client/src/mod_api/generated.rs index 0342a158c7..23a72110d5 100644 --- a/crates/horizon-client/src/mod_api/generated.rs +++ b/crates/horizon-client/src/mod_api/generated.rs @@ -4259,7 +4259,7 @@ pub struct FrameEvent { } pub fn dispatch_frame(host: &mut dyn Host, mods: &[Box], elapsed: Duration) { let mut event = FrameEvent { elapsed }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "frame") { mod_hook.frame(host, &mut event); } } @@ -4268,7 +4268,7 @@ pub fn dispatch_frame(host: &mut dyn Host, mods: &[Box], elapsed: Dur pub struct TickEvent {} pub fn dispatch_tick(host: &mut dyn Host, mods: &[Box]) { let mut event = TickEvent {}; - for mod_hook in mods { + for mod_hook in super::entered(mods, "tick") { mod_hook.tick(host, &mut event); } } @@ -4285,7 +4285,7 @@ pub fn dispatch_visuals( lights: &mut Vec, ) { let mut event = VisualsEvent { rims, lights }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "visuals") { mod_hook.visuals(host, &mut event); } } @@ -4300,7 +4300,7 @@ pub fn dispatch_emissive( layers: &mut Vec<(&'static str, &'static str)>, ) { let mut event = EmissiveEvent { layers }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "emissive") { mod_hook.emissive(host, &mut event); } } @@ -4323,7 +4323,7 @@ pub fn dispatch_world_lifecycle( phase, error_text, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "world_lifecycle") { mod_hook.world_lifecycle(host, &mut event); } } @@ -4338,7 +4338,7 @@ pub fn dispatch_server_about_to_start( dedicated: bool, ) { let mut event = ServerAboutToStartEvent { dedicated }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "server_about_to_start") { mod_hook.server_about_to_start(host, &mut event); } } @@ -4349,7 +4349,7 @@ pub struct ServerStoppingEvent { } pub fn dispatch_server_stopping(host: &mut dyn Host, mods: &[Box], dedicated: bool) { let mut event = ServerStoppingEvent { dedicated }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "server_stopping") { mod_hook.server_stopping(host, &mut event); } } @@ -4366,7 +4366,7 @@ pub fn dispatch_server_tick( phase: ServerTickPhase, ) { let mut event = ServerTickEvent { context, phase }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "server_tick") { mod_hook.server_tick(host, &mut event); } } @@ -4377,7 +4377,7 @@ pub struct LevelTickPreEvent<'a> { } pub fn dispatch_level_tick_pre(host: &mut dyn Host, mods: &[Box], dimension: &str) { let mut event = LevelTickPreEvent { dimension }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "level_tick_pre") { mod_hook.level_tick_pre(host, &mut event); } } @@ -4388,7 +4388,7 @@ pub struct LevelTickPostEvent<'a> { } pub fn dispatch_level_tick_post(host: &mut dyn Host, mods: &[Box], dimension: &str) { let mut event = LevelTickPostEvent { dimension }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "level_tick_post") { mod_hook.level_tick_post(host, &mut event); } } @@ -4414,7 +4414,7 @@ pub fn dispatch_block_changed( old, new, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_changed") { mod_hook.block_changed(level, &mut event); } } @@ -4443,7 +4443,7 @@ pub fn dispatch_neighbor_changed( changed, moved, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "neighbor_changed") { mod_hook.neighbor_changed(level, &mut event); } } @@ -4470,7 +4470,7 @@ pub fn dispatch_random_tick( pos, state, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "random_tick") { if matches!(mod_hook.random_tick(level, &mut event), Flow::Cancel) { *handled = true; break; @@ -4500,7 +4500,7 @@ pub fn dispatch_tick_block( pos, state, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "tick_block") { if matches!(mod_hook.tick_block(level, &mut event), Flow::Cancel) { *handled = true; break; @@ -4539,7 +4539,7 @@ pub fn dispatch_update_shape( neighbour_pos, neighbour, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "update_shape") { if let Some(replacement) = mod_hook.update_shape(level, &mut event) { *new = Some(replacement); break; @@ -4559,7 +4559,7 @@ pub fn dispatch_hud( corners: &mut Corners, ) { let mut event = HudEvent { batch, corners }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "hud") { mod_hook.hud(host, &mut event); } } @@ -4571,7 +4571,7 @@ pub struct KeyEvent<'a> { } pub fn dispatch_key(host: &mut dyn Host, mods: &[Box], key: &str, pressed: bool) { let mut event = KeyEvent { key, pressed }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "key") { mod_hook.key(host, &mut event); } } @@ -4590,7 +4590,7 @@ pub fn dispatch_wheel( return; } let mut event = WheelEvent { steps }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "wheel") { if matches!(mod_hook.wheel(host, &mut event), Flow::Cancel) { *claimed = true; break; @@ -4612,7 +4612,7 @@ pub fn dispatch_command( return; } let mut event = CommandEvent { command }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "command") { if matches!(mod_hook.command(host, &mut event), Flow::Cancel) { *ran = true; break; @@ -4630,7 +4630,7 @@ pub fn dispatch_commands( commands: &mut Vec<&'static str>, ) { let mut event = CommandsEvent { commands }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "commands") { mod_hook.commands(host, &mut event); } } @@ -4642,7 +4642,7 @@ pub fn dispatch_zoom(host: &dyn Host, mods: &[Box], zoom: &mut Option return; } let mut event = ZoomEvent {}; - for mod_hook in mods { + for mod_hook in super::entered(mods, "zoom") { if let Some(replacement) = mod_hook.zoom(host, &mut event) { *zoom = Some(replacement); break; @@ -4661,7 +4661,7 @@ pub fn dispatch_minimap( return; } let mut event = MinimapEvent {}; - for mod_hook in mods { + for mod_hook in super::entered(mods, "minimap") { if let Some(replacement) = mod_hook.minimap(host, &mut event) { *minimap = Some(replacement); break; @@ -4675,7 +4675,7 @@ pub struct ModsEvent<'a> { } pub fn dispatch_mods(host: &mut dyn Host, mods_: &[Box], mods: &mut Vec) { let mut event = ModsEvent { mods }; - for mod_hook in mods_ { + for mod_hook in super::entered(mods_, "mods") { mod_hook.mods(host, &mut event); } } @@ -4692,7 +4692,7 @@ pub fn dispatch_settings( buttons: &mut Vec, ) { let mut event = SettingsEvent { mod_id, buttons }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "settings") { mod_hook.settings(host, &mut event); } } @@ -4709,7 +4709,7 @@ pub fn dispatch_settings_click( button: usize, ) { let mut event = SettingsClickEvent { mod_id, button }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "settings_click") { mod_hook.settings_click(host, &mut event); } } @@ -4726,7 +4726,7 @@ pub fn dispatch_panel_event( event: &NativePanelEvent, ) { let mut event_ = PanelEventEvent { mod_id, event }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "panel_event") { mod_hook.panel_event(host, &mut event_); } } @@ -4745,7 +4745,7 @@ pub fn dispatch_block_entity( return; } let mut event = BlockEntityEvent { block }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity") { if let Some(replacement) = mod_hook.block_entity(host, &mut event) { *entity = Some(replacement); break; @@ -4768,7 +4768,7 @@ pub fn dispatch_block_entity_ticks( block, ticks: *ticks, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity_ticks") { mod_hook.block_entity_ticks(host, &mut event); } *ticks = event.ticks; @@ -4786,7 +4786,7 @@ pub fn dispatch_block_entity_tick( entity: &mut ModBlockEntity, ) { let mut event = BlockEntityTickEvent { pos, entity }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity_tick") { mod_hook.block_entity_tick(host, &mut event); } } @@ -4806,7 +4806,7 @@ pub fn dispatch_block_entity_update_tag( return; } let mut event = BlockEntityUpdateTagEvent { pos, entity }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity_update_tag") { if let Some(replacement) = mod_hook.block_entity_update_tag(&mut event) { *tag = Some(replacement); break; @@ -4828,7 +4828,7 @@ pub fn dispatch_block_entity_container( return; } let mut event = BlockEntityContainerEvent { block }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity_container") { if let Some(replacement) = mod_hook.block_entity_container(host, &mut event) { *container = Some(replacement); break; @@ -4850,7 +4850,7 @@ pub fn dispatch_screen( return; } let mut event = ScreenEvent { block }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen") { if let Some(replacement) = mod_hook.screen(host, &mut event) { *screen = Some(replacement); break; @@ -4879,7 +4879,7 @@ pub fn dispatch_screen_draw( batch, origin, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_draw") { mod_hook.screen_draw(host, &mut event); } } @@ -4909,7 +4909,7 @@ pub fn dispatch_screen_click( at, right, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_click") { if let Some(replacement) = mod_hook.screen_click(host, &mut event) { *button = Some(replacement); break; @@ -4938,7 +4938,7 @@ pub fn dispatch_screen_tooltip( at, lines, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_tooltip") { mod_hook.screen_tooltip(host, &mut event); } } @@ -4957,7 +4957,7 @@ pub fn dispatch_menu_button( id: i32, ) { let mut event = MenuButtonEvent { pos, entity, id }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "menu_button") { mod_hook.menu_button(host, &mut event); } } @@ -4972,7 +4972,7 @@ pub fn dispatch_register_commands( commands: &mut Vec, ) { let mut event = RegisterCommandsEvent { commands }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "register_commands") { mod_hook.register_commands(host, &mut event); } } @@ -4993,7 +4993,7 @@ pub fn dispatch_perform_command( return; } let mut event = PerformCommandEvent { player, command }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "perform_command") { if matches!(mod_hook.perform_command(host, &mut event), Flow::Cancel) { *ran = true; break; @@ -5025,7 +5025,7 @@ pub fn dispatch_menu_clicked( button, mode, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "menu_clicked") { mod_hook.menu_clicked(host, &mut event); } } @@ -5037,7 +5037,7 @@ pub struct MenuClosedEvent { } pub fn dispatch_menu_closed(host: &mut dyn Host, mods: &[Box], uuid: u128, window: i32) { let mut event = MenuClosedEvent { uuid, window }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "menu_closed") { mod_hook.menu_closed(host, &mut event); } } @@ -5054,7 +5054,7 @@ pub fn dispatch_tooltip( lines: &mut Vec<(Text, u32)>, ) { let mut event = TooltipEvent { stack, lines }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "tooltip") { mod_hook.tooltip(host, &mut event); } } @@ -5077,7 +5077,7 @@ pub fn dispatch_use_item_on( return; } let mut event = UseItemOnEvent { stack, pos, face }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "use_item_on") { if matches!(mod_hook.use_item_on(host, &mut event), Flow::Cancel) { *claimed = true; break; @@ -5099,7 +5099,7 @@ pub fn dispatch_use_item( return; } let mut event = UseItemEvent { stack }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "use_item") { if matches!(mod_hook.use_item(host, &mut event), Flow::Cancel) { *claimed = true; break; @@ -5123,7 +5123,7 @@ pub fn dispatch_destroy_block( return; } let mut event = DestroyBlockEvent { pos, state }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "destroy_block") { if matches!(mod_hook.destroy_block(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -5145,7 +5145,7 @@ pub fn dispatch_place_block( state: BlockStateId, ) { let mut event = PlaceBlockEvent { stack, pos, state }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "place_block") { mod_hook.place_block(host, &mut event); } } @@ -5166,7 +5166,7 @@ pub fn dispatch_right_click_block( return; } let mut event = RightClickBlockEvent { pos, face }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "right_click_block") { if matches!(mod_hook.right_click_block(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -5199,7 +5199,7 @@ pub fn dispatch_block_spread( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_spread") { if matches!(mod_hook.block_spread(level, &mut event), Flow::Cancel) { *canceled = true; break; @@ -5235,7 +5235,7 @@ pub fn dispatch_piston_move( push, destroy, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "piston_move") { if matches!(mod_hook.piston_move(level, &mut event), Flow::Cancel) { *canceled = true; break; @@ -5261,7 +5261,7 @@ pub fn dispatch_explosion_detonate( center, blocks, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "explosion_detonate") { mod_hook.explosion_detonate(host, &mut event); } } @@ -5282,7 +5282,7 @@ pub fn dispatch_fill_bucket( return; } let mut event = FillBucketEvent { stack, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "fill_bucket") { if matches!(mod_hook.fill_bucket(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -5308,7 +5308,7 @@ pub fn dispatch_attack_entity( return; } let mut event = AttackEntityEvent { entity, kind, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "attack_entity") { if matches!(mod_hook.attack_entity(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -5334,7 +5334,7 @@ pub fn dispatch_net_from_client( channel, data, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "net_from_client") { mod_hook.net_from_client(host, &mut event); } } @@ -5351,7 +5351,7 @@ pub fn dispatch_net_from_server( data: &[u8], ) { let mut event = NetFromServerEvent { channel, data }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "net_from_server") { mod_hook.net_from_server(host, &mut event); } } @@ -5368,7 +5368,7 @@ pub fn dispatch_player_died( cause: Option<&str>, ) { let mut event = PlayerDiedEvent { player, cause }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_died") { mod_hook.player_died(host, &mut event); } } @@ -5394,7 +5394,7 @@ pub fn dispatch_mob_spawned( pos, natural, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mob_spawned") { mod_hook.mob_spawned(host, &mut event); } } @@ -5417,7 +5417,7 @@ pub fn dispatch_mob_killed( entity, kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mob_killed") { mod_hook.mob_killed(host, &mut event); } } @@ -5440,7 +5440,7 @@ pub fn dispatch_item_dropped( item, count, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "item_dropped") { mod_hook.item_dropped(host, &mut event); } } @@ -5467,7 +5467,7 @@ pub fn dispatch_item_picked_up( item, count, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "item_picked_up") { if matches!(mod_hook.item_picked_up(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -5493,7 +5493,7 @@ pub fn dispatch_hurt_enemy( entity, kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "hurt_enemy") { mod_hook.hurt_enemy(host, &mut event); } } @@ -5510,7 +5510,7 @@ pub fn dispatch_inventory_tick( selected: bool, ) { let mut event = InventoryTickEvent { slot, selected }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "inventory_tick") { mod_hook.inventory_tick(host, &mut event); } } @@ -5527,7 +5527,7 @@ pub fn dispatch_on_equip( new: Option<&ItemStack>, ) { let mut event = OnEquipEvent { slot, new }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "on_equip") { mod_hook.on_equip(host, &mut event); } } @@ -5559,7 +5559,7 @@ pub fn dispatch_block_signal( direct, signal: *signal, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_signal") { mod_hook.block_signal(level, &mut event); } *signal = event.signal; @@ -5580,7 +5580,7 @@ pub fn dispatch_is_signal_source( state, source: *source, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "is_signal_source") { mod_hook.is_signal_source(level, &mut event); } *source = event.source; @@ -5604,7 +5604,7 @@ pub fn dispatch_health_hud( return; } let mut event = HealthHudEvent { inputs, wi, hi }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "health_hud") { if let Some(replacement) = mod_hook.health_hud(host, &mut event) { *draws = Some(replacement); break; @@ -5634,7 +5634,7 @@ pub fn dispatch_interact_entity( kind, stack, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "interact_entity") { if matches!(mod_hook.interact_entity(host, &mut event), Flow::Cancel) { *claimed = true; break; @@ -5660,7 +5660,7 @@ pub fn dispatch_left_click_block( return; } let mut event = LeftClickBlockEvent { pos, face, state }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "left_click_block") { if matches!(mod_hook.left_click_block(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -5672,7 +5672,7 @@ pub fn dispatch_left_click_block( pub struct PlayerTickEvent {} pub fn dispatch_player_tick(host: &mut dyn Host, mods: &[Box]) { let mut event = PlayerTickEvent {}; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_tick") { mod_hook.player_tick(host, &mut event); } } @@ -5705,7 +5705,7 @@ pub fn dispatch_entity_join_level( pos, loaded_from_disk, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_join_level") { if matches!(mod_hook.entity_join_level(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -5743,7 +5743,7 @@ pub fn dispatch_living_incoming_damage( direct, amount: *amount, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "living_incoming_damage") { if matches!(mod_hook.living_incoming_damage(&mut event), Flow::Cancel) { *canceled = true; break; @@ -5773,7 +5773,7 @@ pub fn dispatch_menu_button_v2( id, carried, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "menu_button_v2") { mod_hook.menu_button_v2(host, &mut event); } } @@ -5796,7 +5796,7 @@ pub fn dispatch_entity_leave_level( entity, kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_leave_level") { mod_hook.entity_leave_level(host, &mut event); } } @@ -5815,7 +5815,7 @@ pub fn dispatch_block_entity_fluids( return; } let mut event = BlockEntityFluidsEvent { block }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity_fluids") { if let Some(replacement) = mod_hook.block_entity_fluids(host, &mut event) { *fluids = Some(replacement); break; @@ -5844,7 +5844,7 @@ pub fn dispatch_should_apply_effect_tick_this_tick( amplifier, apply: *apply, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "should_apply_effect_tick_this_tick") { mod_hook.should_apply_effect_tick_this_tick(host, &mut event); } *apply = event.apply; @@ -5874,7 +5874,7 @@ pub fn dispatch_apply_effect_tick( amplifier, keep: *keep, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "apply_effect_tick") { mod_hook.apply_effect_tick(host, &mut event); } *keep = event.keep; @@ -5898,7 +5898,7 @@ pub fn dispatch_on_effect_added( entity, amplifier, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "on_effect_added") { mod_hook.on_effect_added(host, &mut event); } } @@ -5921,7 +5921,7 @@ pub fn dispatch_mob_effect_added( entity, amplifier, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mob_effect_added") { mod_hook.mob_effect_added(host, &mut event); } } @@ -5944,7 +5944,7 @@ pub fn dispatch_chunk_load( chunk, new, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "chunk_load") { mod_hook.chunk_load(host, &mut event); } } @@ -5961,7 +5961,7 @@ pub fn dispatch_chunk_unload( chunk: [i32; 2], ) { let mut event = ChunkUnloadEvent { dimension, chunk }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "chunk_unload") { mod_hook.chunk_unload(host, &mut event); } } @@ -5978,7 +5978,7 @@ pub fn dispatch_player_logged_in( name: &str, ) { let mut event = PlayerLoggedInEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_logged_in") { mod_hook.player_logged_in(host, &mut event); } } @@ -5995,7 +5995,7 @@ pub fn dispatch_player_logged_out( name: &str, ) { let mut event = PlayerLoggedOutEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_logged_out") { mod_hook.player_logged_out(host, &mut event); } } @@ -6012,7 +6012,7 @@ pub fn dispatch_item_bar( bar: &mut Option<(i32, u32)>, ) { let mut event = ItemBarEvent { stack, bar }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "item_bar") { mod_hook.item_bar(host, &mut event); } } @@ -6032,7 +6032,7 @@ pub fn dispatch_has_analog_output( state, output: *output, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "has_analog_output") { mod_hook.has_analog_output(level, &mut event); } *output = event.output; @@ -6062,7 +6062,7 @@ pub fn dispatch_analog_output( face, output: *output, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "analog_output") { mod_hook.analog_output(level, &mut event); } *output = event.output; @@ -6074,7 +6074,7 @@ pub struct ComponentTypesEvent<'a> { } pub fn dispatch_component_types(mods: &[Box], types: &mut Vec) { let mut event = ComponentTypesEvent { types }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "component_types") { mod_hook.component_types(&mut event); } } @@ -6104,7 +6104,7 @@ pub fn dispatch_dispense_item( facing, stack, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "dispense_item") { if let Some(replacement) = mod_hook.dispense_item(host, &mut event) { *answer = Some(replacement); break; @@ -6126,7 +6126,7 @@ pub fn dispatch_tooltip_component( return; } let mut event = TooltipComponentEvent { stack }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "tooltip_component") { if let Some(replacement) = mod_hook.tooltip_component(host, &mut event) { *size = Some(replacement); break; @@ -6155,7 +6155,7 @@ pub fn dispatch_tooltip_component_draw( origin, size, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "tooltip_component_draw") { mod_hook.tooltip_component_draw(host, &mut event); } } @@ -6182,7 +6182,7 @@ pub fn dispatch_can_survive( pos, state, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "can_survive") { if let Some(replacement) = mod_hook.can_survive(level, &mut event) { *survives = Some(replacement); break; @@ -6215,7 +6215,7 @@ pub fn dispatch_may_place_on( ground, ground_pos, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "may_place_on") { if let Some(replacement) = mod_hook.may_place_on(level, &mut event) { *may = Some(replacement); break; @@ -6247,7 +6247,7 @@ pub fn dispatch_block_entity_submit( entity, draw, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity_submit") { mod_hook.block_entity_submit(host, &mut event); } } @@ -6276,7 +6276,7 @@ pub fn dispatch_block_entity_render_bounding_box( entity, bounds, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity_render_bounding_box") { mod_hook.block_entity_render_bounding_box(host, &mut event); } } @@ -6303,7 +6303,7 @@ pub fn dispatch_is_valid_bonemeal_target( pos, state, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "is_valid_bonemeal_target") { if let Some(replacement) = mod_hook.is_valid_bonemeal_target(level, &mut event) { *valid = Some(replacement); break; @@ -6332,7 +6332,7 @@ pub fn dispatch_is_bonemeal_success( state, success: *success, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "is_bonemeal_success") { mod_hook.is_bonemeal_success(level, &mut event); } *success = event.success; @@ -6356,7 +6356,7 @@ pub fn dispatch_perform_bonemeal( pos, state, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "perform_bonemeal") { mod_hook.perform_bonemeal(level, &mut event); } } @@ -6384,7 +6384,7 @@ pub fn dispatch_block_step_on( state, position, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_step_on") { mod_hook.block_step_on(&mut event); } } @@ -6412,7 +6412,7 @@ pub fn dispatch_block_entity_inside( state, position, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity_inside") { mod_hook.block_entity_inside(&mut event); } } @@ -6446,7 +6446,7 @@ pub fn dispatch_block_fall_on( distance, damage: *damage, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_fall_on") { mod_hook.block_fall_on(&mut event); } *damage = event.damage; @@ -6464,7 +6464,7 @@ pub fn dispatch_consume_effect( data: &serde_json::Value, ) { let mut event = ConsumeEffectEvent { kind, data }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "consume_effect") { mod_hook.consume_effect(host, &mut event); } } @@ -6476,7 +6476,7 @@ pub struct LootTableLoadEvent<'a> { } pub fn dispatch_loot_table_load(mods: &[Box], id: &str, table: &mut Value) { let mut event = LootTableLoadEvent { id, table }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "loot_table_load") { mod_hook.loot_table_load(&mut event); } } @@ -6493,7 +6493,7 @@ pub fn dispatch_loot_drops( drops: &mut Vec, ) { let mut event = LootDropsEvent { context, drops }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "loot_drops") { mod_hook.loot_drops(host, &mut event); } } @@ -6523,7 +6523,7 @@ pub fn dispatch_state_for_placement( context, fluid, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "state_for_placement") { if let Some(replacement) = mod_hook.state_for_placement(level, &mut event) { *answer = Some(replacement); break; @@ -6555,7 +6555,7 @@ pub fn dispatch_enchant_effect( level, victim, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "enchant_effect") { mod_hook.enchant_effect(host, &mut event); } } @@ -6572,7 +6572,7 @@ pub fn dispatch_screen_render_post( screen: &NativeScreenView<'_>, ) { let mut event = ScreenRenderPostEvent { batch, screen }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_render_post") { mod_hook.screen_render_post(host, &mut event); } } @@ -6588,7 +6588,7 @@ pub fn dispatch_modify_default_components( components: &mut Map, ) { let mut event = ModifyDefaultComponentsEvent { item, components }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "modify_default_components") { mod_hook.modify_default_components(&mut event); } } @@ -6615,7 +6615,7 @@ pub fn dispatch_screen_mouse_button_pressed_pre( button, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_mouse_button_pressed_pre") { if matches!( mod_hook.screen_mouse_button_pressed_pre(host, &mut event), Flow::Cancel @@ -6648,7 +6648,7 @@ pub fn dispatch_screen_mouse_button_released_pre( button, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_mouse_button_released_pre") { if matches!( mod_hook.screen_mouse_button_released_pre(host, &mut event), Flow::Cancel @@ -6671,7 +6671,7 @@ pub fn dispatch_camera_shake( shake: &mut NativeShake, ) { let mut event = CameraShakeEvent { partial, shake }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "camera_shake") { mod_hook.camera_shake(host, &mut event); } } @@ -6688,7 +6688,7 @@ pub fn dispatch_shader_params( params: &mut [[f32; 4]; 8], ) { let mut event = ShaderParamsEvent { partial, params }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "shader_params") { mod_hook.shader_params(host, &mut event); } } @@ -6715,7 +6715,7 @@ pub fn dispatch_block_highlight( state, partial, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_highlight") { if matches!(mod_hook.block_highlight(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -6751,7 +6751,7 @@ pub fn dispatch_render_hand( swing, equip, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "render_hand") { if matches!(mod_hook.render_hand(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -6763,7 +6763,7 @@ pub fn dispatch_render_hand( pub struct ClientResourcesReloadedEvent {} pub fn dispatch_client_resources_reloaded(host: &mut dyn Host, mods: &[Box]) { let mut event = ClientResourcesReloadedEvent {}; - for mod_hook in mods { + for mod_hook in super::entered(mods, "client_resources_reloaded") { mod_hook.client_resources_reloaded(host, &mut event); } } @@ -6784,7 +6784,7 @@ pub fn dispatch_item_decorations( batch: &mut HudBatch, ) { let mut event = ItemDecorationsEvent { stack, x, y, batch }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "item_decorations") { mod_hook.item_decorations(host, &mut event); } } @@ -6804,7 +6804,7 @@ pub fn dispatch_use_duration( stack, duration: *duration, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "use_duration") { mod_hook.use_duration(host, &mut event); } *duration = event.duration; @@ -6822,7 +6822,7 @@ pub fn dispatch_use_animation( animation: &mut UseAnimation, ) { let mut event = UseAnimationEvent { stack, animation }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "use_animation") { mod_hook.use_animation(host, &mut event); } } @@ -6842,7 +6842,7 @@ pub fn dispatch_can_eat( stack, can_eat: *can_eat, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "can_eat") { mod_hook.can_eat(host, &mut event); } *can_eat = event.can_eat; @@ -6873,7 +6873,7 @@ pub fn dispatch_living_entity_use_item_start( hand, duration: *duration, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "living_entity_use_item_start") { if matches!( mod_hook.living_entity_use_item_start(host, &mut event), Flow::Cancel @@ -6909,7 +6909,7 @@ pub fn dispatch_living_entity_use_item_finish( duration, result, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "living_entity_use_item_finish") { mod_hook.living_entity_use_item_finish(host, &mut event); } } @@ -6936,7 +6936,7 @@ pub fn dispatch_screen_mouse_scrolled_pre( scroll, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_mouse_scrolled_pre") { if matches!( mod_hook.screen_mouse_scrolled_pre(host, &mut event), Flow::Cancel @@ -6972,7 +6972,7 @@ pub fn dispatch_player_command( command, replies, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_command") { if matches!(mod_hook.player_command(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -6994,7 +6994,7 @@ pub fn dispatch_perform_console_command( return; } let mut event = PerformConsoleCommandEvent { command }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "perform_console_command") { if matches!( mod_hook.perform_console_command(host, &mut event), Flow::Cancel @@ -7030,7 +7030,7 @@ pub fn dispatch_screen_key_pressed_pre( repeat, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_key_pressed_pre") { if matches!( mod_hook.screen_key_pressed_pre(host, &mut event), Flow::Cancel @@ -7063,7 +7063,7 @@ pub fn dispatch_screen_char_typed_pre( c, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_char_typed_pre") { if matches!( mod_hook.screen_char_typed_pre(host, &mut event), Flow::Cancel @@ -7084,7 +7084,7 @@ pub fn dispatch_data_pack_files( files: &mut Vec<(String, Vec)>, ) { let mut event = DataPackFilesEvent { files }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "data_pack_files") { mod_hook.data_pack_files(host, &mut event); } } @@ -7101,7 +7101,7 @@ pub fn dispatch_biome_colors( colors: &mut BiomeColors, ) { let mut event = BiomeColorsEvent { biome, colors }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "biome_colors") { mod_hook.biome_colors(host, &mut event); } } @@ -7112,7 +7112,7 @@ pub struct ServerDataLoadedEvent { } pub fn dispatch_server_data_loaded(host: &mut dyn Host, mods: &[Box], reload: bool) { let mut event = ServerDataLoadedEvent { reload }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "server_data_loaded") { mod_hook.server_data_loaded(host, &mut event); } } @@ -7135,7 +7135,7 @@ pub fn dispatch_compute_fov( camera, degrees: *degrees, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "compute_fov") { mod_hook.compute_fov(host, &mut event); } *degrees = event.degrees; @@ -7157,7 +7157,7 @@ pub fn dispatch_mob_submit( return; } let mut event = MobSubmitEvent { mob, draw }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mob_submit") { if matches!(mod_hook.mob_submit(host, &mut event), Flow::Cancel) { *drawn = true; break; @@ -7186,7 +7186,7 @@ pub fn dispatch_camera_distance( entity, distance: *distance, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "camera_distance") { mod_hook.camera_distance(host, &mut event); } *distance = event.distance; @@ -7213,7 +7213,7 @@ pub fn dispatch_compute_fog_color( fog_type, rgb, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "compute_fog_color") { mod_hook.compute_fog_color(host, &mut event); } } @@ -7240,7 +7240,7 @@ pub fn dispatch_mouse_button_pre( pressed, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mouse_button_pre") { if matches!(mod_hook.mouse_button_pre(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -7266,7 +7266,7 @@ pub fn dispatch_mouse_button_post( pressed, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mouse_button_post") { mod_hook.mouse_button_post(host, &mut event); } } @@ -7283,7 +7283,7 @@ pub fn dispatch_player_respawned( name: &str, ) { let mut event = PlayerRespawnedEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_respawned") { mod_hook.player_respawned(host, &mut event); } } @@ -7309,7 +7309,7 @@ pub fn dispatch_render_fog( fog_type, fog, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "render_fog") { mod_hook.render_fog(host, &mut event); } } @@ -7336,7 +7336,7 @@ pub fn dispatch_screen_key_released_pre( key, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_key_released_pre") { if matches!( mod_hook.screen_key_released_pre(host, &mut event), Flow::Cancel @@ -7362,7 +7362,7 @@ pub fn dispatch_music( music, volume: *volume, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "music") { mod_hook.music(host, &mut event); } *volume = event.volume; @@ -7378,7 +7378,7 @@ pub fn dispatch_music_layers( layers: &mut Vec, ) { let mut event = MusicLayersEvent { layers }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "music_layers") { mod_hook.music_layers(host, &mut event); } } @@ -7393,7 +7393,7 @@ pub fn dispatch_datapack_sync( recipe_types: &mut Vec, ) { let mut event = DatapackSyncEvent { recipe_types }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "datapack_sync") { mod_hook.datapack_sync(host, &mut event); } } @@ -7408,7 +7408,7 @@ pub fn dispatch_recipes_received( recipe_types: &[String], ) { let mut event = RecipesReceivedEvent { recipe_types }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "recipes_received") { mod_hook.recipes_received(host, &mut event); } } @@ -7425,7 +7425,7 @@ pub fn dispatch_input_key( modifiers: u32, ) { let mut event_ = InputKeyEvent { event, modifiers }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "input_key") { mod_hook.input_key(host, &mut event_); } } @@ -7458,7 +7458,7 @@ pub fn dispatch_mouse_scrolling( cursor, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mouse_scrolling") { if matches!(mod_hook.mouse_scrolling(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -7491,7 +7491,7 @@ pub fn dispatch_screen_mouse_dragged_pre( delta, modifiers, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "screen_mouse_dragged_pre") { if matches!( mod_hook.screen_mouse_dragged_pre(host, &mut event), Flow::Cancel @@ -7523,7 +7523,7 @@ pub fn dispatch_mod_container_viewers( viewers, previous, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mod_container_viewers") { mod_hook.mod_container_viewers(host, &mut event); } } @@ -7564,7 +7564,7 @@ pub fn dispatch_living_knockback( x: *x, z: *z, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "living_knockback") { if matches!(mod_hook.living_knockback(&mut event), Flow::Cancel) { *canceled = true; break; @@ -7602,7 +7602,7 @@ pub fn dispatch_experience_orb_can_merge( from_value, can_merge: *can_merge, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "experience_orb_can_merge") { mod_hook.experience_orb_can_merge(host, &mut event); } *can_merge = event.can_merge; @@ -7633,7 +7633,7 @@ pub fn dispatch_experience_orb_merge( from, from_value, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "experience_orb_merge") { if matches!( mod_hook.experience_orb_merge(host, &mut event), Flow::Cancel @@ -7667,7 +7667,7 @@ pub fn dispatch_menu_slot_rules( may_place: *may_place, max_stack: *max_stack, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "menu_slot_rules") { mod_hook.menu_slot_rules(&mut event); } *may_place = event.may_place; @@ -7699,7 +7699,7 @@ pub fn dispatch_living_entity_use_item_tick( hand, duration: *duration, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "living_entity_use_item_tick") { if matches!( mod_hook.living_entity_use_item_tick(host, &mut event), Flow::Cancel @@ -7729,7 +7729,7 @@ pub fn dispatch_on_use_tick( entity, remaining, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "on_use_tick") { mod_hook.on_use_tick(host, &mut event); } } @@ -7759,7 +7759,7 @@ pub fn dispatch_living_entity_use_item_stop( hand, duration, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "living_entity_use_item_stop") { if matches!( mod_hook.living_entity_use_item_stop(host, &mut event), Flow::Cancel @@ -7791,7 +7791,7 @@ pub fn dispatch_release_using( time_left, used: *used, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "release_using") { mod_hook.release_using(host, &mut event); } *used = event.used; @@ -7817,7 +7817,7 @@ pub fn dispatch_loot_function( ctx, stack, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "loot_function") { mod_hook.loot_function(&mut event); } } @@ -7842,7 +7842,7 @@ pub fn dispatch_loot_condition( ctx, holds: *holds, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "loot_condition") { mod_hook.loot_condition(&mut event); } *holds = event.holds; @@ -7854,7 +7854,7 @@ pub struct LevelLoadEvent<'a> { } pub fn dispatch_level_load(host: &mut dyn Host, mods: &[Box], dimension: &str) { let mut event = LevelLoadEvent { dimension }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "level_load") { mod_hook.level_load(host, &mut event); } } @@ -7865,7 +7865,7 @@ pub struct LevelUnloadEvent<'a> { } pub fn dispatch_level_unload(host: &mut dyn Host, mods: &[Box], dimension: &str) { let mut event = LevelUnloadEvent { dimension }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "level_unload") { mod_hook.level_unload(host, &mut event); } } @@ -7876,7 +7876,7 @@ pub struct ClientLevelLoadEvent<'a> { } pub fn dispatch_client_level_load(host: &mut dyn Host, mods: &[Box], dimension: &str) { let mut event = ClientLevelLoadEvent { dimension }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "client_level_load") { mod_hook.client_level_load(host, &mut event); } } @@ -7887,7 +7887,7 @@ pub struct ClientLevelUnloadEvent<'a> { } pub fn dispatch_client_level_unload(host: &mut dyn Host, mods: &[Box], dimension: &str) { let mut event = ClientLevelUnloadEvent { dimension }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "client_level_unload") { mod_hook.client_level_unload(host, &mut event); } } @@ -7902,7 +7902,7 @@ pub fn dispatch_hears_projectile_impacts( hears: &mut bool, ) { let mut event = HearsProjectileImpactsEvent { hears: *hears }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "hears_projectile_impacts") { mod_hook.hears_projectile_impacts(host, &mut event); } *hears = event.hears; @@ -7948,7 +7948,7 @@ pub fn dispatch_projectile_impact( face, at, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "projectile_impact") { if matches!(mod_hook.projectile_impact(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -7987,7 +7987,7 @@ pub fn dispatch_entity_mount( vehicle_kind, mounting, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_mount") { if matches!(mod_hook.entity_mount(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -8020,7 +8020,7 @@ pub fn dispatch_interaction_key( hand, swing_hand: *swing_hand, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "interaction_key") { if matches!(mod_hook.interaction_key(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -8045,7 +8045,7 @@ pub fn dispatch_gui_layer_pre( return; } let mut event = GuiLayerPreEvent { layer, batch }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "gui_layer_pre") { if matches!(mod_hook.gui_layer_pre(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -8065,7 +8065,7 @@ pub fn dispatch_gui_layer_post( batch: &mut HudBatch, ) { let mut event = GuiLayerPostEvent { layer, batch }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "gui_layer_post") { mod_hook.gui_layer_post(host, &mut event); } } @@ -8082,7 +8082,7 @@ pub fn dispatch_map_decorations( decorations: &mut Vec, ) { let mut event = MapDecorationsEvent { map, decorations }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "map_decorations") { mod_hook.map_decorations(host, &mut event); } } @@ -8111,7 +8111,7 @@ pub fn dispatch_player_start_tracking( uuid, kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_start_tracking") { mod_hook.player_start_tracking(host, &mut event); } } @@ -8140,7 +8140,7 @@ pub fn dispatch_player_stop_tracking( uuid, kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_stop_tracking") { mod_hook.player_stop_tracking(host, &mut event); } } @@ -8159,7 +8159,7 @@ pub fn dispatch_block_entity_energy( return; } let mut event = BlockEntityEnergyEvent { block }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_entity_energy") { if let Some(replacement) = mod_hook.block_entity_energy(host, &mut event) { *energy = Some(replacement); break; @@ -8177,7 +8177,7 @@ pub fn dispatch_data_map_types( types: &mut Vec, ) { let mut event = DataMapTypesEvent { types }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "data_map_types") { mod_hook.data_map_types(host, &mut event); } } @@ -8205,7 +8205,7 @@ pub fn dispatch_living_breathe( consume: *consume, refill: *refill, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "living_breathe") { mod_hook.living_breathe(&mut event); } *can_breathe = event.can_breathe; @@ -8219,7 +8219,7 @@ pub struct BlocksEvent<'a> { } pub fn dispatch_blocks(mods: &[Box], blocks: &mut Vec) { let mut event = BlocksEvent { blocks }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "blocks") { mod_hook.blocks(&mut event); } } @@ -8230,7 +8230,7 @@ pub struct ItemsEvent<'a> { } pub fn dispatch_items(mods: &[Box], items: &mut Vec) { let mut event = ItemsEvent { items }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "items") { mod_hook.items(&mut event); } } @@ -8257,7 +8257,7 @@ pub fn dispatch_entity_tick_pre( entity, kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_tick_pre") { if matches!(mod_hook.entity_tick_pre(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -8283,7 +8283,7 @@ pub fn dispatch_entity_tick_post( entity, kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_tick_post") { mod_hook.entity_tick_post(host, &mut event); } } @@ -8300,7 +8300,7 @@ pub fn dispatch_entity_tick_listened( let mut event = EntityTickListenedEvent { listened: *listened, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_tick_listened") { mod_hook.entity_tick_listened(host, &mut event); } *listened = event.listened; @@ -8320,7 +8320,7 @@ pub fn dispatch_item_fluid_tank( return; } let mut event = ItemFluidTankEvent { item }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "item_fluid_tank") { if let Some(replacement) = mod_hook.item_fluid_tank(host, &mut event) { *capacity = Some(replacement); break; @@ -8352,7 +8352,7 @@ pub fn dispatch_living_equipment_change( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "living_equipment_change") { mod_hook.living_equipment_change(host, &mut event); } } @@ -8369,7 +8369,7 @@ pub fn dispatch_living_equipment_listened( let mut event = LivingEquipmentListenedEvent { listened: *listened, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "living_equipment_listened") { mod_hook.living_equipment_listened(host, &mut event); } *listened = event.listened; @@ -8393,7 +8393,7 @@ pub fn dispatch_player_submit( return; } let mut event = PlayerSubmitEvent { player, who, draw }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_submit") { if matches!(mod_hook.player_submit(host, &mut event), Flow::Cancel) { *drawn = true; break; @@ -8415,7 +8415,7 @@ pub fn dispatch_mob_layer( draw: &mut BlockEntityDraw, ) { let mut event = MobLayerEvent { mob, who, draw }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mob_layer") { mod_hook.mob_layer(host, &mut event); } } @@ -8432,7 +8432,7 @@ pub fn dispatch_player_render_listened( let mut event = PlayerRenderListenedEvent { listened: *listened, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_render_listened") { mod_hook.player_render_listened(host, &mut event); } *listened = event.listened; @@ -8469,7 +8469,7 @@ pub fn dispatch_sign_changed( front, lines, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "sign_changed") { if matches!(mod_hook.sign_changed(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -8483,7 +8483,7 @@ pub struct StandaloneModelsEvent<'a> { } pub fn dispatch_standalone_models(mods: &[Box], models: &mut Vec) { let mut event = StandaloneModelsEvent { models }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "standalone_models") { mod_hook.standalone_models(&mut event); } } @@ -8512,7 +8512,7 @@ pub fn dispatch_player_container_open( menu, pos, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_container_open") { mod_hook.player_container_open(host, &mut event); } } @@ -8541,7 +8541,7 @@ pub fn dispatch_player_container_close( menu, pos, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_container_close") { mod_hook.player_container_close(host, &mut event); } } @@ -8568,7 +8568,7 @@ pub fn dispatch_player_toggle_flight( name, flying, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_toggle_flight") { if matches!( mod_hook.player_toggle_flight(host, &mut event), Flow::Cancel @@ -8600,7 +8600,7 @@ pub fn dispatch_anvil_damaged( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "anvil_damaged") { mod_hook.anvil_damaged(host, &mut event); } } @@ -8627,7 +8627,7 @@ pub fn dispatch_arrow_loose( has_ammo, charge: *charge, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "arrow_loose") { if matches!(mod_hook.arrow_loose(host, &mut event), Flow::Cancel) { *canceled = true; break; @@ -8654,7 +8654,7 @@ pub fn dispatch_beacon_state_change( pos, active, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "beacon_state_change") { mod_hook.beacon_state_change(host, &mut event); } } @@ -8681,7 +8681,7 @@ pub fn dispatch_bell_ring( player, pos, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "bell_ring") { if matches!(mod_hook.bell_ring(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -8710,7 +8710,7 @@ pub fn dispatch_block_break_progress_update( pos, progress, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_break_progress_update") { mod_hook.block_break_progress_update(host, &mut event); } } @@ -8731,7 +8731,7 @@ pub fn dispatch_block_burn( return; } let mut event = BlockBurnEvent { dimension, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_burn") { if matches!(mod_hook.block_burn(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -8753,7 +8753,7 @@ pub fn dispatch_block_cook( result: &str, ) { let mut event = BlockCookEvent { pos, item, result }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_cook") { mod_hook.block_cook(host, &mut event); } } @@ -8779,7 +8779,7 @@ pub fn dispatch_block_dispense_armor( item, target, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_dispense_armor") { mod_hook.block_dispense_armor(host, &mut event); } } @@ -8805,7 +8805,7 @@ pub fn dispatch_block_exp( block, experience: *experience, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_exp") { mod_hook.block_exp(level, &mut event); } *experience = event.experience; @@ -8836,7 +8836,7 @@ pub fn dispatch_block_fade( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_fade") { if matches!(mod_hook.block_fade(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -8862,7 +8862,7 @@ pub fn dispatch_block_failed_dispense( pos, item, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_failed_dispense") { mod_hook.block_failed_dispense(host, &mut event); } } @@ -8892,7 +8892,7 @@ pub fn dispatch_block_form( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_form") { if matches!(mod_hook.block_form(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -8925,7 +8925,7 @@ pub fn dispatch_block_ignite( pos, cause, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_ignite") { if matches!(mod_hook.block_ignite(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -8951,7 +8951,7 @@ pub fn dispatch_block_lock_check( return; } let mut event = BlockLockCheckEvent { player, name, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_lock_check") { if matches!(mod_hook.block_lock_check(host, &mut event), Flow::Cancel) { *locked = true; break; @@ -8984,7 +8984,7 @@ pub fn dispatch_block_receive_game( block, event, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_receive_game") { if matches!(mod_hook.block_receive_game(host, &mut event_), Flow::Cancel) { *cancel = true; break; @@ -9013,7 +9013,7 @@ pub fn dispatch_block_shear_entity( entity, kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "block_shear_entity") { mod_hook.block_shear_entity(host, &mut event); } } @@ -9024,7 +9024,7 @@ pub struct BrewingCompleteEvent { } pub fn dispatch_brewing_complete(host: &dyn Host, mods: &[Box], pos: [i32; 3]) { let mut event = BrewingCompleteEvent { pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "brewing_complete") { mod_hook.brewing_complete(host, &mut event); } } @@ -9036,7 +9036,7 @@ pub struct BrewingFuelEvent<'a> { } pub fn dispatch_brewing_fuel(host: &dyn Host, mods: &[Box], pos: [i32; 3], fuel: &str) { let mut event = BrewingFuelEvent { pos, fuel }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "brewing_fuel") { mod_hook.brewing_fuel(host, &mut event); } } @@ -9053,7 +9053,7 @@ pub fn dispatch_brewing_start( ingredient: &str, ) { let mut event = BrewingStartEvent { pos, ingredient }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "brewing_start") { mod_hook.brewing_start(host, &mut event); } } @@ -9072,7 +9072,7 @@ pub fn dispatch_broadcast_message( return; } let mut event = BroadcastMessageEvent { line }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "broadcast_message") { if matches!(mod_hook.broadcast_message(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -9092,7 +9092,7 @@ pub fn dispatch_campfire_start( item: &str, ) { let mut event = CampfireStartEvent { pos, item }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "campfire_start") { mod_hook.campfire_start(host, &mut event); } } @@ -9128,7 +9128,7 @@ pub fn dispatch_cauldron_level_changed( to_level, reason, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "cauldron_level_changed") { if matches!( mod_hook.cauldron_level_changed(level, &mut event), Flow::Cancel @@ -9164,7 +9164,7 @@ pub fn dispatch_chorus_fruit_teleport( from, target, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "chorus_fruit_teleport") { if matches!( mod_hook.chorus_fruit_teleport(host, &mut event), Flow::Cancel @@ -9182,7 +9182,7 @@ pub struct CompostItemEvent<'a> { } pub fn dispatch_compost_item(host: &dyn Host, mods: &[Box], pos: [i32; 3], item: &str) { let mut event = CompostItemEvent { pos, item }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "compost_item") { mod_hook.compost_item(host, &mut event); } } @@ -9199,7 +9199,7 @@ pub fn dispatch_crafter_craft( recipe: &str, ) { let mut event = CrafterCraftEvent { pos, recipe }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "crafter_craft") { mod_hook.crafter_craft(host, &mut event); } } @@ -9222,7 +9222,7 @@ pub fn dispatch_creeper_ignite( player, item, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "creeper_ignite") { mod_hook.creeper_ignite(host, &mut event); } } @@ -9239,7 +9239,7 @@ pub fn dispatch_creeper_power( lightning: [f64; 3], ) { let mut event = CreeperPowerEvent { entity, lightning }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "creeper_power") { mod_hook.creeper_power(host, &mut event); } } @@ -9265,7 +9265,7 @@ pub fn dispatch_critical_hit( critical: *critical, damage_multiplier: *damage_multiplier, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "critical_hit") { mod_hook.critical_hit(host, &mut event); } *critical = event.critical; @@ -9284,7 +9284,7 @@ pub fn dispatch_difficulty_changed( to: &str, ) { let mut event = DifficultyChangedEvent { from, to }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "difficulty_changed") { mod_hook.difficulty_changed(host, &mut event); } } @@ -9305,7 +9305,7 @@ pub fn dispatch_dragon_egg_form( return; } let mut event = DragonEggFormEvent { dimension, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "dragon_egg_form") { if matches!(mod_hook.dragon_egg_form(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -9337,7 +9337,7 @@ pub fn dispatch_enchant_item( item, levels, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "enchant_item") { mod_hook.enchant_item(host, &mut event); } } @@ -9373,7 +9373,7 @@ pub fn dispatch_ender_pearl_teleport( target, damage: *damage, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "ender_pearl_teleport") { if matches!( mod_hook.ender_pearl_teleport(host, &mut event), Flow::Cancel @@ -9403,7 +9403,7 @@ pub fn dispatch_entities_load( chunk, count, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entities_load") { mod_hook.entities_load(host, &mut event); } } @@ -9426,7 +9426,7 @@ pub fn dispatch_entities_unload( chunk, count, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entities_unload") { mod_hook.entities_unload(host, &mut event); } } @@ -9445,7 +9445,7 @@ pub fn dispatch_entity_break_door( pos: [i32; 3], ) { let mut event = EntityBreakDoorEvent { entity, kind, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_break_door") { mod_hook.entity_break_door(host, &mut event); } } @@ -9468,7 +9468,7 @@ pub fn dispatch_entity_breed( partner, child, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_breed") { mod_hook.entity_breed(host, &mut event); } } @@ -9497,7 +9497,7 @@ pub fn dispatch_entity_change_block( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_change_block") { mod_hook.entity_change_block(host, &mut event); } } @@ -9523,7 +9523,7 @@ pub fn dispatch_entity_enter_block( pos, block, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_enter_block") { mod_hook.entity_enter_block(host, &mut event); } } @@ -9546,7 +9546,7 @@ pub fn dispatch_entity_enter_love_mode( kind, player, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_enter_love_mode") { mod_hook.entity_enter_love_mode(host, &mut event); } } @@ -9569,7 +9569,7 @@ pub fn dispatch_entity_portal( entity, pos, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_portal") { mod_hook.entity_portal(host, &mut event); } } @@ -9595,7 +9595,7 @@ pub fn dispatch_entity_pose_change( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_pose_change") { mod_hook.entity_pose_change(host, &mut event); } } @@ -9621,7 +9621,7 @@ pub fn dispatch_entity_shoot_bow( projectile, force, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_shoot_bow") { mod_hook.entity_shoot_bow(host, &mut event); } } @@ -9644,7 +9644,7 @@ pub fn dispatch_entity_tame( kind, owner, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_tame") { mod_hook.entity_tame(host, &mut event); } } @@ -9670,7 +9670,7 @@ pub fn dispatch_entity_teleport( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_teleport") { mod_hook.entity_teleport(host, &mut event); } } @@ -9693,7 +9693,7 @@ pub fn dispatch_entity_toggle_glide( name, gliding, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_toggle_glide") { mod_hook.entity_toggle_glide(host, &mut event); } } @@ -9719,7 +9719,7 @@ pub fn dispatch_entity_transform( transformed, transformed_kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "entity_transform") { mod_hook.entity_transform(host, &mut event); } } @@ -9736,7 +9736,7 @@ pub fn dispatch_exp_bottle( experience: u32, ) { let mut event = ExpBottleEvent { pos, experience }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "exp_bottle") { mod_hook.exp_bottle(host, &mut event); } } @@ -9753,7 +9753,7 @@ pub fn dispatch_experience_orb_pickup_listened( let mut event = ExperienceOrbPickupListenedEvent { listened: *listened, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "experience_orb_pickup_listened") { mod_hook.experience_orb_pickup_listened(host, &mut event); } *listened = event.listened; @@ -9787,7 +9787,7 @@ pub fn dispatch_experience_orb_pickup( value: *value, count: *count, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "experience_orb_pickup") { if matches!( mod_hook.experience_orb_pickup(host, &mut event), Flow::Cancel @@ -9821,7 +9821,7 @@ pub fn dispatch_mending_repair( experience, repair: *repair, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "mending_repair") { mod_hook.mending_repair(host, &mut event); } *repair = event.repair; @@ -9843,7 +9843,7 @@ pub fn dispatch_fire_odds( return; } let mut event = FireOddsEvent { dimension, state }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "fire_odds") { if let Some(replacement) = mod_hook.fire_odds(level, &mut event) { *odds = Some(replacement); break; @@ -9867,7 +9867,7 @@ pub fn dispatch_smoke_source( return; } let mut event = SmokeSourceEvent { dimension, state }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "smoke_source") { if let Some(replacement) = mod_hook.smoke_source(level, &mut event) { *smoke = Some(replacement); break; @@ -9893,7 +9893,7 @@ pub fn dispatch_firework_explode( pos, bursts, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "firework_explode") { mod_hook.firework_explode(host, &mut event); } } @@ -9926,7 +9926,7 @@ pub fn dispatch_fluid_level_change( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "fluid_level_change") { if matches!(mod_hook.fluid_level_change(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -9955,7 +9955,7 @@ pub fn dispatch_framerate_limit( in_world, limit: *limit, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "framerate_limit") { mod_hook.framerate_limit(host, &mut event); } *limit = event.limit; @@ -9968,7 +9968,7 @@ pub struct FurnaceBurnEvent<'a> { } pub fn dispatch_furnace_burn(host: &dyn Host, mods: &[Box], pos: [i32; 3], fuel: &str) { let mut event = FurnaceBurnEvent { pos, fuel }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "furnace_burn") { mod_hook.furnace_burn(host, &mut event); } } @@ -9997,7 +9997,7 @@ pub fn dispatch_furnace_extract( item, count, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "furnace_extract") { mod_hook.furnace_extract(host, &mut event); } } @@ -10016,7 +10016,7 @@ pub fn dispatch_furnace_smelt( result: &str, ) { let mut event = FurnaceSmeltEvent { pos, item, result }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "furnace_smelt") { mod_hook.furnace_smelt(host, &mut event); } } @@ -10033,7 +10033,7 @@ pub fn dispatch_furnace_start_smelt( item: &str, ) { let mut event = FurnaceStartSmeltEvent { pos, item }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "furnace_start_smelt") { mod_hook.furnace_start_smelt(host, &mut event); } } @@ -10050,7 +10050,7 @@ pub fn dispatch_game_event( pos: [f64; 3], ) { let mut event_ = GameEventEvent { event, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "game_event") { mod_hook.game_event(host, &mut event_); } } @@ -10080,7 +10080,7 @@ pub fn dispatch_hopper_pickup_item( item, count, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "hopper_pickup_item") { if matches!(mod_hook.hopper_pickup_item(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10101,7 +10101,7 @@ pub fn dispatch_ingredient( items: &mut Vec, ) { let mut event = IngredientEvent { kind, data, items }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "ingredient") { mod_hook.ingredient(&mut event); } } @@ -10124,7 +10124,7 @@ pub fn dispatch_inventory_block_start( return; } let mut event = InventoryBlockStartEvent { player, name, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "inventory_block_start") { if matches!( mod_hook.inventory_block_start(host, &mut event), Flow::Cancel @@ -10153,7 +10153,7 @@ pub fn dispatch_item_crafted( recipe, stack, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "item_crafted") { mod_hook.item_crafted(host, &mut event); } } @@ -10172,7 +10172,7 @@ pub fn dispatch_item_energy_buffer( return; } let mut event = ItemEnergyBufferEvent { item }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "item_energy_buffer") { if let Some(replacement) = mod_hook.item_energy_buffer(host, &mut event) { *buffer = Some(replacement); break; @@ -10201,7 +10201,7 @@ pub fn dispatch_item_spawn( count, pos, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "item_spawn") { mod_hook.item_spawn(host, &mut event); } } @@ -10222,7 +10222,7 @@ pub fn dispatch_leaves_decay( return; } let mut event = LeavesDecayEvent { dimension, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "leaves_decay") { if matches!(mod_hook.leaves_decay(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10248,7 +10248,7 @@ pub fn dispatch_lightning_strike( return; } let mut event = LightningStrikeEvent { player, pos, cause }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "lightning_strike") { if matches!(mod_hook.lightning_strike(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10284,7 +10284,7 @@ pub fn dispatch_menu_quick_move( slot, stack, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "menu_quick_move") { if matches!(mod_hook.menu_quick_move(host, &mut event), Flow::Cancel) { *handled = true; break; @@ -10317,7 +10317,7 @@ pub fn dispatch_moisture_change( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "moisture_change") { if matches!(mod_hook.moisture_change(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10350,7 +10350,7 @@ pub fn dispatch_armor_stand_manipulate( stand_id, slot, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "armor_stand_manipulate") { if matches!( mod_hook.armor_stand_manipulate(host, &mut event), Flow::Cancel @@ -10386,7 +10386,7 @@ pub fn dispatch_bucket_empty( pos, fluid, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "bucket_empty") { if matches!(mod_hook.bucket_empty(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10419,7 +10419,7 @@ pub fn dispatch_container_opened( kind, pos, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "container_opened") { if matches!(mod_hook.container_opened(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10455,7 +10455,7 @@ pub fn dispatch_creative_slot( item, count, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "creative_slot") { if matches!(mod_hook.creative_slot(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10488,7 +10488,7 @@ pub fn dispatch_food_level_changed( from, to: *to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "food_level_changed") { if matches!(mod_hook.food_level_changed(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10515,7 +10515,7 @@ pub fn dispatch_hanging_break( return; } let mut event = HangingBreakEvent { player, kind, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "hanging_break") { if matches!(mod_hook.hanging_break(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10548,7 +10548,7 @@ pub fn dispatch_hanging_place( kind, pos, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "hanging_place") { if matches!(mod_hook.hanging_place(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10581,7 +10581,7 @@ pub fn dispatch_item_damaged( item, amount: *amount, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "item_damaged") { if matches!(mod_hook.item_damaged(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10611,7 +10611,7 @@ pub fn dispatch_player_changed_dimension( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_changed_dimension") { mod_hook.player_changed_dimension(host, &mut event); } } @@ -10634,7 +10634,7 @@ pub fn dispatch_player_clone( name, was_death, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_clone") { mod_hook.player_clone(host, &mut event); } } @@ -10657,7 +10657,7 @@ pub fn dispatch_player_commands_sent( name, names, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_commands_sent") { mod_hook.player_commands_sent(host, &mut event); } } @@ -10683,7 +10683,7 @@ pub fn dispatch_player_destroy_item( item, slot, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_destroy_item") { mod_hook.player_destroy_item(host, &mut event); } } @@ -10710,7 +10710,7 @@ pub fn dispatch_player_fish( name, state, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_fish") { if matches!(mod_hook.player_fish(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10739,7 +10739,7 @@ pub fn dispatch_player_flower_pot_manipulate( pos, plant, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_flower_pot_manipulate") { mod_hook.player_flower_pot_manipulate(host, &mut event); } } @@ -10769,7 +10769,7 @@ pub fn dispatch_player_game_mode_changed( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_game_mode_changed") { if matches!( mod_hook.player_game_mode_changed(host, &mut event), Flow::Cancel @@ -10801,7 +10801,7 @@ pub fn dispatch_player_insert_lectern_book( pos, book, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_insert_lectern_book") { mod_hook.player_insert_lectern_book(host, &mut event); } } @@ -10833,7 +10833,7 @@ pub fn dispatch_player_item_frame_change( item, rotation, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_item_frame_change") { mod_hook.player_item_frame_change(host, &mut event); } } @@ -10862,7 +10862,7 @@ pub fn dispatch_player_item_mend( repair, experience, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_item_mend") { mod_hook.player_item_mend(host, &mut event); } } @@ -10888,7 +10888,7 @@ pub fn dispatch_player_lectern_page_change( pos, page, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_lectern_page_change") { mod_hook.player_lectern_page_change(host, &mut event); } } @@ -10911,7 +10911,7 @@ pub fn dispatch_player_load_from_file( name, directory, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_load_from_file") { mod_hook.player_load_from_file(host, &mut event); } } @@ -10938,7 +10938,7 @@ pub fn dispatch_player_login( name, reason, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_login") { if matches!(mod_hook.player_login(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -10964,7 +10964,7 @@ pub fn dispatch_player_save_to_file( name, directory, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_save_to_file") { mod_hook.player_save_to_file(host, &mut event); } } @@ -10987,7 +10987,7 @@ pub fn dispatch_player_sprint( name, sprinting, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_sprint") { mod_hook.player_sprint(host, &mut event); } } @@ -11008,7 +11008,7 @@ pub fn dispatch_player_swap_hands( return; } let mut event = PlayerSwapHandsEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_swap_hands") { if matches!(mod_hook.player_swap_hands(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -11037,7 +11037,7 @@ pub fn dispatch_player_take_lectern_book( pos, book, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_take_lectern_book") { mod_hook.player_take_lectern_book(host, &mut event); } } @@ -11066,7 +11066,7 @@ pub fn dispatch_player_teleported( to, dimension, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_teleported") { mod_hook.player_teleported(host, &mut event); } } @@ -11083,7 +11083,7 @@ pub fn dispatch_player_totem( name: &str, ) { let mut event = PlayerTotemEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_totem") { mod_hook.player_totem(host, &mut event); } } @@ -11106,7 +11106,7 @@ pub fn dispatch_resource_pack_status( name, status, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "resource_pack_status") { mod_hook.resource_pack_status(host, &mut event); } } @@ -11123,7 +11123,7 @@ pub fn dispatch_spawn_change( angle: [f32; 2], ) { let mut event = SpawnChangeEvent { pos, angle }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "spawn_change") { mod_hook.spawn_change(host, &mut event); } } @@ -11144,7 +11144,7 @@ pub fn dispatch_tnt_primed( return; } let mut event = TntPrimedEvent { player, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "tnt_primed") { if matches!(mod_hook.tnt_primed(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -11173,7 +11173,7 @@ pub fn dispatch_vehicle_moved( from, to, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "vehicle_moved") { mod_hook.vehicle_moved(host, &mut event); } } @@ -11182,7 +11182,7 @@ pub fn dispatch_vehicle_moved( pub struct WorldBorderBoundsChangedEvent {} pub fn dispatch_world_border_bounds_changed(host: &mut dyn Host, mods: &[Box]) { let mut event = WorldBorderBoundsChangedEvent {}; - for mod_hook in mods { + for mod_hook in super::entered(mods, "world_border_bounds_changed") { mod_hook.world_border_bounds_changed(host, &mut event); } } @@ -11191,7 +11191,7 @@ pub fn dispatch_world_border_bounds_changed(host: &mut dyn Host, mods: &[Box]) { let mut event = WorldBorderCenterChangedEvent {}; - for mod_hook in mods { + for mod_hook in super::entered(mods, "world_border_center_changed") { mod_hook.world_border_center_changed(host, &mut event); } } @@ -11217,7 +11217,7 @@ pub fn dispatch_world_game_rule_change( rule, value, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "world_game_rule_change") { mod_hook.world_game_rule_change(host, &mut event); } } @@ -11250,7 +11250,7 @@ pub fn dispatch_note_play( instrument, note, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "note_play") { if matches!(mod_hook.note_play(level, &mut event), Flow::Cancel) { *cancel = true; break; @@ -11276,7 +11276,7 @@ pub fn dispatch_player_advancement_done( name, advancement, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_advancement_done") { mod_hook.player_advancement_done(host, &mut event); } } @@ -11305,7 +11305,7 @@ pub fn dispatch_player_advancement_progress( criterion, granted, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_advancement_progress") { mod_hook.player_advancement_progress(host, &mut event); } } @@ -11322,7 +11322,7 @@ pub fn dispatch_player_attack_cooldown_reset( name: &str, ) { let mut event = PlayerAttackCooldownResetEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_attack_cooldown_reset") { mod_hook.player_attack_cooldown_reset(host, &mut event); } } @@ -11345,7 +11345,7 @@ pub fn dispatch_player_bed_enter( return; } let mut event = PlayerBedEnterEvent { player, name, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_bed_enter") { if matches!(mod_hook.player_bed_enter(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -11367,7 +11367,7 @@ pub fn dispatch_player_bed_leave( pos: [i32; 3], ) { let mut event = PlayerBedLeaveEvent { player, name, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_bed_leave") { mod_hook.player_bed_leave(host, &mut event); } } @@ -11393,7 +11393,7 @@ pub fn dispatch_player_bucket_entity( entity_id, entity, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_bucket_entity") { mod_hook.player_bucket_entity(host, &mut event); } } @@ -11422,7 +11422,7 @@ pub fn dispatch_player_change_beacon_effect( primary, secondary, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_change_beacon_effect") { mod_hook.player_change_beacon_effect(host, &mut event); } } @@ -11441,7 +11441,7 @@ pub fn dispatch_player_change_main_hand( left: bool, ) { let mut event = PlayerChangeMainHandEvent { player, name, left }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_change_main_hand") { mod_hook.player_change_main_hand(host, &mut event); } } @@ -11458,7 +11458,7 @@ pub fn dispatch_player_deep_sleep( name: &str, ) { let mut event = PlayerDeepSleepEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_deep_sleep") { mod_hook.player_deep_sleep(host, &mut event); } } @@ -11488,7 +11488,7 @@ pub fn dispatch_player_edit_book( pages, signing, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_edit_book") { if matches!(mod_hook.player_edit_book(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -11508,7 +11508,7 @@ pub fn dispatch_player_egg_throw( name: &str, ) { let mut event = PlayerEggThrowEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_egg_throw") { mod_hook.player_egg_throw(host, &mut event); } } @@ -11525,7 +11525,7 @@ pub fn dispatch_player_elytra_boost( name: &str, ) { let mut event = PlayerElytraBoostEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_elytra_boost") { mod_hook.player_elytra_boost(host, &mut event); } } @@ -11548,7 +11548,7 @@ pub fn dispatch_player_exp_change( name, amount: *amount, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_exp_change") { mod_hook.player_exp_change(host, &mut event); } *amount = event.amount; @@ -11572,7 +11572,7 @@ pub fn dispatch_player_exp_cooldown_change( name, ticks, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_exp_cooldown_change") { mod_hook.player_exp_cooldown_change(host, &mut event); } } @@ -11602,7 +11602,7 @@ pub fn dispatch_player_item_cooldown( item, ticks, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_item_cooldown") { if matches!( mod_hook.player_item_cooldown(host, &mut event), Flow::Cancel @@ -11638,7 +11638,7 @@ pub fn dispatch_player_item_held( from_slot, to_slot, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_item_held") { if matches!(mod_hook.player_item_held(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -11664,7 +11664,7 @@ pub fn dispatch_player_locale_change( name, locale, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_locale_change") { mod_hook.player_locale_change(host, &mut event); } } @@ -11687,7 +11687,7 @@ pub fn dispatch_player_loom_pattern_select( name, pattern, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_loom_pattern_select") { mod_hook.player_loom_pattern_select(host, &mut event); } } @@ -11710,7 +11710,7 @@ pub fn dispatch_player_map_filled( name, map_id, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_map_filled") { mod_hook.player_map_filled(host, &mut event); } } @@ -11736,7 +11736,7 @@ pub fn dispatch_player_name_entity( entity_id, entity_name, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_name_entity") { mod_hook.player_name_entity(host, &mut event); } } @@ -11762,7 +11762,7 @@ pub fn dispatch_player_open_sign( pos, front, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_open_sign") { mod_hook.player_open_sign(host, &mut event); } } @@ -11795,7 +11795,7 @@ pub fn dispatch_player_pick_item( pos, entity_id, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_pick_item") { if matches!(mod_hook.player_pick_item(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -11824,7 +11824,7 @@ pub fn dispatch_player_pickup_arrow( entity_id, item, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_pickup_arrow") { mod_hook.player_pickup_arrow(host, &mut event); } } @@ -11857,7 +11857,7 @@ pub fn dispatch_player_portal( to_dimension, cause, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_portal") { if matches!(mod_hook.player_portal(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -11886,7 +11886,7 @@ pub fn dispatch_player_recipe_book_click( recipe, all, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_recipe_book_click") { mod_hook.player_recipe_book_click(host, &mut event); } } @@ -11913,7 +11913,7 @@ pub fn dispatch_player_recipe_discovered( name, recipe, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_recipe_discovered") { if matches!( mod_hook.player_recipe_discovered(host, &mut event), Flow::Cancel @@ -11936,7 +11936,7 @@ pub fn dispatch_player_riptide( name: &str, ) { let mut event = PlayerRiptideEvent { player, name }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_riptide") { mod_hook.player_riptide(host, &mut event); } } @@ -11966,7 +11966,7 @@ pub fn dispatch_player_shear_entity( entity_id, off_hand, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_shear_entity") { if matches!(mod_hook.player_shear_entity(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -11992,7 +11992,7 @@ pub fn dispatch_player_shield_disable( name, ticks, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_shield_disable") { mod_hook.player_shield_disable(host, &mut event); } } @@ -12025,7 +12025,7 @@ pub fn dispatch_player_spawn_point_set( pos, cause, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_spawn_point_set") { if matches!( mod_hook.player_spawn_point_set(host, &mut event), Flow::Cancel @@ -12064,7 +12064,7 @@ pub fn dispatch_player_stat_award( stat, value, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_stat_award") { if matches!(mod_hook.player_stat_award(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -12090,7 +12090,7 @@ pub fn dispatch_player_stonecutter_recipe_select( name, recipe, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_stonecutter_recipe_select") { mod_hook.player_stonecutter_recipe_select(host, &mut event); } } @@ -12113,7 +12113,7 @@ pub fn dispatch_player_stop_spectating_entity( name, entity_id, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_stop_spectating_entity") { mod_hook.player_stop_spectating_entity(host, &mut event); } } @@ -12132,7 +12132,7 @@ pub fn dispatch_player_swap_with_equipment_slot( slot: &str, ) { let mut event = PlayerSwapWithEquipmentSlotEvent { player, name, slot }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_swap_with_equipment_slot") { mod_hook.player_swap_with_equipment_slot(host, &mut event); } } @@ -12159,7 +12159,7 @@ pub fn dispatch_player_teleport_end_gateway( name, gateway, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_teleport_end_gateway") { if matches!( mod_hook.player_teleport_end_gateway(host, &mut event), Flow::Cancel @@ -12191,7 +12191,7 @@ pub fn dispatch_player_toggle_entity_age_lock( entity_id, locked, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_toggle_entity_age_lock") { mod_hook.player_toggle_entity_age_lock(host, &mut event); } } @@ -12214,7 +12214,7 @@ pub fn dispatch_player_trade( name, entity_id, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_trade") { mod_hook.player_trade(host, &mut event); } } @@ -12237,7 +12237,7 @@ pub fn dispatch_player_unleash_entity( name, entity_id, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_unleash_entity") { mod_hook.player_unleash_entity(host, &mut event); } } @@ -12260,7 +12260,7 @@ pub fn dispatch_player_velocity( name, velocity, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "player_velocity") { mod_hook.player_velocity(host, &mut event); } } @@ -12277,7 +12277,7 @@ pub fn dispatch_portal_create( pos: [i32; 3], ) { let mut event = PortalCreateEvent { dimension, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "portal_create") { mod_hook.portal_create(host, &mut event); } } @@ -12294,7 +12294,7 @@ pub fn dispatch_potion_splash( pos: [f64; 3], ) { let mut event = PotionSplashEvent { item, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "potion_splash") { mod_hook.potion_splash(host, &mut event); } } @@ -12324,7 +12324,7 @@ pub fn dispatch_prepare_anvil( pos, cost: *cost, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "prepare_anvil") { if let Some(replacement) = mod_hook.prepare_anvil(host, &mut event) { *result = Some(replacement); break; @@ -12351,7 +12351,7 @@ pub fn dispatch_prepare_grindstone( return; } let mut event = PrepareGrindstoneEvent { player, name, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "prepare_grindstone") { if let Some(replacement) = mod_hook.prepare_grindstone(host, &mut event) { *result = Some(replacement); break; @@ -12377,7 +12377,7 @@ pub fn dispatch_prepare_item_craft( return; } let mut event = PrepareItemCraftEvent { player, name, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "prepare_item_craft") { if let Some(replacement) = mod_hook.prepare_item_craft(host, &mut event) { *result = Some(replacement); break; @@ -12406,7 +12406,7 @@ pub fn dispatch_prepare_item_enchant( pos, costs, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "prepare_item_enchant") { mod_hook.prepare_item_enchant(host, &mut event); } } @@ -12429,7 +12429,7 @@ pub fn dispatch_prepare_smithing( return; } let mut event = PrepareSmithingEvent { player, name, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "prepare_smithing") { if let Some(replacement) = mod_hook.prepare_smithing(host, &mut event) { *result = Some(replacement); break; @@ -12458,7 +12458,7 @@ pub fn dispatch_projectile_launch( entity, kind, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "projectile_launch") { mod_hook.projectile_launch(host, &mut event); } } @@ -12484,7 +12484,7 @@ pub fn dispatch_raid_spawn_wave( wave, raiders, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "raid_spawn_wave") { mod_hook.raid_spawn_wave(host, &mut event); } } @@ -12503,7 +12503,7 @@ pub fn dispatch_raid_state_change( state: &str, ) { let mut event = RaidStateChangeEvent { raid, pos, state }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "raid_state_change") { mod_hook.raid_state_change(host, &mut event); } } @@ -12520,7 +12520,7 @@ pub fn dispatch_sculk_bloom( pos: [i32; 3], ) { let mut event = SculkBloomEvent { dimension, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "sculk_bloom") { mod_hook.sculk_bloom(host, &mut event); } } @@ -12543,7 +12543,7 @@ pub fn dispatch_sleep_finished_time( current, new_time: *new_time, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "sleep_finished_time") { mod_hook.sleep_finished_time(host, &mut event); } *new_time = event.new_time; @@ -12561,7 +12561,7 @@ pub fn dispatch_sponge_absorb( pos: BlockPos, ) { let mut event = SpongeAbsorbEvent { dimension, pos }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "sponge_absorb") { mod_hook.sponge_absorb(level, &mut event); } } @@ -12590,7 +12590,7 @@ pub fn dispatch_tab_complete( range, suggestions, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "tab_complete") { mod_hook.tab_complete(host, &mut event); } } @@ -12613,7 +12613,7 @@ pub fn dispatch_target_hit( pos, strength, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "target_hit") { mod_hook.target_hit(host, &mut event); } } @@ -12637,7 +12637,7 @@ pub fn dispatch_thunder_change( dimension, thundering, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "thunder_change") { if matches!(mod_hook.thunder_change(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -12670,7 +12670,7 @@ pub fn dispatch_time_skip( to, cause, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "time_skip") { if matches!(mod_hook.time_skip(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -12699,7 +12699,7 @@ pub fn dispatch_trade_select( villager, index, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "trade_select") { mod_hook.trade_select(host, &mut event); } } @@ -12722,7 +12722,7 @@ pub fn dispatch_trade_with_villager( kind, offer, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "trade_with_villager") { mod_hook.trade_with_villager(host, &mut event); } } @@ -12745,7 +12745,7 @@ pub fn dispatch_vault_change_state( pos, state, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "vault_change_state") { mod_hook.vault_change_state(host, &mut event); } } @@ -12772,7 +12772,7 @@ pub fn dispatch_weather_change( raining, thundering, }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "weather_change") { if matches!(mod_hook.weather_change(host, &mut event), Flow::Cancel) { *cancel = true; break; @@ -12790,7 +12790,7 @@ pub fn dispatch_whitelist_state_update( enabled: bool, ) { let mut event = WhitelistStateUpdateEvent { enabled }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "whitelist_state_update") { mod_hook.whitelist_state_update(host, &mut event); } } @@ -12801,7 +12801,7 @@ pub struct WorldSavedEvent { } pub fn dispatch_world_saved(host: &mut dyn Host, mods: &[Box], wait: bool) { let mut event = WorldSavedEvent { wait }; - for mod_hook in mods { + for mod_hook in super::entered(mods, "world_saved") { mod_hook.world_saved(host, &mut event); } } diff --git a/docs/native-mods.md b/docs/native-mods.md index 9b8765ac3b..8f429ccb08 100644 --- a/docs/native-mods.md +++ b/docs/native-mods.md @@ -2148,6 +2148,12 @@ another mod's hook object is not exposed. Trait dispatch follows dependency order, with ties kept in bundle order. Mixin injection order remains horizon-mixins' priority, mod ID, then injection ID; dependency order does not change injection order. + +A panic in a trait mod's hook adds `in native mod , hook ` to the panic's message, in the crash report +and in the server thread's log line, with the bundle's `[mod] id` (the generated executable passes the ids to +`mod_api::name_mods`; a build that doesn't gives the mod's place in dispatch order, `#0` first). The game still +stops as before. Render hooks and trait injections are not named yet. + A bundle with an `[api]` package may declare its own injection in the trait: ```toml diff --git a/launcher/src/native_mods/api.rs b/launcher/src/native_mods/api.rs index f20f6f5234..b890b50d92 100644 --- a/launcher/src/native_mods/api.rs +++ b/launcher/src/native_mods/api.rs @@ -79,10 +79,24 @@ fn path_dep(path: &str) -> toml::Value { toml::Value::Table(toml::Table::from_iter([("path".into(), path.into())])) } -fn main_rs(count: usize) -> String { - let entries = (0..count) +/// Whether the staged revision names its trait mods (`mod_api::name_mods`, which a panic in a +/// hook names its mod by); an older one takes the list alone. +fn names_mods(stage: &Path) -> bool { + fs::read_to_string(stage.join("crates/horizon-client/src/mod_api.rs")) + .is_ok_and(|text| text.contains("pub fn name_mods(")) +} + +/// The generated executable's `main`: the trait mods of bundles `ids`, in that order, named by +/// those ids when `named`. +fn main_rs(ids: &[&str], named: bool) -> String { + let entries = (0..ids.len()) .map(|i| format!(" mod_{i}::hooks(),\n")) .collect::(); + let naming = if named { + format!(" horizon_client::mod_api::name_mods(&{ids:?});\n") + } else { + String::new() + }; // Mirrors crates/horizon-client/src/main.rs, with trait mods passed to main_with. format!( r#"//! Generated by the launcher. @@ -97,7 +111,7 @@ fn main() {{ std::hint::black_box(&MOD_API_LEVEL); let mods: horizon_client::mod_api::Mods = vec![ {entries} ].into(); - horizon_client::entry::main_with(mods); +{naming} horizon_client::entry::main_with(mods); }} "# ) @@ -258,7 +272,9 @@ pub(super) fn stage( )])), ); write(&game.join("Cargo.toml"), &manifest)?; - fs::write(game.join("src/main.rs"), main_rs(mods.len())).map_err(|e| e.to_string())?; + let ids: Vec<_> = mods.iter().map(|(_, bundle)| bundle.id.as_str()).collect(); + fs::write(game.join("src/main.rs"), main_rs(&ids, names_mods(stage))) + .map_err(|e| e.to_string())?; let root = stage.join("Cargo.toml"); let mut workspace = read(&root)?; let list = workspace @@ -330,16 +346,25 @@ mod tests { #[test] fn generated_main_keeps_mod_order() { + let ids = ["base", "extra"]; for count in 0..=2 { - let text = main_rs(count); + let text = main_rs(&ids[..count], false); assert!(text.contains("entry::main_with(mods)")); assert_eq!(text.matches("::hooks()").count(), count); + assert!(!text.contains("name_mods")); if count == 2 { assert!( text.find("mod_0::hooks()").unwrap() < text.find("mod_1::hooks()").unwrap() ); } } + // A revision that names its mods gets the ids in the same order, before main_with. + let named = main_rs(&ids, true); + let naming = named + .find(r#"mod_api::name_mods(&["base", "extra"]);"#) + .unwrap(); + assert!(named.find("mod_1::hooks()").unwrap() < naming); + assert!(naming < named.find("entry::main_with(mods)").unwrap()); } #[test] @@ -397,6 +422,18 @@ mod tests { game["features"]["default"][0].as_str(), Some("horizon-client/default") ); + let main = || fs::read_to_string(stage_dir.join(GAME).join("src/main.rs")).unwrap(); + assert!(!main().contains("name_mods")); + // A revision with `mod_api::name_mods` gets each bundle's id. + fs::create_dir_all(stage_dir.join("crates/horizon-client/src")).unwrap(); + fs::write( + stage_dir.join("crates/horizon-client/src/mod_api.rs"), + "pub fn name_mods(ids: &'static [&'static str]) {}\n", + ) + .unwrap(); + let bundle = super::super::bundle(&dir, None).unwrap(); + stage(&stage_dir, &[bundle], &[vec![]], &resolution).unwrap(); + assert!(main().contains(r#"name_mods(&["example"]);"#)); fs::remove_dir_all(dir).unwrap(); } diff --git a/xtask/src/mod_api.rs b/xtask/src/mod_api.rs index a32cf4ee25..3f72fddbbb 100644 --- a/xtask/src/mod_api.rs +++ b/xtask/src/mod_api.rs @@ -853,17 +853,23 @@ fn generate(root: &Path, check: bool) -> Result<(), String> { "/// What [`{trait_name}::{name}`] is told. Fields may be added: the struct is `#[non_exhaustive]`.\n#[non_exhaustive]\npub struct {event_type}{generics} {{\n{fields}}}\n" )); let build = format!("let mut {event} = {event_type} {{ {} }};", inits.join(", ")); + // A trait mod's call is marked with the mod for a panic to name; render hooks are called bare. + let each = if is_render { + mod_list.clone() + } else { + format!("super::entered({mod_list}, \"{name}\")") + }; let body = match contract { "cancel" => format!( - "if *{o} {{ return; }} {build} for {mod_item} in {mod_list} {{ if matches!({mod_item}.{name}({invoke}), Flow::Cancel) {{ *{o} = true; break; }} }} {write_back}", + "if *{o} {{ return; }} {build} for {mod_item} in {each} {{ if matches!({mod_item}.{name}({invoke}), Flow::Cancel) {{ *{o} = true; break; }} }} {write_back}", o = out.unwrap() ), "replace" => format!( - "if {o}.is_some() {{ return; }} {build} for {mod_item} in {mod_list} {{ if let Some({replacement}) = {mod_item}.{name}({invoke}) {{ *{o} = Some({replacement}); break; }} }} {write_back}", + "if {o}.is_some() {{ return; }} {build} for {mod_item} in {each} {{ if let Some({replacement}) = {mod_item}.{name}({invoke}) {{ *{o} = Some({replacement}); break; }} }} {write_back}", o = out.unwrap() ), _ => format!( - "{build} for {mod_item} in {mod_list} {{ {mod_item}.{name}({invoke}); }} {write_back}" + "{build} for {mod_item} in {each} {{ {mod_item}.{name}({invoke}); }} {write_back}" ), }; dispatch.push_str(&format!( @@ -1143,6 +1149,19 @@ mod tests { )); } use generated::*; + thread_local! { + /// The hooks each dispatch entered, a mod at a time. + static ENTERED: std::cell::RefCell> = const { std::cell::RefCell::new(Vec::new()) }; + } + fn entered<'a>( + mods: &'a [Box], + hook: &'static str, + ) -> impl Iterator> { + mods.iter().enumerate().map(move |(index, hooks)| { + ENTERED.with(|entered| entered.borrow_mut().push((index, hook))); + hooks + }) + } struct Mod { id: u32, calls: Arc>>, @@ -1317,6 +1336,9 @@ mod tests { dispatch_mouse_button_pre(&mut TestHost, &mods, 0, true, 0, &mut canceled); assert!(canceled); assert_eq!(*calls.lock().unwrap(), [1]); + // Each call is entered under the hook's name; the cancelled one's is the last. + let entered = ENTERED.with(|entered| entered.take()); + assert_eq!(entered, [(0, "mouse_button_pre")]); } #[test]