From e9a24e515df97cb971fd7e67d2a9e13cab1491b7 Mon Sep 17 00:00:00 2001 From: jake Date: Fri, 13 Sep 2019 19:21:33 -0700 Subject: [PATCH] param pkt --- src/login/character.rs | 76 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) diff --git a/src/login/character.rs b/src/login/character.rs index 19db09f..be112cf 100644 --- a/src/login/character.rs +++ b/src/login/character.rs @@ -1,4 +1,6 @@ use std::net; +use std::sync::Arc; +use std::io::Read; use rand::{Rng, RngCore}; use bcrypt::{DEFAULT_COST, hash, verify}; @@ -16,6 +18,7 @@ use elseware::common::network::{PacketNetworkError}; use elseware::common::client::Client; use elseware::common::serverstate::{SendServerPacket, RecvServerPacket, ServerState, OnConnect, ClientId}; use elseware::common::util::array_to_utf8; +use elseware::utf8_to_array; use crate::dataaccess::DataAccess; use crate::login::{SharedLoginState, get_login_status}; @@ -36,6 +39,8 @@ pub enum RecvCharacterPacket { Checksum(Checksum), GuildcardDataRequest(GuildcardDataRequest), GuildcardDataChunkRequest(GuildcardDataChunkRequest), + ParamDataRequest(ParamDataRequest), + ParamDataChunkRequest(ParamDataChunkRequest), } impl RecvServerPacket for RecvCharacterPacket { @@ -47,6 +52,8 @@ impl RecvServerPacket for RecvCharacterPacket { 0x1E8 => Ok(RecvCharacterPacket::Checksum(Checksum::from_bytes(data)?)), 0x3E8 => Ok(RecvCharacterPacket::GuildcardDataRequest(GuildcardDataRequest::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) } } @@ -62,7 +69,9 @@ pub enum SendCharacterPacket { ChecksumAck(ChecksumAck), CharacterPreview(CharacterPreview), GuildcardDataHeader(GuildcardDataHeader), - GuildcardDataChunk(GuildcardDataChunk) + GuildcardDataChunk(GuildcardDataChunk), + ParamDataHeader(ParamDataHeader), + ParamDataChunk(ParamDataChunk), } impl SendServerPacket for SendCharacterPacket { @@ -76,14 +85,52 @@ impl SendServerPacket for SendCharacterPacket { SendCharacterPacket::CharacterPreview(pkt) => pkt.as_bytes(), SendCharacterPacket::GuildcardDataHeader(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(), } } } + +fn generate_param_data(path: &str) -> (ParamDataHeader, Vec) { + 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(¶m).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 pub struct CharacterServerState { //shared_state: SharedLoginState, data_access: DA, + param_header: ParamDataHeader, + + param_index: usize, + param_data: Arc>, user: Option, characters: Option<[Option; 4]>, guildcard_data_buffer: Option>, @@ -92,9 +139,15 @@ pub struct CharacterServerState { impl CharacterServerState { pub fn new(data_access: DA) -> CharacterServerState { + let (param_header, param_data) = generate_param_data("param/"); + CharacterServerState { //shared_state: shared_state, data_access: data_access, + param_header: param_header, + + param_index: 0, + param_data: Arc::new(param_data), user: None, characters: None, guildcard_data_buffer: None, @@ -226,6 +279,27 @@ impl ServerState for CharacterServerState { }, RecvCharacterPacket::GuildcardDataChunkRequest(request) => { 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))) } } }