convert patch server to new serverstate
This commit is contained in:
		
							parent
							
								
									606bd191b8
								
							
						
					
					
						commit
						86f994164e
					
				| @ -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<dyn PSOPacket>), | ||||
|     //UnexpectedPacket(Box<dyn PSOPacket>),
 | ||||
|     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<u8>) -> Result<PatchPacket, PacketParseError> { | ||||
| impl RecvServerPacket for RecvPatchPacket { | ||||
|     fn from_bytes(data: &Vec<u8>) -> Result<RecvPatchPacket, PacketParseError> { | ||||
|         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<u8> { | ||||
|         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<u32, PatchFile>, | ||||
| @ -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<OnConnect> { | ||||
|     fn on_connect(&mut self) -> Vec<OnConnect<Self::SendPacket>> { | ||||
|         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<dyn Iterator<Item = Box<dyn PSOPacket>>> { | ||||
|     fn handle(&mut self, pkt: &RecvPatchPacket) -> Box<dyn Iterator<Item = SendPatchPacket>> { | ||||
|         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::<Vec<_>>(); | ||||
| @ -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<u32, PatchFile> | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| fn get_file_list_packets(patch_file_tree: &PatchFileTree) -> Vec<Box<dyn PSOPacket>> { | ||||
|     let mut pkts: Vec<Box<dyn PSOPacket>> = Vec::new(); | ||||
| fn get_file_list_packets(patch_file_tree: &PatchFileTree) -> Vec<SendPatchPacket> { | ||||
|     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<dyn PSOPacket>; | ||||
|     type Item = SendPatchPacket; | ||||
| 
 | ||||
|     fn next(&mut self) -> Option<Self::Item> { | ||||
|         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..."); | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user