convert login packets
This commit is contained in:
		
							parent
							
								
									8eaf7f08ff
								
							
						
					
					
						commit
						04322d2526
					
				| @ -1,7 +1,8 @@ | ||||
| use chrono::{DateTime, Utc}; | ||||
| 
 | ||||
| use psopacket::pso_packet; | ||||
| use crate::{PSOPacket, PacketParseError}; | ||||
| //use psopacket::pso_packet;
 | ||||
| use psopacket::pso_packet2 as pso_packet; | ||||
| use crate::{PSOPacket, PacketParseError, PSOPacketData}; | ||||
| 
 | ||||
| use crate::character::character::SelectScreenCharacter; | ||||
| 
 | ||||
| @ -11,13 +12,10 @@ pub const PATCH_FILE_CHUNK_SIZE: u16 = 0x8000; // 32kb | ||||
| pub const GUILD_CARD_CHUNK_SIZE: usize = 0x6800; | ||||
| pub const PARAM_DATA_CHUNK_SIZE: usize = 0x6800; | ||||
| 
 | ||||
| #[allow(non_camel_case_types)] | ||||
| type u8_str = u8; | ||||
| 
 | ||||
| #[pso_packet(0x03)] | ||||
| pub struct LoginWelcome { | ||||
|     flag: u32, | ||||
|     copyright: [u8_str; 0x60], | ||||
|     #[utf8] | ||||
|     copyright: [u8; 0x60], | ||||
|     server_key: [u8; 48], | ||||
|     client_key: [u8; 48], | ||||
| } | ||||
| @ -27,7 +25,6 @@ impl LoginWelcome { | ||||
|         let mut copyright = [0u8; 0x60]; | ||||
|         copyright[..0x4B].clone_from_slice(b"Phantasy Star Online Blue Burst Game Server. Copyright 1999-2004 SONICTEAM."); | ||||
|         LoginWelcome { | ||||
|             flag: 0, | ||||
|             copyright: copyright, | ||||
|             server_key: server_key, | ||||
|             client_key: client_key, | ||||
| @ -37,15 +34,16 @@ impl LoginWelcome { | ||||
| 
 | ||||
| #[pso_packet(0x93)] | ||||
| pub struct Login { | ||||
|     pub flag: u32, | ||||
|     pub tag: u32, | ||||
|     pub guildcard: u32, | ||||
|     pub version: u16, | ||||
|     pub unknown1: [u8; 6], | ||||
|     pub team: u32, | ||||
|     pub username: [u8_str; 16], | ||||
|     #[utf8] | ||||
|     pub username: [u8; 16], | ||||
|     pub unknown2: [u8; 32], | ||||
|     pub password: [u8_str; 16], | ||||
|     #[utf8] | ||||
|     pub password: [u8; 16], | ||||
|     pub unknown3: [u8; 40], | ||||
|     pub hwinfo: [u8; 8], | ||||
|     pub security_data: [u8; 40], | ||||
| @ -67,27 +65,10 @@ pub enum AccountStatus { | ||||
|     BadVersion, | ||||
| } | ||||
| 
 | ||||
| impl AccountStatus { | ||||
|     const SIZE: usize = 4; | ||||
|     
 | ||||
|     fn to_le_bytes(&self) -> [u8; 4] { | ||||
|         [match self { | ||||
|             AccountStatus::Ok => 0, | ||||
|             AccountStatus::Error => 1, | ||||
|             AccountStatus::InvalidPassword => 2, | ||||
|             AccountStatus::InvalidPassword2 => 3, | ||||
|             AccountStatus::Maintenance => 4, | ||||
|             AccountStatus::AlreadyOnline => 5, | ||||
|             AccountStatus::Banned => 6, | ||||
|             AccountStatus::Banned2 => 7, | ||||
|             AccountStatus::InvalidUser => 8, | ||||
|             AccountStatus::PayUp => 9, | ||||
|             AccountStatus::Locked => 10, | ||||
|             AccountStatus::BadVersion => 11, | ||||
|         },0,0,0] | ||||
|     } | ||||
| 
 | ||||
|     fn from_le_bytes(bytes: [u8; 4]) -> Result<AccountStatus, PacketParseError> { | ||||
| impl PSOPacketData for AccountStatus { | ||||
|     fn from_bytes<R: Read>(cursor: &mut R) -> Result<Self, PacketParseError> { | ||||
|         let mut bytes = [0u8; 4]; | ||||
|         cursor.read(&mut bytes).map_err(|_| PacketParseError::ReadError)?; | ||||
|         match bytes[0] { | ||||
|             0 => Ok(AccountStatus::Ok), | ||||
|             1 => Ok(AccountStatus::Error), | ||||
| @ -104,12 +85,28 @@ impl AccountStatus { | ||||
|             _ => Err(PacketParseError::InvalidValue), | ||||
|         } | ||||
|     } | ||||
|         
 | ||||
| 
 | ||||
|     fn as_bytes(&self) -> Vec<u8> { | ||||
|         vec![match self { | ||||
|             AccountStatus::Ok => 0, | ||||
|             AccountStatus::Error => 1, | ||||
|             AccountStatus::InvalidPassword => 2, | ||||
|             AccountStatus::InvalidPassword2 => 3, | ||||
|             AccountStatus::Maintenance => 4, | ||||
|             AccountStatus::AlreadyOnline => 5, | ||||
|             AccountStatus::Banned => 6, | ||||
|             AccountStatus::Banned2 => 7, | ||||
|             AccountStatus::InvalidUser => 8, | ||||
|             AccountStatus::PayUp => 9, | ||||
|             AccountStatus::Locked => 10, | ||||
|             AccountStatus::BadVersion => 11, | ||||
|         },0,0,0] | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[pso_packet(0xE6)] | ||||
| pub struct LoginResponse { | ||||
|     pub flag: u32, | ||||
|     pub status: AccountStatus, | ||||
|     pub tag: u32, | ||||
|     pub guildcard: u32, | ||||
| @ -121,7 +118,6 @@ pub struct LoginResponse { | ||||
| impl LoginResponse { | ||||
|     pub fn by_status(status: AccountStatus, security_data: [u8; 40]) -> LoginResponse { | ||||
|         LoginResponse { | ||||
|             flag: 0, | ||||
|             status: status, | ||||
|             tag: 0x00010000, | ||||
|             //tag: 0x00000100,
 | ||||
| @ -133,7 +129,6 @@ impl LoginResponse { | ||||
|     } | ||||
|     pub fn by_char_select(guildcard: u32, team_id: u32, security_data: [u8; 40]) -> LoginResponse { | ||||
|         LoginResponse { | ||||
|             flag: 0, | ||||
|             status: AccountStatus::Ok, | ||||
|             tag: 0x00010000, | ||||
|             //tag: 0x00000100,
 | ||||
| @ -148,12 +143,10 @@ impl LoginResponse { | ||||
| 
 | ||||
| #[pso_packet(0xE0)] | ||||
| pub struct RequestSettings { | ||||
|     pub flag: u32 | ||||
| } | ||||
| 
 | ||||
| #[pso_packet(0xE2)] | ||||
| pub struct SendKeyAndTeamSettings { | ||||
|     flag: u32, | ||||
|     unknown: [u8; 0x114], | ||||
|     key_config: [u8; 0x16C], | ||||
|     joystick_config: [u8; 0x38], | ||||
| @ -165,6 +158,7 @@ pub struct SendKeyAndTeamSettings { | ||||
|     unknown2: u16, | ||||
|     //team_name: [u16; 16],
 | ||||
|     team_name: [u8; 32], | ||||
|     #[nodebug] | ||||
|     team_flag: [u8; 2048], | ||||
|     team_rewards: [u8; 8], | ||||
| } | ||||
| @ -172,7 +166,6 @@ pub struct SendKeyAndTeamSettings { | ||||
| impl SendKeyAndTeamSettings { | ||||
|     pub fn new(key_config: [u8; 0x16C], joystick_config: [u8; 0x38], guildcard: u32, team_id: u32) -> SendKeyAndTeamSettings { | ||||
|         SendKeyAndTeamSettings { | ||||
|             flag: 0, | ||||
|             unknown: [0; 0x114], | ||||
|             key_config: key_config, | ||||
|             joystick_config: joystick_config, | ||||
| @ -192,7 +185,6 @@ impl SendKeyAndTeamSettings { | ||||
| 
 | ||||
| #[pso_packet(0x19)] | ||||
| pub struct RedirectClient { | ||||
|     pub flag: u32, | ||||
|     pub ip: u32, | ||||
|     pub port: u16, | ||||
|     pub padding: u16, | ||||
| @ -201,7 +193,6 @@ pub struct RedirectClient { | ||||
| impl RedirectClient { | ||||
|     pub fn new(ip: u32, port: u16) -> RedirectClient { | ||||
|         RedirectClient { | ||||
|             flag: 0, | ||||
|             ip: ip, | ||||
|             port: port, | ||||
|             padding: 0, | ||||
| @ -211,21 +202,18 @@ impl RedirectClient { | ||||
| 
 | ||||
| #[pso_packet(0x1E8)] | ||||
| pub struct Checksum { | ||||
|     pub flag: u32, | ||||
|     pub checksum: u32, | ||||
|     pub padding: u32, | ||||
| } | ||||
| 
 | ||||
| #[pso_packet(0x2E8)] | ||||
| pub struct ChecksumAck { | ||||
|     pub flag: u32, | ||||
|     pub ack: u32, | ||||
| } | ||||
| 
 | ||||
| impl ChecksumAck { | ||||
|     pub fn new(ack: u32) -> ChecksumAck { | ||||
|         ChecksumAck { | ||||
|             flag: 0, | ||||
|             ack: ack, | ||||
|         } | ||||
|     } | ||||
| @ -233,34 +221,40 @@ impl ChecksumAck { | ||||
| 
 | ||||
| #[pso_packet(0xE3)] | ||||
| pub struct CharSelect { | ||||
|     pub flag: u32, | ||||
|     pub slot: u32, | ||||
|     pub reason: u32, // TODO: enum?
 | ||||
| } | ||||
| 
 | ||||
| #[pso_packet(0xE4)] | ||||
| pub struct CharAck { | ||||
|     pub flag: u32, | ||||
|     pub slot: u32, | ||||
|     pub code: u32, // TODO: enum?
 | ||||
| } | ||||
| 
 | ||||
| impl PSOPacketData for SelectScreenCharacter { | ||||
|     fn from_bytes<R: Read>(cursor: &mut R) -> Result<Self, PacketParseError> { | ||||
|         let mut buf = [0u8; SelectScreenCharacter::SIZE]; | ||||
|         cursor.read(&mut buf).map_err(|_| PacketParseError::ReadError)?; | ||||
|         SelectScreenCharacter::from_le_bytes(buf) | ||||
|     } | ||||
| 
 | ||||
|     fn as_bytes(&self) -> Vec<u8> { | ||||
|         self.to_le_bytes().to_vec() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #[pso_packet(0xE5)] | ||||
| pub struct CharacterPreview { | ||||
|     pub flag: u32, | ||||
|     pub slot: u32, | ||||
|     pub character: SelectScreenCharacter, | ||||
| } | ||||
| 
 | ||||
| #[pso_packet(0x3E8)] | ||||
| pub struct GuildcardDataRequest { | ||||
|     flag: u32, | ||||
| } | ||||
| 
 | ||||
| #[pso_packet(0x1DC)] | ||||
| pub struct GuildcardDataHeader { | ||||
|     flag: u32, | ||||
|     one: u32, | ||||
|     len: u32, | ||||
|     checksum: u32, | ||||
| @ -269,7 +263,6 @@ pub struct GuildcardDataHeader { | ||||
| impl GuildcardDataHeader { | ||||
|     pub fn new(len: usize, checksum: u32) -> GuildcardDataHeader { | ||||
|         GuildcardDataHeader { | ||||
|             flag: 0, | ||||
|             one: 1, | ||||
|             len: len as u32, | ||||
|             checksum: checksum | ||||
| @ -279,14 +272,12 @@ impl GuildcardDataHeader { | ||||
| 
 | ||||
| #[pso_packet(0x3DC)] | ||||
| pub struct GuildcardDataChunkRequest { | ||||
|     flag: u32, | ||||
|     _unknown: u32, | ||||
|     pub chunk: u32, | ||||
|     pub again: u32, | ||||
| } | ||||
| 
 | ||||
| pub struct GuildcardDataChunk { | ||||
|     flag: u32, | ||||
|     _unknown: u32, | ||||
|     chunk: u32, | ||||
|     pub buffer: [u8; GUILD_CARD_CHUNK_SIZE], | ||||
| @ -297,7 +288,6 @@ pub struct GuildcardDataChunk { | ||||
| impl GuildcardDataChunk { | ||||
|     pub fn new(chunk: u32, buffer: [u8; GUILD_CARD_CHUNK_SIZE], len: usize) -> GuildcardDataChunk { | ||||
|         GuildcardDataChunk { | ||||
|             flag: 0, | ||||
|             _unknown: 0, | ||||
|             chunk: chunk as u32, | ||||
|             buffer: buffer, | ||||
| @ -313,7 +303,7 @@ impl PSOPacket for GuildcardDataChunk { | ||||
| 
 | ||||
|     fn as_bytes(&self) -> Vec<u8> { | ||||
|         let mut buf: Vec<u8> = Vec::new(); | ||||
|         buf.extend_from_slice(&u32::to_le_bytes(self.flag)); | ||||
|         buf.extend_from_slice(&u32::to_le_bytes(0)); | ||||
|         buf.extend_from_slice(&u32::to_le_bytes(self._unknown)); | ||||
|         buf.extend_from_slice(&u32::to_le_bytes(self.chunk)); | ||||
|         buf.extend_from_slice(&self.buffer[0..self.len]); | ||||
| @ -333,7 +323,7 @@ impl PSOPacket for GuildcardDataChunk { | ||||
| impl std::fmt::Debug for GuildcardDataChunk { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||||
|         write!(f, "packet GuildcardDataChunk {{\n").unwrap(); | ||||
|         write!(f, "    flag: {:?}\n", self.flag).unwrap(); | ||||
|         write!(f, "    flag: {:?}\n", 0).unwrap(); | ||||
|         write!(f, "    _unknown: {:X?}\n", self._unknown).unwrap(); | ||||
|         write!(f, "    chunk: {:X?}\n", self.chunk).unwrap(); | ||||
|         write!(f, "    buffer: [0..{:X}]\n", self.len).unwrap(); | ||||
| @ -344,7 +334,6 @@ impl std::fmt::Debug for GuildcardDataChunk { | ||||
| 
 | ||||
| #[pso_packet(0x4EB)] | ||||
| pub struct ParamDataRequest { | ||||
|     flag: u32, | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone)] | ||||
| @ -398,27 +387,25 @@ impl std::fmt::Debug for ParamDataHeader { | ||||
| 
 | ||||
| #[pso_packet(0x3EB)] | ||||
| pub struct ParamDataChunkRequest { | ||||
|     flag: u32, | ||||
| } | ||||
| 
 | ||||
| #[pso_packet(0x2EB)] | ||||
| pub struct ParamDataChunk { | ||||
|     pub flag: u32, | ||||
|     pub chunk: u32, | ||||
|     #[nodebug] | ||||
|     pub data: [u8; 0x6800], // TODO: why wont the const work here? (blame macros?)
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[pso_packet(0xEC)] | ||||
| pub struct SetFlag { | ||||
|     flag: u32, | ||||
|     pub flags: u32, | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[pso_packet(0xB1)] | ||||
| pub struct Timestamp { | ||||
|     flag: u32, | ||||
|     #[utf8] | ||||
|     timestamp: [u8; 28], | ||||
| } | ||||
| 
 | ||||
| @ -429,7 +416,6 @@ impl Timestamp { | ||||
|         let mut timebuf = [0u8; 28]; | ||||
|         timebuf[..timebytes.len()].clone_from_slice(timebytes); | ||||
|         Timestamp { | ||||
|             flag: 0, | ||||
|             timestamp: timebuf | ||||
|         } | ||||
|     } | ||||
| @ -444,8 +430,41 @@ pub struct ShipListEntry { | ||||
|     pub name: [u16; 0x11], | ||||
| } | ||||
| 
 | ||||
| impl PSOPacketData for ShipListEntry { | ||||
|     fn from_bytes<R: Read>(cursor: &mut R) -> Result<Self, PacketParseError> { | ||||
|         let mut buf4 = [0u8; 4]; | ||||
|         cursor.read(&mut buf4).map_err(|_| PacketParseError::ReadError)?; | ||||
|         let menu = u32::from_le_bytes(buf4); | ||||
|         cursor.read(&mut buf4).map_err(|_| PacketParseError::ReadError)?; | ||||
|         let item = u32::from_le_bytes(buf4); | ||||
| 
 | ||||
|         let mut buf2 = [0u8; 2]; | ||||
|         cursor.read(&mut buf2).map_err(|_| PacketParseError::ReadError)?; | ||||
|         let flags = u16::from_le_bytes(buf2); | ||||
| 
 | ||||
|         let mut name = [0u8; 0x11 * 2]; | ||||
|         cursor.read(&mut name).map_err(|_| PacketParseError::ReadError)?; | ||||
|         Ok(ShipListEntry { | ||||
|             menu: menu, | ||||
|             item: item, | ||||
|             flags: flags, | ||||
|             name: unsafe { std::mem::transmute(name)} | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     fn as_bytes(&self) -> Vec<u8> { | ||||
|         let mut bytes = Vec::new(); | ||||
|         bytes.extend_from_slice(&u32::to_le_bytes(self.menu)); | ||||
|         bytes.extend_from_slice(&u32::to_le_bytes(self.item)); | ||||
|         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()
 | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| pub struct ShipList { | ||||
|     pub flag: u32, | ||||
|     pub ships: Vec<ShipListEntry>, | ||||
| } | ||||
| 
 | ||||
| @ -490,7 +509,7 @@ impl PSOPacket for ShipList { | ||||
| impl std::fmt::Debug for ShipList { | ||||
|     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||||
|         write!(f, "packet ShipList {{\n").unwrap(); | ||||
|         write!(f, "    flag: {:?}\n", self.flag).unwrap(); | ||||
|         write!(f, "    flag: {:?}\n", 0).unwrap(); | ||||
|         write!(f, "    ships: {:?}]\n", self.ships).unwrap(); | ||||
|         write!(f, "}}") | ||||
|     } | ||||
| @ -499,7 +518,6 @@ impl std::fmt::Debug for ShipList { | ||||
| 
 | ||||
| #[pso_packet(0x10)] | ||||
| pub struct MenuSelect { | ||||
|     pub flag: u32, | ||||
|     pub menu: u32, | ||||
|     pub item: u32, | ||||
| } | ||||
| @ -511,7 +529,6 @@ mod tests { | ||||
|     fn test_account_status_enum() { | ||||
|         use super::PSOPacket; | ||||
|         let pkt = super::LoginResponse { | ||||
|             flag: 0, | ||||
|             status: super::AccountStatus::InvalidPassword, | ||||
|             tag: 0, | ||||
|             guildcard: 0, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user