diff --git a/src/patch/main.rs b/src/patch/main.rs index 6315ba6..06875e1 100644 --- a/src/patch/main.rs +++ b/src/patch/main.rs @@ -17,16 +17,16 @@ use elseware::pktvec; use elseware::common::pktvec::PktVec; use elseware::common::network::{PacketNetworkError}; use elseware::common::client::Client; -use elseware::common::serverstate::{ServerPacket, ServerState, OnConnect}; +use elseware::common::serverstate::{RecvServerPacket, SendServerPacket, ServerState, OnConnect}; const PATCH_PORT: u16 = 11000; #[derive(Debug)] enum PatchError { PacketNetworkError(PacketNetworkError), - UnexpectedPacket(Box), + //UnexpectedPacket(Box), IOError(std::io::Error), - CloseConnection, + //CloseConnection, } // TODO: something like @@ -93,25 +93,63 @@ impl PatchFileTree { #[derive(Debug)] -pub enum PatchPacket { +pub enum RecvPatchPacket { PatchWelcomeReply(PatchWelcomeReply), LoginReply(LoginReply), FileInfoReply(FileInfoReply), FileInfoListEnd(FileInfoListEnd), } -impl ServerPacket for PatchPacket { - fn from_bytes(data: &Vec) -> Result { +impl RecvServerPacket for RecvPatchPacket { + fn from_bytes(data: &Vec) -> Result { match data[2] { - 0x02 => Ok(PatchPacket::PatchWelcomeReply(PatchWelcomeReply::from_bytes(data)?)), - 0x04 => Ok(PatchPacket::LoginReply(LoginReply::from_bytes(data)?)), - 0x0F => Ok(PatchPacket::FileInfoReply(FileInfoReply::from_bytes(data)?)), - 0x10 => Ok(PatchPacket::FileInfoListEnd(FileInfoListEnd::from_bytes(data)?)), + 0x02 => Ok(RecvPatchPacket::PatchWelcomeReply(PatchWelcomeReply::from_bytes(data)?)), + 0x04 => Ok(RecvPatchPacket::LoginReply(LoginReply::from_bytes(data)?)), + 0x0F => Ok(RecvPatchPacket::FileInfoReply(FileInfoReply::from_bytes(data)?)), + 0x10 => Ok(RecvPatchPacket::FileInfoListEnd(FileInfoListEnd::from_bytes(data)?)), _ => Err(PacketParseError::WrongPacketForServerType) } } } +#[derive(Debug)] +pub enum SendPatchPacket { + ChangeDirectory(ChangeDirectory), + EndFileSend(EndFileSend), + FileInfo(FileInfo), + FileSend(FileSend), + FilesToPatchMetadata(FilesToPatchMetadata), + FinalizePatching(FinalizePatching), + Message(Message), + PatchEndList(PatchEndList), + PatchStartList(PatchStartList), + PatchWelcome(PatchWelcome), + RequestLogin(RequestLogin), + StartFileSend(StartFileSend), + UpOneDirectory(UpOneDirectory), +} + +impl SendServerPacket for SendPatchPacket { + fn as_bytes(&self) -> Vec { + match self { + SendPatchPacket::ChangeDirectory(pkt) => pkt.as_bytes(), + SendPatchPacket::EndFileSend(pkt) => pkt.as_bytes(), + SendPatchPacket::FileInfo(pkt) => pkt.as_bytes(), + SendPatchPacket::FileSend(pkt) => pkt.as_bytes(), + SendPatchPacket::FilesToPatchMetadata(pkt) => pkt.as_bytes(), + SendPatchPacket::FinalizePatching(pkt) => pkt.as_bytes(), + SendPatchPacket::Message(pkt) => pkt.as_bytes(), + SendPatchPacket::PatchEndList(pkt) => pkt.as_bytes(), + SendPatchPacket::PatchStartList(pkt) => pkt.as_bytes(), + SendPatchPacket::PatchWelcome(pkt) => pkt.as_bytes(), + SendPatchPacket::RequestLogin(pkt) => pkt.as_bytes(), + SendPatchPacket::StartFileSend(pkt) => pkt.as_bytes(), + SendPatchPacket::UpOneDirectory(pkt) => pkt.as_bytes(), + } + } +} + + struct PatchServerState { patch_file_tree: PatchFileTree, patch_file_lookup: HashMap, @@ -129,35 +167,36 @@ impl PatchServerState { } impl ServerState for PatchServerState { - type Packet = PatchPacket; + type SendPacket = SendPatchPacket; + type RecvPacket = RecvPatchPacket; type PacketError = PatchError; - fn on_connect(&mut self) -> Vec { + fn on_connect(&mut self) -> Vec> { let mut rng = rand::thread_rng(); let key_in: u32 = rng.gen(); let key_out: u32 = rng.gen(); - vec![OnConnect::Packet(Box::new(PatchWelcome::new(key_out, key_in))), + vec![OnConnect::Packet(SendPatchPacket::PatchWelcome(PatchWelcome::new(key_out, key_in))), OnConnect::Cipher((Box::new(PSOPCCipher::new(key_in)), Box::new(PSOPCCipher::new(key_out)))) ] } - fn handle(&mut self, pkt: &PatchPacket) -> Box>> { + fn handle(&mut self, pkt: &RecvPatchPacket) -> Box> { match pkt { - PatchPacket::PatchWelcomeReply(_pkt) => { - pktvec![RequestLogin {}] + RecvPatchPacket::PatchWelcomeReply(_pkt) => { + Box::new(vec![SendPatchPacket::RequestLogin(RequestLogin {})].into_iter()) }, - PatchPacket::LoginReply(_pkt) => { - let mut p = pktvec![Message::new("hello player".to_string())]; - p.append(get_file_list_packets(&self.patch_file_tree)); - p.push(Box::new(PatchEndList {})); - p + RecvPatchPacket::LoginReply(_pkt) => { + let mut p = vec![SendPatchPacket::Message(Message::new("hello player".to_string()))]; + p.append(&mut get_file_list_packets(&self.patch_file_tree)); + p.push(SendPatchPacket::PatchEndList(PatchEndList {})); + Box::new(p.into_iter()) }, - PatchPacket::FileInfoReply(pkt) => { + RecvPatchPacket::FileInfoReply(pkt) => { self.patch_file_info.push(pkt.clone()); Box::new(None.into_iter()) }, - PatchPacket::FileInfoListEnd(_pkt) => { + RecvPatchPacket::FileInfoListEnd(_pkt) => { let need_update = self.patch_file_info.iter() .filter(|file_info| does_file_need_updating(file_info, &self.patch_file_lookup)) .collect::>(); @@ -165,10 +204,10 @@ impl ServerState for PatchServerState { let total_size = need_update.iter().fold(0, |a, file_info| a + file_info.size); let total_files = need_update.len() as u32; - let p = pktvec![FilesToPatchMetadata::new(total_size, total_files), - PatchStartList {} + let p = vec![SendPatchPacket::FilesToPatchMetadata(FilesToPatchMetadata::new(total_size, total_files)), + SendPatchPacket::PatchStartList(PatchStartList {}) ]; - Box::new(p.chain(SendFileIterator::new(&self))) + Box::new(p.into_iter().chain(SendFileIterator::new(&self))) } } } @@ -211,19 +250,19 @@ fn generate_patch_tree(basedir: &str) -> (PatchFileTree, HashMap } -fn get_file_list_packets(patch_file_tree: &PatchFileTree) -> Vec> { - let mut pkts: Vec> = Vec::new(); +fn get_file_list_packets(patch_file_tree: &PatchFileTree) -> Vec { + let mut pkts = Vec::new(); for item in patch_file_tree.flatten() { match item { PatchTreeIterItem::Directory(path) => { - pkts.push(Box::new(ChangeDirectory::new(path.to_str().unwrap()))); + pkts.push(SendPatchPacket::ChangeDirectory(ChangeDirectory::new(path.to_str().unwrap()))); }, PatchTreeIterItem::File(path, id) => { - pkts.push(Box::new(FileInfo::new(path.to_str().unwrap(), id))); + pkts.push(SendPatchPacket::FileInfo(FileInfo::new(path.to_str().unwrap(), id))); }, PatchTreeIterItem::UpDirectory => { - pkts.push(Box::new(UpOneDirectory {})); + pkts.push(SendPatchPacket::UpOneDirectory(UpOneDirectory {})); } } } @@ -281,7 +320,7 @@ impl SendFileIterator { } impl Iterator for SendFileIterator { - type Item = Box; + type Item = SendPatchPacket; fn next(&mut self) -> Option { if self.done { @@ -295,19 +334,19 @@ impl Iterator for SendFileIterator { if len == 0 { self.current_file = None; self.chunk_num = 0; - Some(Box::new(EndFileSend::new())) + Some(SendPatchPacket::EndFileSend(EndFileSend::new())) } else { let mut crc = crc32::Digest::new(crc32::IEEE); crc.write(&buf[0..len]); - let pkt = FileSend { + let pkt = SendPatchPacket::FileSend(FileSend { chunk_num: self.chunk_num, checksum: crc.sum32(), chunk_size: len as u32, buffer: buf, - }; + }); self.chunk_num += 1; - Some(Box::new(pkt)) + Some(pkt) } }, None => { @@ -315,7 +354,7 @@ impl Iterator for SendFileIterator { Some(next_file) => { match next_file { PatchTreeIterItem::Directory(path) => { - Some(Box::new(ChangeDirectory::new(path.to_str().unwrap()))) + Some(SendPatchPacket::ChangeDirectory(ChangeDirectory::new(path.to_str().unwrap()))) }, PatchTreeIterItem::File(path, id) => { if self.file_ids_to_update.contains(&id) { @@ -323,21 +362,21 @@ impl Iterator for SendFileIterator { let file = fs::File::open(&patch_file.path).unwrap(); let size = file.metadata().unwrap().len(); self.current_file = Some(io::BufReader::new(file)); - Some(Box::new(StartFileSend::new(path.to_str().unwrap(), size as u32, id))) + Some(SendPatchPacket::StartFileSend(StartFileSend::new(path.to_str().unwrap(), size as u32, id))) } else { self.next() } }, PatchTreeIterItem::UpDirectory => { - Some(Box::new(UpOneDirectory {})) + Some(SendPatchPacket::UpOneDirectory(UpOneDirectory {})) }, } }, None => { self.current_file = None; self.done = true; - Some(Box::new(FinalizePatching {})) + Some(SendPatchPacket::FinalizePatching(FinalizePatching {})) } } } @@ -353,8 +392,6 @@ fn new_client(socket: net::TcpStream, patch_file_tree: PatchFileTree, patch_file client.io_loop(); } - - fn main() { println!("[patch] starting server"); @@ -390,6 +427,5 @@ fn main() { }); } - println!("[patch] exiting..."); }