|
@ -1,3 +1,5 @@ |
|
|
|
|
|
use chrono::{DateTime, Utc};
|
|
|
|
|
|
|
|
|
use psopacket::pso_packet;
|
|
|
use psopacket::pso_packet;
|
|
|
use crate::{PSOPacket, PacketParseError};
|
|
|
use crate::{PSOPacket, PacketParseError};
|
|
|
|
|
|
|
|
@ -129,6 +131,18 @@ impl LoginResponse { |
|
|
caps: 0x00000102,
|
|
|
caps: 0x00000102,
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
|
|
|
guildcard: guildcard,
|
|
|
|
|
|
team_id: team_id,
|
|
|
|
|
|
security_data: security_data,
|
|
|
|
|
|
caps: 0x00000102,
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -395,6 +409,93 @@ pub struct ParamDataChunk { |
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[pso_packet(0xEC)]
|
|
|
|
|
|
pub struct SetFlag {
|
|
|
|
|
|
flag: u32,
|
|
|
|
|
|
pub flags: u32,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[pso_packet(0xB1)]
|
|
|
|
|
|
pub struct Timestamp {
|
|
|
|
|
|
flag: u32,
|
|
|
|
|
|
timestamp: [u8; 28],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Timestamp {
|
|
|
|
|
|
pub fn new(time: DateTime<Utc>) -> Timestamp {
|
|
|
|
|
|
let timestr = time.format("%Y:%m:%d: %H:%M:%S").to_string();
|
|
|
|
|
|
let timebytes = timestr.as_bytes();
|
|
|
|
|
|
let mut timebuf = [0u8; 28];
|
|
|
|
|
|
timebuf[..timebytes.len()].clone_from_slice(timebytes);
|
|
|
|
|
|
Timestamp {
|
|
|
|
|
|
flag: 0,
|
|
|
|
|
|
timestamp: timebuf
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
|
pub struct ShipListEntry {
|
|
|
|
|
|
pub menu: u32,
|
|
|
|
|
|
pub item: u32,
|
|
|
|
|
|
pub flags: u16,
|
|
|
|
|
|
pub name: [u16; 0x11],
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub struct ShipList {
|
|
|
|
|
|
pub flag: u32,
|
|
|
|
|
|
pub ships: Vec<ShipListEntry>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl PSOPacket for ShipList {
|
|
|
|
|
|
fn from_bytes(_data: &[u8]) -> Result<ShipList, PacketParseError> {
|
|
|
|
|
|
unimplemented!();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn as_bytes(&self) -> Vec<u8> {
|
|
|
|
|
|
let mut buf: Vec<u8> = Vec::new();
|
|
|
|
|
|
buf.extend_from_slice(&u32::to_le_bytes(self.ships.len() as u32));
|
|
|
|
|
|
buf.extend_from_slice(&u32::to_le_bytes(0));
|
|
|
|
|
|
buf.extend_from_slice(&u32::to_le_bytes(0));
|
|
|
|
|
|
buf.extend_from_slice(&u16::to_le_bytes(0));
|
|
|
|
|
|
let filler_name: [u16; 0x11] = ['S' as u16,0, 'h' as u16,0, 'i' as u16,0, 'p' as u16 ,0,0,0,0,0,0,0,0,0,0];
|
|
|
|
|
|
for char in filler_name.iter() {
|
|
|
|
|
|
buf.extend_from_slice(&u16::to_le_bytes(*char));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for ship in self.ships.iter() {
|
|
|
|
|
|
buf.extend_from_slice(&u32::to_le_bytes(ship.menu));
|
|
|
|
|
|
buf.extend_from_slice(&u32::to_le_bytes(ship.item));
|
|
|
|
|
|
buf.extend_from_slice(&u16::to_le_bytes(ship.flags));
|
|
|
|
|
|
for char in ship.name.iter() {
|
|
|
|
|
|
buf.extend_from_slice(&u16::to_le_bytes(*char));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
while buf.len() % 4 != 0 {
|
|
|
|
|
|
buf.push(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let pkt_len = (buf.len() + 4) as u16;
|
|
|
|
|
|
let mut prebuf: Vec<u8> = Vec::new();
|
|
|
|
|
|
prebuf.extend_from_slice(&u16::to_le_bytes(pkt_len));
|
|
|
|
|
|
prebuf.extend_from_slice(&u16::to_le_bytes(0xA0));
|
|
|
|
|
|
prebuf.append(&mut buf);
|
|
|
|
|
|
prebuf
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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, " ships: {:?}]\n", self.ships).unwrap();
|
|
|
|
|
|
write!(f, "}}")
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
#[cfg(test)]
|
|
|