159 lines
5.0 KiB
Rust
159 lines
5.0 KiB
Rust
use crate::{
|
|
protocol::{
|
|
client::{
|
|
config::CFinishConfig,
|
|
login::{CEncryptionRequest, CLoginSuccess},
|
|
status::{CPingResponse, CStatusResponse},
|
|
},
|
|
server::{
|
|
config::{SAcknowledgeFinishConfig, SClientInformation},
|
|
handshake::SHandShake,
|
|
login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart},
|
|
status::{SPingRequest, SStatusRequest},
|
|
},
|
|
ConnectionState,
|
|
},
|
|
server::Server,
|
|
};
|
|
|
|
use super::{Client, PlayerConfig};
|
|
|
|
pub trait ClientPacketProcessor {
|
|
// Handshake
|
|
fn handle_handshake(&mut self, server: &mut Server, handshake: SHandShake);
|
|
// Status
|
|
fn handle_status_request(&mut self, server: &mut Server, status_request: SStatusRequest);
|
|
fn handle_ping_request(&mut self, server: &mut Server, ping_request: SPingRequest);
|
|
// Login
|
|
fn handle_login_start(&mut self, server: &mut Server, login_start: SLoginStart);
|
|
fn handle_encryption_response(
|
|
&mut self,
|
|
server: &mut Server,
|
|
encryption_response: SEncryptionResponse,
|
|
);
|
|
fn handle_plugin_response(
|
|
&mut self,
|
|
server: &mut Server,
|
|
plugin_response: SLoginPluginResponse,
|
|
);
|
|
fn handle_login_acknowledged(
|
|
&mut self,
|
|
server: &mut Server,
|
|
login_acknowledged: SLoginAcknowledged,
|
|
);
|
|
// Config
|
|
fn handle_client_information(
|
|
&mut self,
|
|
server: &mut Server,
|
|
client_information: SClientInformation,
|
|
);
|
|
fn handle_config_acknowledged(
|
|
&mut self,
|
|
server: &mut Server,
|
|
config_acknowledged: SAcknowledgeFinishConfig,
|
|
);
|
|
}
|
|
|
|
impl ClientPacketProcessor for Client {
|
|
fn handle_handshake(&mut self, _server: &mut Server, handshake: SHandShake) {
|
|
// TODO set protocol version and check protocol version
|
|
self.connection_state = handshake.next_state;
|
|
dbg!("handshake");
|
|
}
|
|
|
|
fn handle_status_request(&mut self, server: &mut Server, _status_request: SStatusRequest) {
|
|
dbg!("sending status");
|
|
|
|
let response = serde_json::to_string(&server.status_response).unwrap();
|
|
|
|
self.send_packet(CStatusResponse::new(response));
|
|
}
|
|
|
|
fn handle_ping_request(&mut self, _server: &mut Server, ping_request: SPingRequest) {
|
|
dbg!("ping");
|
|
self.send_packet(CPingResponse::new(ping_request.payload));
|
|
self.close();
|
|
}
|
|
|
|
fn handle_login_start(&mut self, server: &mut Server, login_start: SLoginStart) {
|
|
dbg!("login start");
|
|
self.name = Some(login_start.name);
|
|
self.uuid = Some(login_start.uuid);
|
|
let verify_token: [u8; 4] = rand::random();
|
|
let public_key_der = &server.public_key_der;
|
|
let packet = CEncryptionRequest::new(
|
|
"".into(),
|
|
public_key_der.len() as i32,
|
|
public_key_der,
|
|
verify_token.len() as i32,
|
|
&verify_token,
|
|
false, // TODO
|
|
);
|
|
self.send_packet(packet);
|
|
}
|
|
|
|
fn handle_encryption_response(
|
|
&mut self,
|
|
server: &mut Server,
|
|
encryption_response: SEncryptionResponse,
|
|
) {
|
|
dbg!("encryption response");
|
|
// should be impossible
|
|
if self.uuid.is_none() || self.name.is_none() {
|
|
self.kick("UUID or Name is none".into());
|
|
return;
|
|
}
|
|
self.enable_encryption(server, encryption_response.shared_secret)
|
|
.unwrap();
|
|
|
|
let packet = CLoginSuccess::new(self.uuid.unwrap(), self.name.clone().unwrap(), 0, false);
|
|
self.send_packet(packet);
|
|
}
|
|
|
|
fn handle_plugin_response(
|
|
&mut self,
|
|
_server: &mut Server,
|
|
_plugin_response: SLoginPluginResponse,
|
|
) {
|
|
}
|
|
|
|
fn handle_login_acknowledged(
|
|
&mut self,
|
|
_server: &mut Server,
|
|
login_acknowledged: SLoginAcknowledged,
|
|
) {
|
|
let _ = login_acknowledged;
|
|
self.connection_state = ConnectionState::Config;
|
|
dbg!("login achnowlaged");
|
|
}
|
|
fn handle_client_information(
|
|
&mut self,
|
|
_server: &mut Server,
|
|
client_information: SClientInformation,
|
|
) {
|
|
self.config = Some(PlayerConfig {
|
|
locale: client_information.locale,
|
|
view_distance: client_information.view_distance,
|
|
chat_mode: client_information.chat_mode,
|
|
chat_colors: client_information.chat_colors,
|
|
skin_parts: client_information.skin_parts,
|
|
main_hand: client_information.main_hand,
|
|
text_filtering: client_information.text_filtering,
|
|
server_listing: client_information.server_listing,
|
|
});
|
|
// We are done with configuring
|
|
self.send_packet(CFinishConfig::new());
|
|
}
|
|
|
|
fn handle_config_acknowledged(
|
|
&mut self,
|
|
server: &mut Server,
|
|
config_acknowledged: SAcknowledgeFinishConfig,
|
|
) {
|
|
dbg!("config acknowledged");
|
|
self.connection_state = ConnectionState::Play;
|
|
// generate a player
|
|
server.spawn_player(self);
|
|
}
|
|
}
|