From a578aba450f04c1f14b953cd97c56e0f7b0829f1 Mon Sep 17 00:00:00 2001 From: andy Date: Sat, 19 Feb 2022 22:59:00 +0000 Subject: [PATCH] patch the patch server --- src/patch/patch.rs | 55 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/src/patch/patch.rs b/src/patch/patch.rs index 52dd7d2..4a43477 100644 --- a/src/patch/patch.rs +++ b/src/patch/patch.rs @@ -18,6 +18,7 @@ use crate::common::serverstate::{RecvServerPacket, SendServerPacket, ServerState pub enum PatchError { NetworkError(NetworkError), IOError(std::io::Error), + NoSuchClient(ClientId), } impl From for PatchError { @@ -135,11 +136,11 @@ impl SendServerPacket for SendPatchPacket { } } - pub struct PatchServerState { patch_file_tree: PatchFileTree, patch_file_lookup: HashMap, patch_file_info: Vec, + client_file_info: HashMap>, patch_motd: String, } @@ -149,6 +150,7 @@ impl PatchServerState { patch_file_tree, patch_file_lookup, patch_file_info: Vec::new(), + client_file_info: HashMap::new(), patch_motd, } } @@ -160,10 +162,11 @@ impl ServerState for PatchServerState { type RecvPacket = RecvPatchPacket; type PacketError = PatchError; - async fn on_connect(&mut self, _id: ClientId) -> Result>, PatchError> { + async fn on_connect(&mut self, id: ClientId) -> Result>, PatchError> { let mut rng = rand::thread_rng(); let key_in: u32 = rng.gen(); let key_out: u32 = rng.gen(); + self.client_file_info.insert(id, Vec::new()); Ok(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)))) @@ -183,26 +186,39 @@ impl ServerState for PatchServerState { Box::new(p.into_iter().map(move |pkt| (id, pkt))) }, RecvPatchPacket::FileInfoReply(pkt) => { - self.patch_file_info.push(pkt.clone()); + self.client_file_info.get_mut(&id).ok_or(PatchError::NoSuchClient(id))?.push(pkt.clone()); // it should be impossible to error here under normal conditions? + // self.patch_file_info.push(pkt.clone()); + // println!("PatchServerState.patch_file_info: {:?}", self.patch_file_info); Box::new(None.into_iter().map(move |pkt| (id, 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::>(); - - let total_size = need_update.iter().fold(0, |a, file_info| a + file_info.size); + // let need_update = self.patch_file_info.iter() + // .filter(|file_info| does_file_need_updating(file_info, &self.patch_file_lookup)) + // .collect::>(); + println!("patch server hashmap: {:?}", self.patch_file_lookup); + let need_update = self.client_file_info.get(&id) + .ok_or(PatchError::NoSuchClient(id))? + .iter() + .filter(|client_file_info| does_file_need_updating(client_file_info, &self.patch_file_lookup)) + .collect::>(); // collecting list of `client_file_info`s. need to map these to the patch_files and collect those + println!("ClientId({}) needs these files to be updated: {:?}", id, need_update); + // we have the file ids that need to be updated + let total_size = need_update.iter() + .filter_map(|client_file| self.patch_file_lookup.get(&client_file.id)) // TODO: dont unwrap? + .fold(0, |a, file_info| a + file_info.size); let total_files = need_update.len() as u32; - + println!("client {} needs {} bytes of updates across {} files", id, total_size, total_files); let p = vec![SendPatchPacket::FilesToPatchMetadata(FilesToPatchMetadata::new(total_size, total_files)), SendPatchPacket::PatchStartList(PatchStartList {}) ]; - Box::new(p.into_iter().chain(SendFileIterator::new(self)).map(move |pkt| (id, pkt))) + println!("p: {:?}", p); + Box::new(p.into_iter().chain(SendFileIterator::new(self, need_update)).map(move |pkt| (id, pkt))) } }) } - async fn on_disconnect(&mut self, _id: ClientId) -> Result, PatchError> { + async fn on_disconnect(&mut self, id: ClientId) -> Result, PatchError> { + self.client_file_info.remove(&id); Ok(Vec::new()) } } @@ -279,9 +295,10 @@ fn get_checksum_and_size(path: &Path) -> Result<(u32, u32), PatchError> { Ok((crc.sum32(), size as u32)) } -fn does_file_need_updating(file_info: &FileInfoReply, patch_file_lookup: &HashMap) -> bool { - let patch_file = patch_file_lookup.get(&file_info.id).unwrap(); - patch_file.checksum != file_info.checksum || patch_file.size != file_info.size +fn does_file_need_updating(client_file_info: &FileInfoReply, patch_file_lookup: &HashMap) -> bool { + let patch_file = patch_file_lookup.get(&client_file_info.id).unwrap(); + println!("checking if client_file {:?} and patch_file {:?} need to be updated", client_file_info, patch_file); + patch_file.checksum != client_file_info.checksum || patch_file.size != client_file_info.size } @@ -294,9 +311,13 @@ struct SendFileIterator { } impl SendFileIterator { - fn new(state: &PatchServerState) -> SendFileIterator { - let file_ids_to_update = state.patch_file_info.iter() - .filter(|file_info| does_file_need_updating(file_info, &state.patch_file_lookup)) + fn new(state: &PatchServerState, client_file_info: Vec<&FileInfoReply>) -> SendFileIterator { + // let file_ids_to_update = state.patch_file_info.iter() + // .filter(|file_info| does_file_need_updating(file_info, &state.patch_file_lookup)) + // .map(|k| k.id) + // .collect::>(); + + let file_ids_to_update = client_file_info.iter() .map(|k| k.id) .collect::>();