Skip to content

Commit

Permalink
Added more doc comments
Browse files Browse the repository at this point in the history
  • Loading branch information
RadiatedMonkey committed Jan 29, 2023
1 parent 2b1a3c7 commit aa402fb
Show file tree
Hide file tree
Showing 11 changed files with 52 additions and 41 deletions.
18 changes: 12 additions & 6 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 7 additions & 5 deletions src/crypto/encrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,22 @@ use rand::rngs::OsRng;
use spki::{DecodePublicKey, EncodePublicKey};
use spki::der::SecretDocument;

const ENGINE: base64::engine::GeneralPurpose = base64::engine::general_purpose::STANDARD_NO_PAD;
/// Use the default Base64 format with no padding.
const BASE64_ENGINE: base64::engine::GeneralPurpose = base64::engine::general_purpose::STANDARD_NO_PAD;

/// Payload of the encryption handshake token
#[derive(serde::Serialize, Debug)]
struct EncryptionTokenClaims<'a> {
salt: &'a str,
}

/// Used to encrypt and decrypt packets with AES.
pub struct Encryptor {
secret: [u8; 16],
}

impl Debug for Encryptor {
/// Do not log secret key
/// Allow usage in debug derived structs, but prevent logging the secret.
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
fmt.write_str("Encryptor")
}
Expand Down Expand Up @@ -70,7 +72,7 @@ impl Encryptor {
Ok(d) => d,
Err(e) => bail!("Failed to convert public key to DER format: {e}")
};
ENGINE.encode(binary_der)
BASE64_ENGINE.encode(binary_der)
};

