From c510d955bd1f259b8c4f640645ff440b4347c810 Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 17 Mar 2025 16:58:48 -0400 Subject: [PATCH] Document more random things, move session_id from PacketState to LobbyConnection --- Cargo.toml | 1 + src/bin/kawari-lobby.rs | 9 ++++++--- src/bin/kawari-world.rs | 1 - src/lib.rs | 4 +++- src/lobby/connection.rs | 4 +++- src/packet/ipc.rs | 28 ++++++++++++++++++++++++++++ src/packet/packet.rs | 2 +- 7 files changed, 42 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 92fce40..9337b30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [package] name = "kawari" +description = "A server replacement for a certain MMO." version = "0.1.0" edition = "2024" diff --git a/src/bin/kawari-lobby.rs b/src/bin/kawari-lobby.rs index 228dd21..4d8a5d8 100644 --- a/src/bin/kawari-lobby.rs +++ b/src/bin/kawari-lobby.rs @@ -23,12 +23,15 @@ async fn main() { let state = PacketState { client_key: None, - session_id: None, clientbound_oodle: FFXIVOodle::new(), serverbound_oodle: FFXIVOodle::new(), }; - let mut connection = LobbyConnection { socket, state }; + let mut connection = LobbyConnection { + socket, + state, + session_id: None, + }; tokio::spawn(async move { let mut buf = [0; 2056]; @@ -58,7 +61,7 @@ async fn main() { "Client {session_id} ({version_info}) logging in!" ); - connection.state.session_id = Some(session_id.clone()); + connection.session_id = Some(session_id.clone()); connection.send_account_list().await; diff --git a/src/bin/kawari-world.rs b/src/bin/kawari-world.rs index 26f9f3e..062e5ac 100644 --- a/src/bin/kawari-world.rs +++ b/src/bin/kawari-world.rs @@ -33,7 +33,6 @@ async fn main() { let state = PacketState { client_key: None, - session_id: None, clientbound_oodle: FFXIVOodle::new(), serverbound_oodle: FFXIVOodle::new(), }; diff --git a/src/lib.rs b/src/lib.rs index 9935a42..d44cd81 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,3 +1,5 @@ +//! A server replacement for a certain MMO. + use common::CustomizeData; use minijinja::Environment; use rand::Rng; @@ -29,7 +31,7 @@ pub mod packet; // TODO: make this configurable /// The world ID and name for the lobby. -/// See https://ffxiv.consolegameswiki.com/wiki/Servers for a list of possible IDs. +/// See for a list of possible IDs. pub const WORLD_ID: u16 = 63; pub const WORLD_NAME: &str = "KAWARI"; diff --git a/src/lobby/connection.rs b/src/lobby/connection.rs index 55eb466..741b998 100644 --- a/src/lobby/connection.rs +++ b/src/lobby/connection.rs @@ -25,6 +25,8 @@ use crate::lobby::ipc::ClientLobbyIpcSegment; pub struct LobbyConnection { pub socket: TcpStream, + pub session_id: Option, + pub state: PacketState, } @@ -287,7 +289,7 @@ impl LobbyConnection { } pub async fn send_enter_world(&mut self, sequence: u64, lookup_id: u64) { - let Some(session_id) = &self.state.session_id else { + let Some(session_id) = &self.session_id else { panic!("Missing session id!"); }; diff --git a/src/packet/ipc.rs b/src/packet/ipc.rs index 3c38f6e..0b3793e 100644 --- a/src/packet/ipc.rs +++ b/src/packet/ipc.rs @@ -8,6 +8,28 @@ pub trait IpcSegmentTrait: fn calc_size(&self) -> u32; } +/// An IPC packet segment. +/// When implementing a new connection type, `OpCode` and `Data` can be used to specialize this type: +/// ``` +/// # use binrw::binrw; +/// # use kawari::packet::IpcSegment; +/// # +/// # #[binrw] +/// # #[brw(repr = u16)] +/// # #[derive(Clone, PartialEq, Debug)] +/// # pub enum ClientLobbyIpcType { +/// # Dummy = 0x1, +/// # } +/// # +/// # #[binrw] +/// # #[br(import(magic: &ClientLobbyIpcType))] +/// # #[derive(Debug, Clone)] +/// # pub enum ClientLobbyIpcData { +/// # Dummy() +/// # } +/// # +/// pub type ClientLobbyIpcSegment = IpcSegment; +/// ``` #[binrw] #[derive(Debug, Clone)] pub struct IpcSegment @@ -17,12 +39,18 @@ where for<'a> Data: BinRead = (&'a OpCode,)> + 'a + std::fmt::Debug, for<'a> Data: BinWrite = ()> + 'a + std::fmt::Debug, { + /// Unknown purpose, but usually 20. pub unk1: u8, + /// Unknown purpose, but usually 0. pub unk2: u8, + /// The opcode for this segment. pub op_code: OpCode, #[brw(pad_before = 2)] // empty + /// Unknown purpose, but safe to keep 0. pub server_id: u16, + /// The timestamp of this packet in seconds since UNIX epoch. pub timestamp: u32, + /// The data associated with the opcode. #[brw(pad_before = 4)] #[br(args(&op_code))] pub data: Data, diff --git a/src/packet/packet.rs b/src/packet/packet.rs index b98e670..9faa0e1 100644 --- a/src/packet/packet.rs +++ b/src/packet/packet.rs @@ -194,9 +194,9 @@ pub async fn send_packet( } // temporary +/// State needed for each connection between the client & server, containing various things like the compressor and encryption keys. pub struct PacketState { pub client_key: Option<[u8; 16]>, - pub session_id: Option, pub serverbound_oodle: FFXIVOodle, pub clientbound_oodle: FFXIVOodle, }