1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-06-08 17:37:46 +00:00

Allow logging out of the client without destroying the world server

This adds support for the IPC packets sent between the client & server when
using the log out feature.
This commit is contained in:
Joshua Goins 2025-03-12 18:44:05 -04:00
parent 181d127fb5
commit b52ff724ab
3 changed files with 58 additions and 2 deletions

View file

@ -411,6 +411,37 @@ async fn main() {
IPCStructData::UpdatePositionHandler { .. } => {
tracing::info!("Recieved UpdatePositionHandler!");
}
IPCStructData::LogOut { .. } => {
tracing::info!("Recieved log out from client!");
// tell the client to disconnect
{
let ipc = IPCSegment {
unk1: 0,
unk2: 0,
op_code: IPCOpCode::LogOutComplete,
server_id: 0,
timestamp: timestamp_secs(),
data: IPCStructData::LogOutComplete { unk: [0; 8] },
};
let response_packet = PacketSegment {
source_actor: state.player_id.unwrap(),
target_actor: state.player_id.unwrap(),
segment_type: SegmentType::Ipc { data: ipc },
};
send_packet(
&mut write,
&[response_packet],
&mut state,
CompressionType::Oodle,
)
.await;
}
}
IPCStructData::Disconnected { .. } => {
tracing::info!("Client disconnected!");
}
_ => panic!(
"The server is recieving a IPC response or unknown packet!"
),

View file

@ -70,6 +70,12 @@ pub enum IPCOpCode {
// FIXME: 32 bytes of something from the client, not sure what yet
Unk7 = 0x2B5,
UpdatePositionHandler = 0x249, // TODO: assumed
// Sent by the client when the user requests to log out
LogOut = 0x217,
// Sent by the server to indicate the log out is complete
LogOutComplete = 0x369,
// Sent by the client when it's actually disconnecting
Disconnected = 0x360,
}
#[binrw]
@ -259,6 +265,16 @@ pub enum IPCStructData {
// TODO: full of possibly interesting information
unk: [u8; 24],
},
#[br(pre_assert(*magic == IPCOpCode::LogOut))]
LogOut {
// TODO: full of possibly interesting information
unk: [u8; 8],
},
#[br(pre_assert(*magic == IPCOpCode::Disconnected))]
Disconnected {
// TODO: full of possibly interesting information
unk: [u8; 8],
},
// Server->Client IPC
#[br(pre_assert(false))]
@ -357,6 +373,11 @@ pub enum IPCStructData {
UpdateClassInfo(UpdateClassInfo),
#[br(pre_assert(false))]
PlayerSpawn(PlayerSpawn),
#[br(pre_assert(false))]
LogOutComplete {
// TODO: guessed
unk: [u8; 8],
},
}
#[binrw]
@ -409,6 +430,9 @@ impl IPCSegment {
IPCStructData::Unk6 { .. } => todo!(),
IPCStructData::Unk7 { .. } => todo!(),
IPCStructData::UpdatePositionHandler { .. } => todo!(),
IPCStructData::LogOut { .. } => todo!(),
IPCStructData::LogOutComplete { .. } => 8,
IPCStructData::Disconnected { .. } => todo!(),
}
}
}

View file

@ -235,12 +235,13 @@ pub async fn parse_packet(data: &[u8], state: &mut State) -> (Vec<PacketSegment>
Ok(packet) => {
println!("{:#?}", packet);
if packet.header.size as usize != data.len() {
// don't really think this works like I think it does'
/*if packet.header.size as usize != data.len() {
dump(
"Packet size mismatch between what we're given and the header!",
data,
);
}
}*/
(packet.segments, packet.header.connection_type)
}