Login complete
This commit is contained in:
parent
144ebbba1d
commit
4d928973a6
@ -98,6 +98,7 @@ pub mod prelude {
|
||||
pub use log::*;
|
||||
pub use serde::{Deserialize, Serialize};
|
||||
pub use serde_json::json;
|
||||
pub use uuid::Uuid;
|
||||
pub type JSON = serde_json::Value;
|
||||
pub type NBT = fastnbt::Value;
|
||||
pub use std::collections::VecDeque;
|
||||
|
@ -77,6 +77,8 @@ impl NetworkClient {
|
||||
Ok(())
|
||||
}
|
||||
pub async fn send_packet(&mut self, packet: Packet) -> Result<(), tokio::io::Error> {
|
||||
trace!("NetworkClient.send_packet()");
|
||||
debug!("Sending packet {:?} to client {}", packet, self.id);
|
||||
let bytes = packet.serialize();
|
||||
self.stream.write(&bytes).await?;
|
||||
Ok(())
|
||||
@ -90,7 +92,12 @@ impl NetworkClient {
|
||||
let _ = self.read_data().await;
|
||||
let _ = self.read_packet();
|
||||
}
|
||||
pub fn disconnect(&mut self) {
|
||||
pub async fn disconnect(&mut self, reason: Option<JSON>) {
|
||||
if let Some(reason) = reason {
|
||||
if self.state == NetworkClientState::Login {
|
||||
let _ = self.send_packet(Packet::CL00Disconnect { reason }).await;
|
||||
}
|
||||
}
|
||||
self.state = NetworkClientState::Disconnected;
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,40 @@ pub enum Packet {
|
||||
SS01Ping {
|
||||
payload: i64,
|
||||
},
|
||||
|
||||
// Login
|
||||
CL00Disconnect {
|
||||
reason: JSON,
|
||||
},
|
||||
CL01EncryptionRequest {
|
||||
server_id: String,
|
||||
public_key: Vec<u8>,
|
||||
verify_token: Vec<u8>,
|
||||
},
|
||||
CL02LoginSuccess {
|
||||
uuid: u128,
|
||||
username: String,
|
||||
},
|
||||
CL03SetCompression {
|
||||
threshold: usize,
|
||||
},
|
||||
CL04LoginPluginRequest {
|
||||
message_id: i32,
|
||||
channel: String,
|
||||
data: Vec<u8>,
|
||||
},
|
||||
SL00LoginStart {
|
||||
username: String,
|
||||
},
|
||||
SL01EncryptionResponse {
|
||||
shared_secret: Vec<u8>,
|
||||
verify_token: Vec<u8>,
|
||||
},
|
||||
SL02LoginPluginResponse {
|
||||
message_id: i32,
|
||||
successful: bool,
|
||||
data: Option<Vec<u8>>,
|
||||
},
|
||||
// Play
|
||||
}
|
||||
impl Packet {
|
||||
@ -90,7 +123,46 @@ impl Packet {
|
||||
}
|
||||
_ => Err(ParseError::InvalidData),
|
||||
},
|
||||
Login => unimplemented!("Parse Login packet"),
|
||||
Login => match id {
|
||||
0x00 => {
|
||||
if serverbound {
|
||||
let (username, offset_delta) = parse_string(&data[offset..])?;
|
||||
offset += offset_delta;
|
||||
Ok((SL00LoginStart { username }, offset))
|
||||
} else {
|
||||
unimplemented!("Parse CL00Disconnect")
|
||||
}
|
||||
}
|
||||
0x01 => {
|
||||
if serverbound {
|
||||
unimplemented!("Parse SL01EncryptionResponse")
|
||||
} else {
|
||||
unimplemented!("Parse CL01EncryptionRequest")
|
||||
}
|
||||
}
|
||||
0x02 => {
|
||||
if serverbound {
|
||||
unimplemented!("Parse SL02LoginPluginResponse")
|
||||
} else {
|
||||
unimplemented!("Parse CL02LoginSuccess")
|
||||
}
|
||||
}
|
||||
0x03 => {
|
||||
if serverbound {
|
||||
Err(ParseError::InvalidData)
|
||||
} else {
|
||||
unimplemented!("Parse CL03SetCompression")
|
||||
}
|
||||
}
|
||||
0x04 => {
|
||||
if serverbound {
|
||||
Err(ParseError::InvalidData)
|
||||
} else {
|
||||
unimplemented!("Parse CL04LoginPluginRequest")
|
||||
}
|
||||
}
|
||||
_ => Err(ParseError::InvalidData),
|
||||
},
|
||||
Play => unimplemented!("Parse Play packet"),
|
||||
}
|
||||
}
|
||||
@ -105,7 +177,7 @@ impl Packet {
|
||||
description,
|
||||
} => (
|
||||
0x00,
|
||||
serialize_json(serde_json::json!({
|
||||
serialize_json(json!({
|
||||
"version": {
|
||||
"name": version_name,
|
||||
"protocol": protocol_version,
|
||||
@ -120,7 +192,17 @@ impl Packet {
|
||||
})),
|
||||
),
|
||||
CS01Pong { payload } => (0x01, serialize_long(*payload).to_vec()),
|
||||
_ => unimplemented!(),
|
||||
CL00Disconnect { reason } => (0x00, serialize_json(reason.clone())),
|
||||
// CL01EncryptionRequest
|
||||
CL02LoginSuccess { uuid, username } => (0x02, {
|
||||
let mut out = vec![];
|
||||
out.extend(uuid.to_be_bytes());
|
||||
out.extend(serialize_string(username));
|
||||
out
|
||||
}),
|
||||
// CL03SetCompression
|
||||
// CL04LoginPluginRequest
|
||||
_ => unimplemented!("Serializing unknown packet"),
|
||||
};
|
||||
let mut id_and_body = serialize_varint(id as i32);
|
||||
id_and_body.append(&mut body);
|
||||
|
@ -93,7 +93,6 @@ impl Server {
|
||||
current_players += 1;
|
||||
}
|
||||
}
|
||||
// TODO: Make this count the number in the play state.
|
||||
let client = &mut self.clients[client_index];
|
||||
match packet {
|
||||
SH00Handshake {
|
||||
@ -107,7 +106,7 @@ impl Server {
|
||||
"Disconnecting client {} for mismatched protocols: {} (expected {})",
|
||||
client.id, protocol_version, PROTOCOL_VERSION
|
||||
);
|
||||
client.disconnect();
|
||||
client.disconnect(None).await;
|
||||
return Err(());
|
||||
}
|
||||
client.state = next_state;
|
||||
@ -128,7 +127,28 @@ impl Server {
|
||||
SS01Ping { payload } => {
|
||||
let _ = client.send_packet(CS01Pong { payload }).await;
|
||||
debug!("Disconnecting client {}, SLP completed", client.id);
|
||||
client.disconnect();
|
||||
client.disconnect(None).await;
|
||||
}
|
||||
SL00LoginStart { username } => {
|
||||
debug!(
|
||||
"Client {} is connecting with username {}",
|
||||
client.id, username
|
||||
);
|
||||
if current_players >= CONFIG.max_players {
|
||||
client
|
||||
.disconnect(Some(json!({ "text": "Server full!" })))
|
||||
.await;
|
||||
}
|
||||
// TODO: Authentication
|
||||
// TODO: Encryption
|
||||
// TODO: Compression
|
||||
let _ = client
|
||||
.send_packet(CL02LoginSuccess {
|
||||
uuid: client.id,
|
||||
username,
|
||||
})
|
||||
.await;
|
||||
client.state = NetworkClientState::Play;
|
||||
}
|
||||
_ => unimplemented!("Handling unknown packet"),
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user