patch the patch server
This commit is contained in:
		
							parent
							
								
									c7a4dff627
								
							
						
					
					
						commit
						a578aba450
					
				@ -18,6 +18,7 @@ use crate::common::serverstate::{RecvServerPacket, SendServerPacket, ServerState
 | 
				
			|||||||
pub enum PatchError {
 | 
					pub enum PatchError {
 | 
				
			||||||
    NetworkError(NetworkError),
 | 
					    NetworkError(NetworkError),
 | 
				
			||||||
    IOError(std::io::Error),
 | 
					    IOError(std::io::Error),
 | 
				
			||||||
 | 
					    NoSuchClient(ClientId),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<NetworkError> for PatchError {
 | 
					impl From<NetworkError> for PatchError {
 | 
				
			||||||
@ -135,11 +136,11 @@ impl SendServerPacket for SendPatchPacket {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
pub struct PatchServerState {
 | 
					pub struct PatchServerState {
 | 
				
			||||||
    patch_file_tree: PatchFileTree,
 | 
					    patch_file_tree: PatchFileTree,
 | 
				
			||||||
    patch_file_lookup: HashMap<u32, PatchFile>,
 | 
					    patch_file_lookup: HashMap<u32, PatchFile>,
 | 
				
			||||||
    patch_file_info: Vec<FileInfoReply>,
 | 
					    patch_file_info: Vec<FileInfoReply>,
 | 
				
			||||||
 | 
					    client_file_info: HashMap<ClientId, Vec<FileInfoReply>>,
 | 
				
			||||||
    patch_motd: String,
 | 
					    patch_motd: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -149,6 +150,7 @@ impl PatchServerState {
 | 
				
			|||||||
            patch_file_tree,
 | 
					            patch_file_tree,
 | 
				
			||||||
            patch_file_lookup,
 | 
					            patch_file_lookup,
 | 
				
			||||||
            patch_file_info: Vec::new(),
 | 
					            patch_file_info: Vec::new(),
 | 
				
			||||||
 | 
					            client_file_info: HashMap::new(),
 | 
				
			||||||
            patch_motd,
 | 
					            patch_motd,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -160,10 +162,11 @@ impl ServerState for PatchServerState {
 | 
				
			|||||||
    type RecvPacket = RecvPatchPacket;
 | 
					    type RecvPacket = RecvPatchPacket;
 | 
				
			||||||
    type PacketError = PatchError;
 | 
					    type PacketError = PatchError;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn on_connect(&mut self, _id: ClientId) -> Result<Vec<OnConnect<Self::SendPacket>>, PatchError> {
 | 
					    async fn on_connect(&mut self, id: ClientId) -> Result<Vec<OnConnect<Self::SendPacket>>, PatchError> {
 | 
				
			||||||
        let mut rng = rand::thread_rng();
 | 
					        let mut rng = rand::thread_rng();
 | 
				
			||||||
        let key_in: u32 = rng.gen();
 | 
					        let key_in: u32 = rng.gen();
 | 
				
			||||||
        let key_out: 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))),
 | 
					        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))))
 | 
					             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)))
 | 
					                Box::new(p.into_iter().map(move |pkt| (id, pkt)))
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            RecvPatchPacket::FileInfoReply(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)))
 | 
					                Box::new(None.into_iter().map(move |pkt| (id, pkt)))
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            RecvPatchPacket::FileInfoListEnd(_pkt) => {
 | 
					            RecvPatchPacket::FileInfoListEnd(_pkt) => {
 | 
				
			||||||
                let need_update = self.patch_file_info.iter()
 | 
					                // let need_update = self.patch_file_info.iter()
 | 
				
			||||||
                    .filter(|file_info| does_file_need_updating(file_info, &self.patch_file_lookup))
 | 
					                //     .filter(|file_info| does_file_need_updating(file_info, &self.patch_file_lookup))
 | 
				
			||||||
                    .collect::<Vec<_>>();
 | 
					                //     .collect::<Vec<_>>();
 | 
				
			||||||
 | 
					                println!("patch server hashmap: {:?}", self.patch_file_lookup);
 | 
				
			||||||
                let total_size = need_update.iter().fold(0, |a, file_info| a + file_info.size);
 | 
					                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::<Vec<_>>(); // 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;
 | 
					                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)),
 | 
					                let p = vec![SendPatchPacket::FilesToPatchMetadata(FilesToPatchMetadata::new(total_size, total_files)),
 | 
				
			||||||
                             SendPatchPacket::PatchStartList(PatchStartList {})
 | 
					                             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<Vec<(ClientId, SendPatchPacket)>, PatchError> {
 | 
					    async fn on_disconnect(&mut self, id: ClientId) -> Result<Vec<(ClientId, SendPatchPacket)>, PatchError> {
 | 
				
			||||||
 | 
					        self.client_file_info.remove(&id);
 | 
				
			||||||
        Ok(Vec::new())
 | 
					        Ok(Vec::new())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -279,9 +295,10 @@ fn get_checksum_and_size(path: &Path) -> Result<(u32, u32), PatchError> {
 | 
				
			|||||||
    Ok((crc.sum32(), size as u32))
 | 
					    Ok((crc.sum32(), size as u32))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn does_file_need_updating(file_info: &FileInfoReply, patch_file_lookup: &HashMap<u32, PatchFile>) -> bool {
 | 
					fn does_file_need_updating(client_file_info: &FileInfoReply, patch_file_lookup: &HashMap<u32, PatchFile>) -> bool {
 | 
				
			||||||
    let patch_file = patch_file_lookup.get(&file_info.id).unwrap();
 | 
					    let patch_file = patch_file_lookup.get(&client_file_info.id).unwrap();
 | 
				
			||||||
    patch_file.checksum != file_info.checksum || patch_file.size != file_info.size
 | 
					    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 {
 | 
					impl SendFileIterator {
 | 
				
			||||||
    fn new(state: &PatchServerState) -> SendFileIterator {
 | 
					    fn new(state: &PatchServerState, client_file_info: Vec<&FileInfoReply>) -> SendFileIterator {
 | 
				
			||||||
        let file_ids_to_update = state.patch_file_info.iter()
 | 
					        // let file_ids_to_update = state.patch_file_info.iter()
 | 
				
			||||||
            .filter(|file_info| does_file_need_updating(file_info, &state.patch_file_lookup))
 | 
					        //     .filter(|file_info| does_file_need_updating(file_info, &state.patch_file_lookup))
 | 
				
			||||||
 | 
					        //     .map(|k| k.id)
 | 
				
			||||||
 | 
					        //     .collect::<HashSet<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let file_ids_to_update = client_file_info.iter()
 | 
				
			||||||
            .map(|k| k.id)
 | 
					            .map(|k| k.id)
 | 
				
			||||||
            .collect::<HashSet<_>>();
 | 
					            .collect::<HashSet<_>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user