// The typ header is set to none to match the official server software.
Expand All @@ -81,12 +83,12 @@ impl Encryptor {
// Create a JWT encoding key using the session's private key.
let signing_key = jsonwebtoken::EncodingKey::from_ec_der(&private_key_der.to_bytes());
let claims = EncryptionTokenClaims {
salt: &ENGINE.encode(&salt)
salt: &BASE64_ENGINE.encode(&salt)
};

let jwt = jsonwebtoken::encode(&header, &claims, &signing_key)?;
let client_public_key = {
let bytes = ENGINE.decode(client_public_key_der)?;
let bytes = BASE64_ENGINE.decode(client_public_key_der)?;
match PublicKey::from_public_key_der(&bytes) {
Ok(k) => k,
Err(e) => bail!("Failed to read DER-encoded client public key: {e}")
Expand Down
3 changes: 2 additions & 1 deletion src/crypto/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::network::packets::DeviceOS;
/// Used to verify the second token in the identity chain.
pub const MOJANG_PUBLIC_KEY: &str = "MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V";

/// Use the default Base64 format with no padding.
const BASE64_ENGINE: base64::engine::GeneralPurpose =
base64::engine::general_purpose::STANDARD_NO_PAD;

Expand Down Expand Up @@ -209,7 +210,7 @@ pub fn parse_identity_data(buffer: &mut BytesMut) -> anyhow::Result<IdentityToke
}

/// Parses the user data token from the login packet.
/// This token contains the user's operating system, language, skin and more.
/// This token contains the user's operating system, language, skin, etc.
pub fn parse_user_data(buffer: &mut BytesMut, public_key: &str) -> anyhow::Result<UserTokenPayload> {
let token_length = buffer.get_u32_le();
let position = buffer.len() - buffer.remaining();
Expand Down
6 changes: 5 additions & 1 deletion src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ use crate::util::AsyncDeque;
pub const IPV4_LOCAL_ADDR: Ipv4Addr = Ipv4Addr::new(127, 0, 0, 1);
/// Local IPv6 address
pub const IPV6_LOCAL_ADDR: Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);

/// Size of the UDP receive buffer.
const RECV_BUF_SIZE: usize = 4096;
/// Refresh rate of the server's metadata.
/// This data is displayed in the server menu.
const METADATA_REFRESH_INTERVAL: Duration = Duration::from_secs(2);

/// Global instance that manages all data and services of the server.
Expand Down Expand Up @@ -278,6 +280,7 @@ impl ServerInstance {
}
}

/// Generates a new metadata string using the given description and new player count.
fn refresh_metadata(&self, description: &str) {
let new_id = format!(
"MCPE;{};{};{};{};{};{};{};Survival;1;{};{};",
Expand All @@ -296,6 +299,7 @@ impl ServerInstance {
*lock = new_id;
}

/// Returns the current metadata string.
#[inline]
fn metadata(&self) -> String {
(*self.metadata.read()).clone()
Expand Down
2 changes: 2 additions & 0 deletions src/network/packets/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ use crate::network::traits::Encodable;

/// Batch of game packets.
pub struct PacketBatch {
/// Whether packets in this batch should be compressed.
compression_enabled: bool,
/// Packets contained in the batch.
packets: Vec<BytesMut>,
}

Expand Down
11 changes: 8 additions & 3 deletions src/network/packets/login.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@ pub enum DeviceOS {
Ios,
Osx,
FireOS,
/// Samsung's GearVR
GearVR,
HoloLens,
/// Windows 10/11 UWP variant of the game
Win10,
Win32,
Dedicated,
TvOS,
/// Sometimes called Orbis.
PlayStation,
Nx,
Xbox,
Expand Down Expand Up @@ -58,10 +61,13 @@ impl TryFrom<u8> for DeviceOS {
}
}

/// Packet received by the client before initiating encryption.
/// A [`ServerToClientHandshake`](super::ServerToClientHandshake) should be sent in response.
#[derive(Debug)]
pub struct Login {
pub protocol_version: u32,
/// Identity data (Xbox account ID, username, etc.)
pub identity: IdentityData,
/// User data (device OS, skin, etc.)
pub user_data: UserData,
}

Expand All @@ -71,14 +77,13 @@ impl GamePacket for Login {

impl Decodable for Login {
fn decode(mut buffer: BytesMut) -> anyhow::Result<Self> {
let protocol_version = buffer.get_u32();
buffer.advance(4); // Skip protocol version, use the one in RequestNetworkSettings instead.
buffer.get_var_u32()?;

let identity_data = parse_identity_data(&mut buffer)?;
let user_data = parse_user_data(&mut buffer, &identity_data.public_key)?;

Ok(Self {
protocol_version,
identity: IdentityData {
identity: identity_data.client_data.uuid,
xuid: identity_data.client_data.xuid.parse()?,
Expand Down
3 changes: 3 additions & 0 deletions src/network/packets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ mod server_to_client_handshake;
mod start_game;
mod traits;

/// ID of Minecraft game packets.
pub const GAME_PACKET_ID: u8 = 0xfe;
/// Semver version that this server supports.
pub const CLIENT_VERSION_STRING: &str = "1.19";
/// Protocol version that this server supports.
pub const NETWORK_VERSION: u16 = 560;
1 change: 1 addition & 0 deletions src/network/packets/online_ping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::vex_assert;
/// An [`OnlinePong`](super::OnlinePong) packet should be sent in response.
#[derive(Debug)]
pub struct OnlinePing {
/// Timestamp of when the ping was sent.
pub time: i64,
}

Expand Down
2 changes: 2 additions & 0 deletions src/network/raknet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ mod frame;
mod raw;
mod reliability;

/// Version of Raknet that this server uses.
pub const RAKNET_VERSION: u8 = 11;
/// Special sequence of bytes that is contained in every unframed Raknet packet.
pub const OFFLINE_MESSAGE_DATA: &[u8] = &[
0x00, 0xff, 0xff, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0x12, 0x34, 0x56, 0x78,
];
22 changes: 3 additions & 19 deletions src/network/raknet/packets/new_incoming_connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@ use crate::vex_assert;

/// Confirms that the connection was successfully initiated.
#[derive(Debug)]
pub struct NewIncomingConnection {
/// IP address of the server.
pub server_address: SocketAddr,
pub client_timestamp: i64,
pub server_timestamp: i64,
}
pub struct NewIncomingConnection;

impl NewIncomingConnection {
/// Unique ID of this packet.
Expand All @@ -24,18 +19,7 @@ impl Decodable for NewIncomingConnection {
fn decode(mut buffer: BytesMut) -> anyhow::Result<Self> {
vex_assert!(buffer.get_u8() == Self::ID);

let server_address = buffer.get_addr()?;
for _ in 0..20 {
buffer.get_addr()?;
}

let client_timestamp = buffer.get_i64();
let server_timestamp = buffer.get_i64();

Ok(Self {
server_address,
client_timestamp,
server_timestamp,
})
// No data in this packet is used, there is no point in decoding it
Ok(Self)
}
}
13 changes: 7 additions & 6 deletions src/util/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,22 @@ use lazy_static::lazy_static;

use crate::{error, vex_assert};

/// Size of an IPv4 address in bytes.
pub const IPV4_MEM_SIZE: usize = 1 + 4 + 2;
/// Size of an IPv6 address in bytes.
pub const IPV6_MEM_SIZE: usize = 1 + 2 + 2 + 4 + 16 + 4;

lazy_static! {
/// Constant IP address, set to 255.255.255:19132
pub static ref EMPTY_IPV4_ADDRESS: SocketAddr =
SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(255, 255, 255, 255), 19132));
}

/// Determines the size of a varuint32.
pub const fn size_of_var_u32(mut value: u32) -> usize {
let mut v = 1;
while (value & !0x7f) != 0 {
value = value >> 7;
value >>= 7;
v += 1;
}
v
Expand All @@ -32,7 +36,7 @@ pub trait ReadExtensions: Buf {
///
/// * One byte for IP type (4 or 6),
/// * If IPv4, 4 bytes for the 4 octets,
/// * If IPv6, 16 bytes for the 4 octets,
/// * If IPv6, 16 bytes for the 16 octets, 4 bytes for flow information and 4 bytes for scope ID,
/// * Unsigned short for port.
///
/// This method fails if the IP type is a value other than 4 or 6.
Expand Down Expand Up @@ -126,10 +130,7 @@ pub trait WriteExtensions: BufMut + Sized {
/// Writes an IP address into a buffer.
///
/// IP format described in [`get_addr`](ReadExtensions::get_addr).
fn put_addr(&mut self, addr: SocketAddr)
where
Self: Sized,
{
fn put_addr(&mut self, addr: SocketAddr) {
match addr {
SocketAddr::V4(addr_v4) => {
self.put_u8(4);
Expand Down

0 comments on commit aa402fb

Please sign in to comment.