From 84fbe227d6d5a1b4f7ac3d528852749fb924a02d Mon Sep 17 00:00:00 2001 From: jake Date: Mon, 4 Nov 2019 01:07:29 -0800 Subject: [PATCH] security_data -> session --- src/packet/login.rs | 92 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 81 insertions(+), 11 deletions(-) diff --git a/src/packet/login.rs b/src/packet/login.rs index 37acd0e..f381991 100644 --- a/src/packet/login.rs +++ b/src/packet/login.rs @@ -1,6 +1,6 @@ use chrono::{DateTime, Utc}; -use psopacket::pso_packet; +use psopacket::{pso_packet, PSOPacketData}; use crate::{PSOPacket, PacketParseError, PSOPacketData}; use crate::character::character::SelectScreenCharacter; @@ -31,6 +31,64 @@ impl LoginWelcome { } } +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum SessionAction { + None, + SelectCharacter, + NewCharacter, + DressingRoom, +} + +impl PSOPacketData for SessionAction { + fn from_bytes(cursor: &mut R) -> Result { + let mut bytes = [0u8; 1]; + let len = cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; + if len != 1 { + return Err(PacketParseError::NotEnoughBytes) + } + match bytes[0] { + 0 => Ok(SessionAction::None), + 1 => Ok(SessionAction::SelectCharacter), + 2 => Ok(SessionAction::NewCharacter), + 3 => Ok(SessionAction::DressingRoom), + _ => Err(PacketParseError::InvalidValue) + } + } + + fn as_bytes(&self) -> Vec { + vec![match self { + SessionAction::None => 0, + SessionAction::SelectCharacter => 1, + SessionAction::NewCharacter => 2, + SessionAction::DressingRoom => 3, + }] + } +} + + + +#[derive(PSOPacketData, Debug, Clone, Copy, PartialEq)] +pub struct Session { + pub version: [u8; 30], + pub session_id: u32, + pub interserver_checksum: u32, + pub action: SessionAction, + pub character_slot: u8, // 1..=4 +} + +impl Session { + pub fn new() -> Session { + Session { + version: [0; 30], + session_id: 0, + interserver_checksum: 0, + action: SessionAction::None, + character_slot: 0, + } + } +} + + #[pso_packet(0x93)] pub struct Login { pub tag: u32, @@ -45,7 +103,8 @@ pub struct Login { pub password: [u8; 16], pub unknown3: [u8; 40], pub hwinfo: [u8; 8], - pub security_data: [u8; 40], + pub session: Session + //pub security_data: [u8; 40], } #[derive(Debug, Clone, PartialEq)] @@ -67,7 +126,10 @@ pub enum AccountStatus { impl PSOPacketData for AccountStatus { fn from_bytes(cursor: &mut R) -> Result { let mut bytes = [0u8; 4]; - cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; + let len = cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; + if len != 4 { + return Err(PacketParseError::NotEnoughBytes) + } match bytes[0] { 0 => Ok(AccountStatus::Ok), 1 => Ok(AccountStatus::Error), @@ -110,30 +172,31 @@ pub struct LoginResponse { pub tag: u32, pub guildcard: u32, pub team_id: u32, - pub security_data: [u8; 40], + //pub security_data: [u8; 40], + pub session: Session, pub caps: u32, } impl LoginResponse { - pub fn by_status(status: AccountStatus, security_data: [u8; 40]) -> LoginResponse { + pub fn by_status(status: AccountStatus, session: Session) -> LoginResponse { LoginResponse { status: status, tag: 0x00010000, //tag: 0x00000100, guildcard: 0, team_id: 0, - security_data: security_data, + session: session, caps: 0x00000102, } } - pub fn by_char_select(guildcard: u32, team_id: u32, security_data: [u8; 40]) -> LoginResponse { + pub fn by_char_select(guildcard: u32, team_id: u32, session: Session) -> LoginResponse { LoginResponse { status: AccountStatus::Ok, tag: 0x00010000, //tag: 0x00000100, guildcard: guildcard, team_id: team_id, - security_data: security_data, + session: session, caps: 0x00000102, } } @@ -458,7 +521,6 @@ impl PSOPacketData for ShipListEntry { bytes.extend_from_slice(&u16::to_le_bytes(self.flags)); bytes.extend_from_slice(&unsafe { std::mem::transmute::<[u16; 0x11], [u8; 0x11*2]>(self.name) }); bytes - //self.to_le_bytes().to_vec() } } @@ -527,12 +589,13 @@ mod tests { #[test] fn test_account_status_enum() { use super::PSOPacket; + use super::Session; let pkt = super::LoginResponse { status: super::AccountStatus::InvalidPassword, tag: 0, guildcard: 0, team_id: 0, - security_data: [0; 40], + session: Session::new(), caps: 0, }; @@ -552,7 +615,7 @@ mod tests { let mut rng = rand::thread_rng(); - let mut key_config = [0u8; 0x16C]; + let mut key_config = [0u8; 0x16C]; let mut joystick_config = [0u8; 0x38]; rng.fill(&mut key_config[..]); @@ -571,4 +634,11 @@ mod tests { let pkt = super::ChecksumAck::new(1); assert!(pkt.as_bytes() == [0xC, 0, 0xE8, 0x02, 0,0,0,0, 1,0,0,0]); } + + #[test] + fn test_session_size() { + use super::PSOPacketData; + let session = super::Session::new(); + assert!(session.as_bytes().len() == 40); + } }