1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-06-30 03:37:45 +00:00

Rename EventReturnHandler to EventYieldHandler, make generic

This also makes EventScene generic for use in the future.
This commit is contained in:
Joshua Goins 2025-06-28 15:57:45 -04:00
parent 670d25a980
commit 2762407585
5 changed files with 103 additions and 21 deletions

View file

@ -308,10 +308,15 @@
"size": 16
},
{
"name": "EventHandlerReturn",
"name": "EventYieldHandler",
"opcode": 840,
"size": 16
},
{
"name": "EventYieldHandler8",
"opcode": 441,
"size": 40
},
{
"name": "Config",
"opcode": 534,

View file

@ -838,14 +838,23 @@ async fn client_loop(
connection.send_message(&*format!("Event {event_id} tried to start, but it doesn't have a script associated with it!")).await;
}
}
ClientZoneIpcData::EventHandlerReturn { handler_id, scene, error_code, num_results, params } => {
tracing::info!("Finishing this event... {handler_id} {error_code} {scene} {:?}", &params[..*num_results as usize]);
ClientZoneIpcData::EventYieldHandler(handler) => {
tracing::info!("Finishing this event... {} {} {} {:?}", handler.handler_id, handler.error_code, handler.scene, &handler.params[..handler.num_results as usize]);
connection
.event
.as_mut()
.unwrap()
.finish(*scene, &params[..*num_results as usize], &mut lua_player);
.as_mut()
.unwrap()
.finish(handler.scene, &handler.params[..handler.num_results as usize], &mut lua_player);
}
ClientZoneIpcData::EventYieldHandler8(handler) => {
tracing::info!("Finishing this event... {} {} {} {:?}", handler.handler_id, handler.error_code, handler.scene, &handler.params[..handler.num_results as usize]);
connection
.event
.as_mut()
.unwrap()
.finish(handler.scene, &handler.params[..handler.num_results as usize], &mut lua_player);
}
ClientZoneIpcData::Config(config) => {
connection

View file

@ -4,8 +4,8 @@ use crate::common::ObjectTypeId;
#[binrw]
#[brw(little)]
#[derive(Debug, Clone, Default)]
pub struct EventScene {
#[derive(Debug, Clone)]
pub struct EventScene<const MAX_PARAMS: usize> {
pub actor_id: ObjectTypeId,
pub event_id: u32,
pub scene: u16,
@ -15,7 +15,21 @@ pub struct EventScene {
pub params_count: u8,
// Extra padding seems needed after or the client will seemingly softlock even with 2 params, possibly used for alignment?
#[brw(pad_before = 3, pad_after = 4)]
pub params: [u32; 2],
pub params: [u32; MAX_PARAMS],
}
impl<const MAX_PARAMS: usize> Default for EventScene<{ MAX_PARAMS }> {
fn default() -> Self {
Self {
actor_id: ObjectTypeId::default(),
event_id: 0,
scene: 0,
scene_flags: 0,
unk1: 0,
params_count: 0,
params: [0u32; MAX_PARAMS],
}
}
}
#[cfg(test)]
@ -36,7 +50,7 @@ mod tests {
let buffer = read(d).unwrap();
let mut buffer = Cursor::new(&buffer);
let event_play = EventScene::read_le(&mut buffer).unwrap();
let event_play = EventScene::<2>::read_le(&mut buffer).unwrap();
assert_eq!(
event_play.actor_id,
ObjectTypeId {

View file

@ -0,0 +1,24 @@
use binrw::binrw;
#[binrw]
#[brw(little)]
#[derive(Debug, Clone)]
pub struct EventYieldHandler<const MAX_PARAMS: usize> {
pub handler_id: u32,
pub scene: u16,
pub error_code: u8,
pub num_results: u8,
pub params: [i32; MAX_PARAMS],
}
impl<const MAX_PARAMS: usize> Default for EventYieldHandler<{ MAX_PARAMS }> {
fn default() -> Self {
Self {
handler_id: 0,
scene: 0,
error_code: 0,
num_results: 0,
params: [0i32; MAX_PARAMS],
}
}
}

View file

@ -85,6 +85,9 @@ pub use currency_info::CurrencyInfo;
mod config;
pub use config::Config;
mod event_yield_handler;
pub use event_yield_handler::EventYieldHandler;
use crate::common::ObjectTypeId;
use crate::common::Position;
use crate::common::read_string;
@ -241,7 +244,7 @@ pub enum ServerZoneIpcData {
ContainerInfo(ContainerInfo),
/// Sent to tell the client to play a scene
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene))]
EventScene(EventScene),
EventScene(EventScene<2>),
/// Sent to tell the client to load a scene, but not play it
#[br(pre_assert(*magic == ServerZoneIpcType::EventStart))]
EventStart(EventStart),
@ -438,15 +441,10 @@ pub enum ClientZoneIpcData {
#[brw(pad_after = 4)] // padding
event_id: u32,
},
#[br(pre_assert(*magic == ClientZoneIpcType::EventHandlerReturn))]
EventHandlerReturn {
// TODO: This is actually EventYieldHandler
handler_id: u32,
scene: u16,
error_code: u8,
num_results: u8,
params: [i32; 2],
},
#[br(pre_assert(*magic == ClientZoneIpcType::EventYieldHandler))]
EventYieldHandler(EventYieldHandler<2>),
#[br(pre_assert(*magic == ClientZoneIpcType::EventYieldHandler8))]
EventYieldHandler8(EventYieldHandler<8>),
#[br(pre_assert(*magic == ClientZoneIpcType::Config))]
Config(Config),
#[br(pre_assert(*magic == ClientZoneIpcType::EventUnkRequest))]
@ -475,7 +473,7 @@ mod tests {
/// Ensure that the IPC data size as reported matches up with what we write
#[test]
fn world_ipc_sizes() {
fn server_zone_ipc_sizes() {
let ipc_types = [
(
ServerZoneIpcType::InitResponse,
@ -605,4 +603,36 @@ mod tests {
);
}
}
/// Ensure that the IPC data size as reported matches up with what we write
#[test]
fn client_zone_ipc_sizes() {
let ipc_types = [(
ClientZoneIpcType::EventYieldHandler8,
ClientZoneIpcData::EventYieldHandler8(EventYieldHandler::<8>::default()),
)];
for (opcode, data) in &ipc_types {
let mut cursor = Cursor::new(Vec::new());
let ipc_segment = ClientZoneIpcSegment {
unk1: 0,
unk2: 0,
op_code: opcode.clone(), // doesn't matter for this test
option: 0,
timestamp: 0,
data: data.clone(),
};
ipc_segment.write_le(&mut cursor).unwrap();
let buffer = cursor.into_inner();
assert_eq!(
buffer.len(),
ipc_segment.calc_size() as usize,
"{:#?} did not match size!",
opcode
);
}
}
}