Browse Source

param pkt

pbs
jake 5 years ago
parent
commit
e9a24e515d
  1. 76
      src/login/character.rs

76
src/login/character.rs

@ -1,4 +1,6 @@
use std::net; use std::net;
use std::sync::Arc;
use std::io::Read;
use rand::{Rng, RngCore}; use rand::{Rng, RngCore};
use bcrypt::{DEFAULT_COST, hash, verify}; use bcrypt::{DEFAULT_COST, hash, verify};
@ -16,6 +18,7 @@ use elseware::common::network::{PacketNetworkError};
use elseware::common::client::Client; use elseware::common::client::Client;
use elseware::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use elseware::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId};
use elseware::common::util::array_to_utf8; use elseware::common::util::array_to_utf8;
use elseware::utf8_to_array;
use crate::dataaccess::DataAccess; use crate::dataaccess::DataAccess;
use crate::login::{SharedLoginState, get_login_status}; use crate::login::{SharedLoginState, get_login_status};
@ -36,6 +39,8 @@ pub enum RecvCharacterPacket {
Checksum(Checksum), Checksum(Checksum),
GuildcardDataRequest(GuildcardDataRequest), GuildcardDataRequest(GuildcardDataRequest),
GuildcardDataChunkRequest(GuildcardDataChunkRequest), GuildcardDataChunkRequest(GuildcardDataChunkRequest),
ParamDataRequest(ParamDataRequest),
ParamDataChunkRequest(ParamDataChunkRequest),
} }
impl RecvServerPacket for RecvCharacterPacket { impl RecvServerPacket for RecvCharacterPacket {
@ -47,6 +52,8 @@ impl RecvServerPacket for RecvCharacterPacket {
0x1E8 => Ok(RecvCharacterPacket::Checksum(Checksum::from_bytes(data)?)), 0x1E8 => Ok(RecvCharacterPacket::Checksum(Checksum::from_bytes(data)?)),
0x3E8 => Ok(RecvCharacterPacket::GuildcardDataRequest(GuildcardDataRequest::from_bytes(data)?)), 0x3E8 => Ok(RecvCharacterPacket::GuildcardDataRequest(GuildcardDataRequest::from_bytes(data)?)),
0x3DC => Ok(RecvCharacterPacket::GuildcardDataChunkRequest(GuildcardDataChunkRequest::from_bytes(data)?)), 0x3DC => Ok(RecvCharacterPacket::GuildcardDataChunkRequest(GuildcardDataChunkRequest::from_bytes(data)?)),
0x4EB => Ok(RecvCharacterPacket::ParamDataRequest(ParamDataRequest::from_bytes(data)?)),
0x3EB => Ok(RecvCharacterPacket::ParamDataChunkRequest(ParamDataChunkRequest::from_bytes(data)?)),
_ => Err(PacketParseError::WrongPacketForServerType) _ => Err(PacketParseError::WrongPacketForServerType)
} }
} }
@ -62,7 +69,9 @@ pub enum SendCharacterPacket {
ChecksumAck(ChecksumAck), ChecksumAck(ChecksumAck),
CharacterPreview(CharacterPreview), CharacterPreview(CharacterPreview),
GuildcardDataHeader(GuildcardDataHeader), GuildcardDataHeader(GuildcardDataHeader),
GuildcardDataChunk(GuildcardDataChunk)
GuildcardDataChunk(GuildcardDataChunk),
ParamDataHeader(ParamDataHeader),
ParamDataChunk(ParamDataChunk),
} }
impl SendServerPacket for SendCharacterPacket { impl SendServerPacket for SendCharacterPacket {
@ -76,14 +85,52 @@ impl SendServerPacket for SendCharacterPacket {
SendCharacterPacket::CharacterPreview(pkt) => pkt.as_bytes(), SendCharacterPacket::CharacterPreview(pkt) => pkt.as_bytes(),
SendCharacterPacket::GuildcardDataHeader(pkt) => pkt.as_bytes(), SendCharacterPacket::GuildcardDataHeader(pkt) => pkt.as_bytes(),
SendCharacterPacket::GuildcardDataChunk(pkt) => pkt.as_bytes(), SendCharacterPacket::GuildcardDataChunk(pkt) => pkt.as_bytes(),
SendCharacterPacket::ParamDataHeader(pkt) => pkt.as_bytes(),
SendCharacterPacket::ParamDataChunk(pkt) => pkt.as_bytes(),
//SendLoginPacket::RedirectClient(pkt) => pkt.as_bytes(), //SendLoginPacket::RedirectClient(pkt) => pkt.as_bytes(),
} }
} }
} }
fn generate_param_data(path: &str) -> (ParamDataHeader, Vec<u8>) {
let paths = std::fs::read_dir(path).expect("could not find param/ directory");
let mut files = Vec::new();
let mut buffer = Vec::new();
for p in paths {
let param = p.unwrap().path();
let mut file = std::fs::File::open(&param).unwrap();
let mut filebuf = Vec::new();
let len = file.read_to_end(&mut filebuf).unwrap();
let mut crc = crc32::Digest::new(crc32::IEEE);
crc.write(&filebuf[..]);
files.push(ParamFile {
size: len as u32,
checksum: crc.sum32(),
offset: buffer.len() as u32,
filename: utf8_to_array!(param.file_name().unwrap().to_str().unwrap(), 0x40),
});
buffer.append(&mut filebuf);
}
(ParamDataHeader {
files: files
}, buffer)
}
// TODO: rip these client-specific vars into a HashMap<ClientId, ClientState>
pub struct CharacterServerState<DA: DataAccess> { pub struct CharacterServerState<DA: DataAccess> {
//shared_state: SharedLoginState<DA>, //shared_state: SharedLoginState<DA>,
data_access: DA, data_access: DA,
param_header: ParamDataHeader,
param_index: usize,
param_data: Arc<Vec<u8>>,
user: Option<UserAccount>, user: Option<UserAccount>,
characters: Option<[Option<Character>; 4]>, characters: Option<[Option<Character>; 4]>,
guildcard_data_buffer: Option<Vec<u8>>, guildcard_data_buffer: Option<Vec<u8>>,
@ -92,9 +139,15 @@ pub struct CharacterServerState<DA: DataAccess> {
impl<DA: DataAccess> CharacterServerState<DA> { impl<DA: DataAccess> CharacterServerState<DA> {
pub fn new(data_access: DA) -> CharacterServerState<DA> { pub fn new(data_access: DA) -> CharacterServerState<DA> {
let (param_header, param_data) = generate_param_data("param/");
CharacterServerState { CharacterServerState {
//shared_state: shared_state, //shared_state: shared_state,
data_access: data_access, data_access: data_access,
param_header: param_header,
param_index: 0,
param_data: Arc::new(param_data),
user: None, user: None,
characters: None, characters: None,
guildcard_data_buffer: None, guildcard_data_buffer: None,
@ -226,6 +279,27 @@ impl<DA: DataAccess> ServerState for CharacterServerState<DA> {
}, },
RecvCharacterPacket::GuildcardDataChunkRequest(request) => { RecvCharacterPacket::GuildcardDataChunkRequest(request) => {
Box::new(self.guildcard_data_chunk(request.chunk, request.again).into_iter().map(move |pkt| (id, pkt))) Box::new(self.guildcard_data_chunk(request.chunk, request.again).into_iter().map(move |pkt| (id, pkt)))
},
RecvCharacterPacket::ParamDataRequest(_request) => {
Box::new(vec![SendCharacterPacket::ParamDataHeader(self.param_header.clone())].into_iter().map(move |pkt| (id, pkt)))
},
RecvCharacterPacket::ParamDataChunkRequest(_request) => {
let chunk = self.param_index;
self.param_index += 1;
let start = chunk * 0x6800;
let end = std::cmp::min((chunk+1)*0x6800, self.param_data.len());
let mut data = [0u8; 0x6800];
data[..end-start].copy_from_slice(&self.param_data[start..end]);
Box::new(vec![SendCharacterPacket::ParamDataChunk(
ParamDataChunk {
flag: 0,
chunk: chunk as u32,
data: data,
}
)].into_iter().map(move |pkt| (id, pkt)))
} }
} }
} }

Loading…
Cancel
Save