mirror of
https://github.com/redstrate/Kawari.git
synced 2025-06-30 11:47:45 +00:00
Rename EventReturnHandler to EventYieldHandler, make generic
This also makes EventScene generic for use in the future.
This commit is contained in:
parent
670d25a980
commit
2762407585
5 changed files with 103 additions and 21 deletions
|
@ -308,10 +308,15 @@
|
||||||
"size": 16
|
"size": 16
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "EventHandlerReturn",
|
"name": "EventYieldHandler",
|
||||||
"opcode": 840,
|
"opcode": 840,
|
||||||
"size": 16
|
"size": 16
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "EventYieldHandler8",
|
||||||
|
"opcode": 441,
|
||||||
|
"size": 40
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Config",
|
"name": "Config",
|
||||||
"opcode": 534,
|
"opcode": 534,
|
||||||
|
|
|
@ -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;
|
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 } => {
|
ClientZoneIpcData::EventYieldHandler(handler) => {
|
||||||
tracing::info!("Finishing this event... {handler_id} {error_code} {scene} {:?}", ¶ms[..*num_results as usize]);
|
tracing::info!("Finishing this event... {} {} {} {:?}", handler.handler_id, handler.error_code, handler.scene, &handler.params[..handler.num_results as usize]);
|
||||||
|
|
||||||
connection
|
connection
|
||||||
.event
|
.event
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.finish(*scene, ¶ms[..*num_results as usize], &mut lua_player);
|
.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) => {
|
ClientZoneIpcData::Config(config) => {
|
||||||
connection
|
connection
|
||||||
|
|
|
@ -4,8 +4,8 @@ use crate::common::ObjectTypeId;
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[brw(little)]
|
#[brw(little)]
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct EventScene {
|
pub struct EventScene<const MAX_PARAMS: usize> {
|
||||||
pub actor_id: ObjectTypeId,
|
pub actor_id: ObjectTypeId,
|
||||||
pub event_id: u32,
|
pub event_id: u32,
|
||||||
pub scene: u16,
|
pub scene: u16,
|
||||||
|
@ -15,7 +15,21 @@ pub struct EventScene {
|
||||||
pub params_count: u8,
|
pub params_count: u8,
|
||||||
// Extra padding seems needed after or the client will seemingly softlock even with 2 params, possibly used for alignment?
|
// 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)]
|
#[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)]
|
#[cfg(test)]
|
||||||
|
@ -36,7 +50,7 @@ mod tests {
|
||||||
let buffer = read(d).unwrap();
|
let buffer = read(d).unwrap();
|
||||||
let mut buffer = Cursor::new(&buffer);
|
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!(
|
assert_eq!(
|
||||||
event_play.actor_id,
|
event_play.actor_id,
|
||||||
ObjectTypeId {
|
ObjectTypeId {
|
||||||
|
|
24
src/ipc/zone/event_yield_handler.rs
Normal file
24
src/ipc/zone/event_yield_handler.rs
Normal 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],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -85,6 +85,9 @@ pub use currency_info::CurrencyInfo;
|
||||||
mod config;
|
mod config;
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
|
|
||||||
|
mod event_yield_handler;
|
||||||
|
pub use event_yield_handler::EventYieldHandler;
|
||||||
|
|
||||||
use crate::common::ObjectTypeId;
|
use crate::common::ObjectTypeId;
|
||||||
use crate::common::Position;
|
use crate::common::Position;
|
||||||
use crate::common::read_string;
|
use crate::common::read_string;
|
||||||
|
@ -241,7 +244,7 @@ pub enum ServerZoneIpcData {
|
||||||
ContainerInfo(ContainerInfo),
|
ContainerInfo(ContainerInfo),
|
||||||
/// Sent to tell the client to play a scene
|
/// Sent to tell the client to play a scene
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventScene))]
|
||||||
EventScene(EventScene),
|
EventScene(EventScene<2>),
|
||||||
/// Sent to tell the client to load a scene, but not play it
|
/// Sent to tell the client to load a scene, but not play it
|
||||||
#[br(pre_assert(*magic == ServerZoneIpcType::EventStart))]
|
#[br(pre_assert(*magic == ServerZoneIpcType::EventStart))]
|
||||||
EventStart(EventStart),
|
EventStart(EventStart),
|
||||||
|
@ -438,15 +441,10 @@ pub enum ClientZoneIpcData {
|
||||||
#[brw(pad_after = 4)] // padding
|
#[brw(pad_after = 4)] // padding
|
||||||
event_id: u32,
|
event_id: u32,
|
||||||
},
|
},
|
||||||
#[br(pre_assert(*magic == ClientZoneIpcType::EventHandlerReturn))]
|
#[br(pre_assert(*magic == ClientZoneIpcType::EventYieldHandler))]
|
||||||
EventHandlerReturn {
|
EventYieldHandler(EventYieldHandler<2>),
|
||||||
// TODO: This is actually EventYieldHandler
|
#[br(pre_assert(*magic == ClientZoneIpcType::EventYieldHandler8))]
|
||||||
handler_id: u32,
|
EventYieldHandler8(EventYieldHandler<8>),
|
||||||
scene: u16,
|
|
||||||
error_code: u8,
|
|
||||||
num_results: u8,
|
|
||||||
params: [i32; 2],
|
|
||||||
},
|
|
||||||
#[br(pre_assert(*magic == ClientZoneIpcType::Config))]
|
#[br(pre_assert(*magic == ClientZoneIpcType::Config))]
|
||||||
Config(Config),
|
Config(Config),
|
||||||
#[br(pre_assert(*magic == ClientZoneIpcType::EventUnkRequest))]
|
#[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
|
/// Ensure that the IPC data size as reported matches up with what we write
|
||||||
#[test]
|
#[test]
|
||||||
fn world_ipc_sizes() {
|
fn server_zone_ipc_sizes() {
|
||||||
let ipc_types = [
|
let ipc_types = [
|
||||||
(
|
(
|
||||||
ServerZoneIpcType::InitResponse,
|
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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue