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:
parent
a7f60fab4d
commit
1cd68ee1a3
3 changed files with 86 additions and 1 deletions
|
@ -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;
|
||||
}
|
||||
|
|
31
src/ipc.rs
31
src/ipc.rs
|
@ -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!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Add table
Reference in a new issue