Add documentation

This commit is contained in:
Garen Tyler 2021-03-01 20:21:32 -07:00
parent 253ab0802a
commit a94491205d
6 changed files with 61 additions and 15 deletions

View File

@ -1,10 +1,15 @@
/// Data types for every entity in the game.
pub mod entity;
/// Implementations of the data types needed for the Minecraft protocol.
pub mod mctypes;
/// The logic for the server.
pub mod server;
/// The data types for blocks, chunks, dimensions, and world files.
pub mod world;
pub use mctypes::*;
/// Set up logging, read the config file, etc.
pub fn init() {
// Set up fern logging.
fern::Dispatch::new()
@ -24,6 +29,7 @@ pub fn init() {
.unwrap();
}
/// Start the server.
pub fn start_server() -> server::GameServer {
// Start the network.
let network = server::net::NetworkServer::new("0.0.0.0:25565");

View File

@ -8,23 +8,27 @@ use std::fmt::Display;
use std::io::prelude::*;
use std::net::TcpStream;
/// Make sure all types can serialize and deserialize to/from `Vec<u8>`.
pub trait MCType: Into<Vec<u8>> + TryFrom<Vec<u8>> + Display {
fn read(_stream: &mut TcpStream) -> std::io::Result<Self>;
}
// Helper functions.
/// Helper functions.
pub mod functions {
use super::*;
/// Read a single byte from the given `TcpStream`.
pub fn read_byte(t: &mut TcpStream) -> std::io::Result<u8> {
let mut buffer = [0u8; 1];
t.read_exact(&mut buffer)?;
Ok(buffer[0])
}
/// Write a single byte to the given `TcpStream`.
pub fn write_byte(t: &mut TcpStream, value: u8) -> std::io::Result<u8> {
t.write(&[value])?;
Ok(value)
}
/// Take `l` bytes from the given `Vec<u8>`.
pub fn get_bytes(v: Vec<u8>, l: usize) -> Box<[u8]> {
use std::collections::VecDeque;
let mut v = VecDeque::from(v);
@ -40,19 +44,20 @@ pub mod functions {
}
a.into_boxed_slice()
}
// Makes returning errors shorter.
/// Makes returning errors shorter.
pub fn io_error(s: &str) -> std::io::Error {
use std::io::{Error, ErrorKind};
Error::new(ErrorKind::Other, s)
}
}
// The other types, (booleans and strings).
/// The other types, (booleans and strings).
pub mod other {
use super::*;
use std::convert::{From, Into, TryFrom};
use std::fmt::Display;
/// The equivalent of a `bool`.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum MCBoolean {
True,
@ -116,6 +121,7 @@ pub mod other {
}
}
/// The equivalent of a `String`.
#[derive(Debug, PartialEq)]
pub struct MCString {
pub value: String,
@ -196,6 +202,7 @@ pub mod other {
}
}
/// A normal `MCString`, but with extra embedded formatting data.
#[derive(Debug, PartialEq)]
pub struct MCChat {
pub text: MCString,
@ -244,13 +251,13 @@ pub mod other {
}
}
// All the numbers, from i8 and u8 to i64 and u64, plus VarInts.
/// All the numbers, from `i8` and `u8` to `i64` and `u64`, plus `VarInt`s.
pub mod numbers {
use super::*;
use std::convert::{From, Into, TryFrom};
use std::fmt::Display;
// Byte: i8
/// The equivalent of an `i8`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCByte {
pub value: i8, // -128 to 127
@ -317,7 +324,7 @@ pub mod numbers {
}
}
// Unsigned Byte: u8
/// The equivalent of a `u8`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCUnsignedByte {
pub value: u8, // 0 to 255
@ -384,7 +391,7 @@ pub mod numbers {
}
}
// Short: i16
/// The equivalent of an `i16`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCShort {
pub value: i16, // -32768 to 32767
@ -456,7 +463,7 @@ pub mod numbers {
}
}
// Unsigned Short: u16
/// The equivalent of a `u16`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCUnsignedShort {
pub value: u16, // 0 to 65535
@ -528,7 +535,7 @@ pub mod numbers {
}
}
// Int: i32
/// The equivalent of an `i32`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCInt {
pub value: i32, // -2147483648 to 2147483647
@ -601,7 +608,7 @@ pub mod numbers {
}
}
// Unsigned Int: u32
/// The equivalent of a `u32`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCUnsignedInt {
pub value: u32, // 0 to 4294967295
@ -674,7 +681,7 @@ pub mod numbers {
}
}
// Long: i64
/// The equivalent of an `864`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCLong {
pub value: i64, // -9223372036854775808 to 9223372036854775807
@ -747,7 +754,7 @@ pub mod numbers {
}
}
// Unsigned Long: u64
/// The equivalent of a `u64`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCUnsignedLong {
pub value: u64, // 0 to 18446744073709551615
@ -820,7 +827,7 @@ pub mod numbers {
}
}
// Float: f32
/// The equivalent of a `f32`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCFloat {
pub value: f32, // 32-bit floating point number
@ -893,7 +900,7 @@ pub mod numbers {
}
}
// Double: f64
/// The equivalent of a `f64`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCDouble {
pub value: f64, // 64-bit floating point number
@ -947,6 +954,7 @@ pub mod numbers {
}
}
/// A variable-length integer.
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCVarInt {
pub value: i32, // Variable length 32-bit integer

View File

@ -1,9 +1,14 @@
/// Deals with all the network stuff.
pub mod net;
/// The struct containing all the data and running all the updates.
pub struct GameServer {
pub network: net::NetworkServer,
}
impl GameServer {
/// Update the game server.
///
/// Start by updating the network.
pub fn update(&mut self) {
self.network.update();
}

View File

@ -1,3 +1,4 @@
/// Definitions for all the packets in the Minecraft protocol.
pub mod packets;
use crate::mctypes::*;
@ -7,11 +8,16 @@ use serde_json::json;
use std::net::{TcpListener, TcpStream, ToSocketAddrs};
use std::sync::mpsc::{self, Receiver, TryRecvError};
/// The part of the server that handles
/// connecting clients and receiving/sending packets.
pub struct NetworkServer {
pub clients: Vec<NetworkClient>,
receiver: Receiver<NetworkClient>,
}
impl NetworkServer {
/// Create a thread for listening to new clients.
/// Use `std::sync::mpsc::channel()` to send the new clients across threads,
/// then hold that in a queue for processing on an update.
pub fn new<A: 'static + ToSocketAddrs + Send>(addr: A) -> NetworkServer {
let (tx, rx) = mpsc::channel();
std::thread::spawn(move || {
@ -34,6 +40,7 @@ impl NetworkServer {
receiver: rx,
}
}
/// Update each client in `self.clients`.
pub fn update(&mut self) {
loop {
match self.receiver.try_recv() {
@ -53,6 +60,9 @@ impl NetworkServer {
}
}
}
/// The network client can only be in a few states,
/// this enum keeps track of that.
pub enum NetworkClientState {
Handshake,
Status,
@ -60,6 +70,9 @@ pub enum NetworkClientState {
Play,
Disconnected,
}
/// A wrapper to contain everything related
/// to networking for the client.
pub struct NetworkClient {
pub id: u128,
pub connected: bool,
@ -67,6 +80,10 @@ pub struct NetworkClient {
pub state: NetworkClientState,
}
impl NetworkClient {
/// Update the client.
///
/// Updating could mean connecting new clients, reading packets,
/// writing packets, or disconnecting clients.
pub fn update(&mut self) {
match self.state {
NetworkClientState::Handshake => {
@ -114,8 +131,11 @@ impl NetworkClient {
"description": {
"text": "Hello world!"
},
// TODO: Dynamically send the icon instead of linking statically.
"favicon": format!("data:image/png;base64,{}", radix64::STD.encode(include_bytes!("../../server-icon.png")))
}).to_string().into();
})
.to_string()
.into();
statusresponse.write(&mut self.stream).unwrap();
debug!("Sending status response: StatusResponse");
let (_packet_length, _packet_id) = read_packet_header(&mut self.stream).unwrap();

View File

@ -1,4 +1,6 @@
/// The packets that get sent to the client by the server.
pub mod clientbound;
/// The packets that get sent to the server by the client.
pub mod serverbound;
use crate::mctypes::{MCType, MCVarInt};
@ -7,12 +9,16 @@ pub use serverbound::*;
use std::convert::{Into, TryFrom};
use std::net::TcpStream;
/// All packets need to serialize/deserialize to/from `Vec<u8>`.
pub trait Packet: Into<Vec<u8>> + TryFrom<Vec<u8>> {
fn new() -> Self;
/// Read the packet body from the given `TcpStream`.
fn read(_stream: &mut TcpStream) -> std::io::Result<Self>;
/// Write the packet (body and header) to the given `TcpStream`.
fn write(&self, _stream: &mut TcpStream) -> std::io::Result<()>;
}
/// A helper function to read the packet header.
pub fn read_packet_header(t: &mut TcpStream) -> std::io::Result<(MCVarInt, MCVarInt)> {
let length = MCVarInt::read(t)?;
let id = MCVarInt::read(t)?;

View File

@ -3,6 +3,7 @@ use crate::mctypes::*;
use std::convert::{Into, TryFrom};
use std::net::TcpStream;
/// Needed for every interaction with the server.
#[derive(Debug, Clone)]
pub struct Handshake {
pub protocol_version: MCVarInt,