1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-04-22 23:27:46 +00:00

Store session id, handle world join requests

We have yet to implement the world server, so the client gets kicked back to the
main menu immediately right now.
This commit is contained in:
Joshua Goins 2025-03-09 11:01:06 -04:00
parent a7f60fab4d
commit 1cd68ee1a3
3 changed files with 86 additions and 1 deletions

View file

@ -23,7 +23,7 @@ async fn main() {
let (socket, _) = listener.accept().await.unwrap();
let (mut read, mut write) = tokio::io::split(socket);
let mut state = State { client_key: None };
let mut state = State {client_key:None, session_id: None };
tokio::spawn(async move {
let mut buf = [0; 2056];
@ -46,6 +46,8 @@ async fn main() {
"Client {session_id} ({version_info}) logging in!"
);
state.session_id = Some(session_id.clone());
send_account_list(&mut write, &state).await;
}
IPCStructData::RequestCharacterList { sequence } => {
@ -69,6 +71,14 @@ async fn main() {
);
}
},
IPCStructData::RequestEnterWorld {
sequence,
lookup_id,
} => {
tracing::info!("Client is joining the world...");
send_enter_world(&mut write, &state, *sequence, *lookup_id).await;
}
_ => {
panic!("The server is recieving a IPC response packet!")
}
@ -371,3 +381,46 @@ async fn send_lobby_info(socket: &mut WriteHalf<TcpStream>, state: &State, seque
}
}
}
async fn send_enter_world(
socket: &mut WriteHalf<TcpStream>,
state: &State,
sequence: u64,
lookup_id: u64,
) {
let Some(session_id) = &state.session_id else {
panic!("Missing session id!");
};
let timestamp: u32 = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Failed to get UNIX timestamp!")
.as_secs()
.try_into()
.unwrap();
let enter_world = IPCStructData::LobbyEnterWorld {
sequence,
character_id: 0,
content_id: lookup_id, // TODO: shouldn't these be named the same then?
session_id: session_id.clone(),
port: 7100,
host: "127.0.0.1".to_string(),
};
let ipc = IPCSegment {
unk1: 0,
unk2: 0,
op_code: IPCOpCode::LobbyEnterWorld,
server_id: 0,
timestamp,
data: enter_world,
};
let response_packet = PacketSegment {
source_actor: 0,
target_actor: 0,
segment_type: SegmentType::Ipc { data: ipc },
};
send_packet(socket, &[response_packet], state).await;
}

View file

@ -8,6 +8,8 @@ use crate::common::{read_string, write_string};
pub enum IPCOpCode {
/// Sent by the client when it requests the character list in the lobby.
RequestCharacterList = 0x3,
/// Sent by the client when it requests to enter a world.
RequestEnterWorld = 0x4,
/// Sent by the client after exchanging encryption information with the lobby server.
ClientVersionInfo = 0x5,
/// Sent by the client when they request something about the character (e.g. deletion.)
@ -16,6 +18,8 @@ pub enum IPCOpCode {
LobbyServiceAccountList = 0xC,
/// Sent by the server to inform the client of their characters.
LobbyCharacterList = 0xD,
/// Sent by the server to tell the client how to connect to the world server.
LobbyEnterWorld = 0xF,
/// Sent by the server to inform the client of their servers.
LobbyServerList = 0x15,
/// Sent by the server to inform the client of their retainers.
@ -133,6 +137,13 @@ pub enum IPCStructData {
name: String,
// TODO: what else is in here?
},
#[br(pre_assert(*magic == IPCOpCode::RequestEnterWorld))]
RequestEnterWorld {
#[brw(pad_before = 16)]
sequence: u64,
lookup_id: u64,
// TODO: what else is in here?
},
// Server->Client IPC
LobbyServiceAccountList {
@ -185,6 +196,24 @@ pub enum IPCStructData {
#[br(count = 2)]
characters: Vec<CharacterDetails>,
},
LobbyEnterWorld {
sequence: u64,
character_id: u32,
#[brw(pad_before = 4)]
content_id: u64,
#[brw(pad_before = 4)]
#[bw(pad_size_to = 66)]
#[br(count = 66)]
#[br(map = read_string)]
#[bw(map = write_string)]
session_id: String,
port: u16,
#[brw(pad_after = 16)]
#[br(count = 48)]
#[br(map = read_string)]
#[bw(map = write_string)]
host: String,
},
}
#[binrw]
@ -213,6 +242,8 @@ impl IPCSegment {
IPCStructData::LobbyRetainerList { .. } => 210,
IPCStructData::LobbyCharacterList { .. } => 80 + (2 * 1184),
IPCStructData::LobbyCharacterAction { .. } => todo!(),
IPCStructData::LobbyEnterWorld { .. } => 160,
IPCStructData::RequestEnterWorld { .. } => todo!(),
}
}
}

View file

@ -176,6 +176,7 @@ pub async fn send_packet(
// temporary
pub struct State {
pub client_key: Option<[u8; 16]>,
pub session_id: Option<String>,
}
pub async fn parse_packet(data: &[u8], state: &mut State) -> Vec<PacketSegment> {