Login complete
This commit is contained in:
parent
144ebbba1d
commit
4d928973a6
@ -98,6 +98,7 @@ pub mod prelude {
|
|||||||
pub use log::*;
|
pub use log::*;
|
||||||
pub use serde::{Deserialize, Serialize};
|
pub use serde::{Deserialize, Serialize};
|
||||||
pub use serde_json::json;
|
pub use serde_json::json;
|
||||||
|
pub use uuid::Uuid;
|
||||||
pub type JSON = serde_json::Value;
|
pub type JSON = serde_json::Value;
|
||||||
pub type NBT = fastnbt::Value;
|
pub type NBT = fastnbt::Value;
|
||||||
pub use std::collections::VecDeque;
|
pub use std::collections::VecDeque;
|
||||||
|
@ -77,6 +77,8 @@ impl NetworkClient {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
pub async fn send_packet(&mut self, packet: Packet) -> Result<(), tokio::io::Error> {
|
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();
|
let bytes = packet.serialize();
|
||||||
self.stream.write(&bytes).await?;
|
self.stream.write(&bytes).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -90,7 +92,12 @@ impl NetworkClient {
|
|||||||
let _ = self.read_data().await;
|
let _ = self.read_data().await;
|
||||||
let _ = self.read_packet();
|
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;
|
self.state = NetworkClientState::Disconnected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,40 @@ pub enum Packet {
|
|||||||
SS01Ping {
|
SS01Ping {
|
||||||
payload: i64,
|
payload: i64,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Login
|
// 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
|
// Play
|
||||||
}
|
}
|
||||||
impl Packet {
|
impl Packet {
|
||||||
@ -90,7 +123,46 @@ impl Packet {
|
|||||||
}
|
}
|
||||||
_ => Err(ParseError::InvalidData),
|
_ => 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"),
|
Play => unimplemented!("Parse Play packet"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +177,7 @@ impl Packet {
|
|||||||
description,
|
description,
|
||||||
} => (
|
} => (
|
||||||
0x00,
|
0x00,
|
||||||
serialize_json(serde_json::json!({
|
serialize_json(json!({
|
||||||
"version": {
|
"version": {
|
||||||
"name": version_name,
|
"name": version_name,
|
||||||
"protocol": protocol_version,
|
"protocol": protocol_version,
|
||||||
@ -120,7 +192,17 @@ impl Packet {
|
|||||||
})),
|
})),
|
||||||
),
|
),
|
||||||
CS01Pong { payload } => (0x01, serialize_long(*payload).to_vec()),
|
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);
|
let mut id_and_body = serialize_varint(id as i32);
|
||||||
id_and_body.append(&mut body);
|
id_and_body.append(&mut body);
|
||||||
|
@ -93,7 +93,6 @@ impl Server {
|
|||||||
current_players += 1;
|
current_players += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: Make this count the number in the play state.
|
|
||||||
let client = &mut self.clients[client_index];
|
let client = &mut self.clients[client_index];
|
||||||
match packet {
|
match packet {
|
||||||
SH00Handshake {
|
SH00Handshake {
|
||||||
@ -107,7 +106,7 @@ impl Server {
|
|||||||
"Disconnecting client {} for mismatched protocols: {} (expected {})",
|
"Disconnecting client {} for mismatched protocols: {} (expected {})",
|
||||||
client.id, protocol_version, PROTOCOL_VERSION
|
client.id, protocol_version, PROTOCOL_VERSION
|
||||||
);
|
);
|
||||||
client.disconnect();
|
client.disconnect(None).await;
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
client.state = next_state;
|
client.state = next_state;
|
||||||
@ -128,7 +127,28 @@ impl Server {
|
|||||||
SS01Ping { payload } => {
|
SS01Ping { payload } => {
|
||||||
let _ = client.send_packet(CS01Pong { payload }).await;
|
let _ = client.send_packet(CS01Pong { payload }).await;
|
||||||
debug!("Disconnecting client {}, SLP completed", client.id);
|
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"),
|
_ => unimplemented!("Handling unknown packet"),
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user