Browse Source

convert login packets

pull/3/head
jake 5 years ago
parent
commit
04322d2526
  1. 147
      src/packet/login.rs

147
src/packet/login.rs

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

Loading…
Cancel
Save