if packet.id() == 0x02 && !logged { if let PlayerForwarding::PluginResponse = server_config.player_forwarding { let ProxyEvent::SendServerPacketEvent { packet: plugin_response_packet, player: _, } = MeexProx::trigger_event( meexprox.clone(), ProxyEvent::SendServerPacketEvent { packet: plugin_response_packet.clone(), player: this.clone(), }, ) else { return Ok(()); }; server_conn.write_packet(&plugin_response_packet)?; } logged = true; continue; } if packet.id() == 0x01 && !logged { let locked = this.lock().unwrap(); if let Some(shared_secret) = locked.shared_secret.as_ref() { if let Some(verify_token) = locked.verify_token.as_ref() { let encryption_response = Packet::build(0x00, move |resp| { resp.write_usize_varint(shared_secret.len())?; resp.write_bytes(&shared_secret)?; resp.write_usize_varint(verify_token.len())?; resp.write_bytes(&verify_token)?; Ok(()) })?; let ProxyEvent::SendServerPacketEvent { packet: encryption_response, player: _, } = MeexProx::trigger_event( meexprox.clone(), ProxyEvent::SendServerPacketEvent { packet: encryption_response, player: this.clone(), }, ) else { return Ok(()); }; server_conn.write_packet(&encryption_response)?; } } continue; } if packet.id() == 0x03 { let threshold = packet.read_isize_varint()?; if threshold >= 0 { let threshold = threshold.zigzag(); server_conn.set_compression(Some(threshold)); client_conn.set_compression(Some(threshold)); } else { server_conn.set_compression(None); client_conn.set_compression(None); } continue; } client_conn.close(); server_conn.close(); if this.lock().unwrap().remove_player(player.clone()) { if let Some(name) = player.lock().unwrap().name.clone() { info!("{} disconnected player {}", addr.to_string(), name); let ProxyEvent::PlayerDisconnectedEvent { player: _ } = MeexProx::trigger_event( this.clone(), ProxyEvent::PlayerDisconnectedEvent { player: player.clone(), }, ) else { return; }; } } let mut client_conn = client_conn.try_clone().unwrap(); let mut server_conn = server_conn.try_clone().unwrap(); let player = player.clone(); let server = server.clone(); let this = this.clone(); move || { let res = || -> Result<(), ProtocolError> { let mut joined = false; let mut encryption = false; loop { if let Some(player_server) = player.lock().unwrap().server.as_ref() { if player_server.host != server.host { break; } } else { break; } let packet = match client_conn.read_packet() { Ok(packet) => packet, Err(_) => break, }; let ProxyEvent::RecvClientPacketEvent { mut packet, player: _, } = MeexProx::trigger_event( this.clone(), ProxyEvent::RecvClientPacketEvent { packet, player: player.clone(), }, ) else { return Ok(()); }; if packet.id() == 0x00 && !joined { let name = packet.read_string()?; let uuid = packet.read_uuid()?; player.lock().unwrap().name = Some(name.clone()); player.lock().unwrap().uuid = Some(uuid.clone()); info!( "{} connected player {} ({})", addr.to_string(), &name, &uuid ); let ProxyEvent::PlayerConnectedEvent { player: _ } = MeexProx::trigger_event( this.clone(), ProxyEvent::PlayerConnectedEvent { player: player.clone(), }, ) else { return Ok(()); }; joined = true; } if packet.id() == 0x01 && !encryption { let shared_secret_length = packet.read_usize_varint()?; let shared_secret = packet.read_bytes(shared_secret_length)?; let verify_token_length = packet.read_usize_varint()?; let verify_token = packet.read_bytes(verify_token_length)?; player.lock().unwrap().shared_secret = Some(shared_secret.clone()); player.lock().unwrap().verify_token = Some(verify_token.clone()); encryption = true; } let ProxyEvent::SendServerPacketEvent { packet, player: _ } = MeexProx::trigger_event( this.clone(), ProxyEvent::SendServerPacketEvent { packet, player: player.clone(), }, ) else { return Ok(()); }; server_conn.write_packet(&packet)?; } Ok(()) }(); if res.is_err() { client_conn.close(); server_conn.close(); if this.lock().unwrap().remove_player(player.clone()) { if let Some(name) = player.lock().unwrap().name.clone() { info!("{} disconnected player {}", addr.to_string(), name); let ProxyEvent::PlayerDisconnectedEvent { player: _ } = MeexProx::trigger_event( this.clone(), ProxyEvent::PlayerDisconnectedEvent { player: player.clone(), }, ) else { return; }; } } } } let res = || -> Result<(), ProtocolError> { loop { if let Some(player_server) = player.lock().unwrap().server.as_ref() { if player_server.host != server.host { break; } } else { break; } let packet = match server_conn.read_packet() { Ok(packet) => packet, Err(_) => break, }; let ProxyEvent::RecvServerPacketEvent { packet, player: _ } = MeexProx::trigger_event( this.clone(), ProxyEvent::RecvServerPacketEvent { packet, player: player.clone(), }, ) else { return Ok(()); }; if packet.id() == 0x02 { if let PlayerForwarding::PluginResponse = server_config.player_forwarding { let ProxyEvent::SendServerPacketEvent { packet: plugin_response_packet, player: _, } = MeexProx::trigger_event( this.clone(), ProxyEvent::SendServerPacketEvent { packet: plugin_response_packet.clone(), player: player.clone(), }, ) else { return Ok(()); }; server_conn.write_packet(&plugin_response_packet)?; } } let ProxyEvent::SendClientPacketEvent { mut packet, player: _, } = MeexProx::trigger_event( this.clone(), ProxyEvent::SendClientPacketEvent { packet, player: player.clone(), }, ) else { return Ok(()); }; client_conn.write_packet(&packet)?; if packet.id() == 0x03 { let threshold = packet.read_isize_varint()?; if threshold >= 0 { let threshold = threshold.zigzag(); server_conn.set_compression(Some(threshold)); client_conn.set_compression(Some(threshold)); } else { server_conn.set_compression(None); client_conn.set_compression(None); } } } Ok(()) }(); if res.is_err() { client_conn.close(); server_conn.close(); if this.lock().unwrap().remove_player(player.clone()) { if let Some(name) = player.lock().unwrap().name.clone() { info!("{} disconnected player {}", addr.to_string(), name); let ProxyEvent::PlayerDisconnectedEvent { player: _ } = MeexProx::trigger_event( this.clone(), ProxyEvent::PlayerDisconnectedEvent { player: player.clone(), }, ) else { return Ok(()); }; } } }