mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
feat(wasm-api): add ServerTickStartEvent (#2099)
* feat(plugin-api): add ServerTickStartEvent Add a non-cancellable event fired at the start of every server tick, carrying the 0-indexed tick number. Wires through all five layers: WIT contract, plugin-api guest binding, runtime host struct, WASM bridge, and the ticker fire site. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix ci/ fmt --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
pub mod server_broadcast;
|
||||
pub mod server_command;
|
||||
pub mod server_tick_start;
|
||||
pub mod spawn_change;
|
||||
|
||||
pub use server_broadcast::*;
|
||||
pub use server_command::*;
|
||||
pub use server_tick_start::*;
|
||||
pub use spawn_change::*;
|
||||
|
||||
25
pumpkin-plugin-api/src/events/server/server_tick_start.rs
Normal file
25
pumpkin-plugin-api/src/events/server/server_tick_start.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use crate::wit::pumpkin::plugin::event::{Event, EventType, ServerTickStartEventData};
|
||||
|
||||
use super::super::FromIntoEvent;
|
||||
|
||||
/// An event that fires at the start of every server tick (~20 Hz under the
|
||||
/// default tick rate).
|
||||
///
|
||||
/// The associated [`ServerTickStartEventData`] carries the 0-indexed `tick`
|
||||
/// number of the tick about to run. This event is non-cancellable.
|
||||
pub struct ServerTickStartEvent;
|
||||
impl FromIntoEvent for ServerTickStartEvent {
|
||||
const EVENT_TYPE: EventType = EventType::ServerTickStartEvent;
|
||||
type Data = ServerTickStartEventData;
|
||||
|
||||
fn data_from_event(event: Event) -> Self::Data {
|
||||
match event {
|
||||
Event::ServerTickStartEvent(data) => data,
|
||||
_ => panic!("unexpected event"),
|
||||
}
|
||||
}
|
||||
|
||||
fn data_into_event(data: Self::Data) -> Event {
|
||||
Event::ServerTickStartEvent(data)
|
||||
}
|
||||
}
|
||||
@@ -294,6 +294,10 @@ interface event {
|
||||
cancelled: bool
|
||||
}
|
||||
|
||||
record server-tick-start-event-data {
|
||||
tick: s32
|
||||
}
|
||||
|
||||
record packet-received-event-data {
|
||||
player: player,
|
||||
packet: serverbound-packet,
|
||||
@@ -341,6 +345,7 @@ interface event {
|
||||
server-command-event,
|
||||
spawn-change-event,
|
||||
server-broadcast-event,
|
||||
server-tick-start-event,
|
||||
packet-received-event,
|
||||
packet-sent-event,
|
||||
}
|
||||
@@ -380,6 +385,7 @@ interface event {
|
||||
server-command-event(server-command-event-data),
|
||||
spawn-change-event(spawn-change-event-data),
|
||||
server-broadcast-event(server-broadcast-event-data),
|
||||
server-tick-start-event(server-tick-start-event-data),
|
||||
packet-received-event(packet-received-event-data),
|
||||
packet-sent-event(packet-sent-event-data),
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
pub mod server_broadcast;
|
||||
pub mod server_command;
|
||||
pub mod server_tick_start;
|
||||
|
||||
16
pumpkin/src/plugin/api/events/server/server_tick_start.rs
Normal file
16
pumpkin/src/plugin/api/events/server/server_tick_start.rs
Normal file
@@ -0,0 +1,16 @@
|
||||
use pumpkin_macros::Event;
|
||||
|
||||
/// An event that fires at the start of every server tick.
|
||||
#[derive(Event, Clone)]
|
||||
pub struct ServerTickStartEvent {
|
||||
/// 0-indexed number of the tick about to run.
|
||||
pub tick: i32,
|
||||
}
|
||||
|
||||
impl ServerTickStartEvent {
|
||||
/// Creates a new `ServerTickStartEvent`.
|
||||
#[must_use]
|
||||
pub const fn new(tick: i32) -> Self {
|
||||
Self { tick }
|
||||
}
|
||||
}
|
||||
@@ -229,6 +229,7 @@ async fn register_server_event(
|
||||
) {
|
||||
use crate::plugin::server::{
|
||||
server_broadcast::ServerBroadcastEvent, server_command::ServerCommandEvent,
|
||||
server_tick_start::ServerTickStartEvent,
|
||||
};
|
||||
|
||||
match event_type {
|
||||
@@ -239,6 +240,10 @@ async fn register_server_event(
|
||||
register_typed_event::<ServerBroadcastEvent>(resource, handler, priority, blocking)
|
||||
.await;
|
||||
}
|
||||
EventType::ServerTickStartEvent => {
|
||||
register_typed_event::<ServerTickStartEvent>(resource, handler, priority, blocking)
|
||||
.await;
|
||||
}
|
||||
_ => unreachable!("non-server event should not be routed to register_server_event"),
|
||||
}
|
||||
}
|
||||
@@ -302,7 +307,9 @@ impl pumpkin::plugin::context::HostContext for PluginHostState {
|
||||
let handler = Arc::new(WasmPluginEventHandler { handler_id, plugin });
|
||||
|
||||
match event_type {
|
||||
event_type @ (EventType::ServerCommandEvent | EventType::ServerBroadcastEvent) => {
|
||||
event_type @ (EventType::ServerCommandEvent
|
||||
| EventType::ServerBroadcastEvent
|
||||
| EventType::ServerTickStartEvent) => {
|
||||
register_server_event(resource, &handler, priority, blocking, event_type).await;
|
||||
}
|
||||
event_type @ EventType::SpawnChangeEvent => {
|
||||
|
||||
@@ -3,10 +3,15 @@ use crate::plugin::{
|
||||
state::PluginHostState,
|
||||
wit::v0_1::{
|
||||
events::{ToFromWasmEvent, consume_text_component},
|
||||
pumpkin::plugin::event::{Event, ServerBroadcastEventData, ServerCommandEventData},
|
||||
pumpkin::plugin::event::{
|
||||
Event, ServerBroadcastEventData, ServerCommandEventData, ServerTickStartEventData,
|
||||
},
|
||||
},
|
||||
},
|
||||
server::{server_broadcast::ServerBroadcastEvent, server_command::ServerCommandEvent},
|
||||
server::{
|
||||
server_broadcast::ServerBroadcastEvent, server_command::ServerCommandEvent,
|
||||
server_tick_start::ServerTickStartEvent,
|
||||
},
|
||||
};
|
||||
|
||||
impl ToFromWasmEvent for ServerCommandEvent {
|
||||
@@ -55,3 +60,16 @@ impl ToFromWasmEvent for ServerBroadcastEvent {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToFromWasmEvent for ServerTickStartEvent {
|
||||
fn to_wasm_event(&self, _state: &mut PluginHostState) -> Event {
|
||||
Event::ServerTickStartEvent(ServerTickStartEventData { tick: self.tick })
|
||||
}
|
||||
|
||||
fn from_wasm_event(event: Event, _state: &mut PluginHostState) -> Self {
|
||||
match event {
|
||||
Event::ServerTickStartEvent(data) => Self { tick: data.tick },
|
||||
_ => panic!("unexpected event type"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use crate::{STOP_INTERRUPT, server::Server};
|
||||
use crate::{
|
||||
STOP_INTERRUPT, plugin::server::server_tick_start::ServerTickStartEvent, server::Server,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::time::Duration;
|
||||
use tokio::time::{Instant, sleep_until};
|
||||
use tracing::debug;
|
||||
@@ -17,6 +20,12 @@ impl Ticker {
|
||||
|
||||
manager.tick();
|
||||
|
||||
let tick_number = server.tick_count.load(Ordering::Relaxed);
|
||||
let _ = server
|
||||
.plugin_manager
|
||||
.fire(ServerTickStartEvent::new(tick_number))
|
||||
.await;
|
||||
|
||||
if manager.is_sprinting() {
|
||||
manager.start_sprint_tick_work();
|
||||
server.tick().await;
|
||||
|
||||
Reference in New Issue
Block a user