mirror of
https://github.com/G2-Games/minecraft_alpha_server.git
synced 2025-04-18 23:03:00 -05:00
Client now gets to near the end of loading in
This commit is contained in:
parent
b43c372cc4
commit
ca67f15d46
6 changed files with 455 additions and 65 deletions
222
Cargo.lock
generated
222
Cargo.lock
generated
|
@ -66,6 +66,27 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "base16ct"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
|
@ -114,6 +135,26 @@ dependencies = [
|
|||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.2"
|
||||
|
@ -147,6 +188,27 @@ dependencies = [
|
|||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
|
@ -165,12 +227,33 @@ version = "1.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "md2"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f4f0f3ed25ff4f8d8d102288d92f900efc202661c884cf67dfe4f0d07c43d1f"
|
||||
dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "md5"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
|
@ -181,10 +264,16 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
|||
name = "minecraft_server_impl"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base16ct",
|
||||
"byteorder",
|
||||
"colog",
|
||||
"flate2",
|
||||
"log",
|
||||
"md2",
|
||||
"md5",
|
||||
"num-derive",
|
||||
"num-traits",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -196,6 +285,83 @@ dependencies = [
|
|||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-derive"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.0"
|
||||
|
@ -225,12 +391,47 @@ version = "0.8.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.79"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
|
@ -369,3 +570,24 @@ name = "windows_x86_64_msvc"
|
|||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
|
|
@ -4,7 +4,13 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
base16ct = { version = "0.2.0", features = ["std"] }
|
||||
byteorder = "1.5.0"
|
||||
colog = "1.3.0"
|
||||
flate2 = "1.0.34"
|
||||
log = "0.4.22"
|
||||
md2 = "0.10.2"
|
||||
md5 = "0.7.0"
|
||||
num-derive = "0.4.2"
|
||||
num-traits = "0.2.19"
|
||||
rand = "0.8.5"
|
||||
|
|
48
src/chunk.rs
48
src/chunk.rs
|
@ -3,10 +3,10 @@ use flate2::write::ZlibEncoder;
|
|||
use flate2::Compression;
|
||||
use std::io::prelude::*;
|
||||
|
||||
use crate::to_bytes::ToBytes;
|
||||
use crate::byte_ops::ToBytes;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct MapChunk {
|
||||
pub struct MapChunk {
|
||||
chunk_x: i32,
|
||||
chunk_y: i16,
|
||||
chunk_z: i32,
|
||||
|
@ -17,7 +17,7 @@ struct MapChunk {
|
|||
}
|
||||
|
||||
impl MapChunk {
|
||||
fn new(chunk_x: i32, chunk_z: i32, compressed_data: BlockArray) -> Self {
|
||||
pub fn new(chunk_x: i32, chunk_z: i32, compressed_data: BlockArray) -> Self {
|
||||
Self {
|
||||
chunk_x,
|
||||
chunk_y: 0,
|
||||
|
@ -31,34 +31,35 @@ impl MapChunk {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct BlockArray {
|
||||
pub struct BlockArray {
|
||||
compressed_size: i32,
|
||||
compressed_data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl BlockArray {
|
||||
fn new_air() -> Self {
|
||||
let mut output_vec = Vec::new();
|
||||
pub fn new_air() -> Self {
|
||||
let mut block_vec = Vec::new();
|
||||
|
||||
for _ in 0..(16 * 127 * 15) {
|
||||
output_vec.push(0);
|
||||
block_vec.push(0);
|
||||
}
|
||||
for _ in 0..(16 * 127 * 15) / 2 {
|
||||
output_vec.push(0);
|
||||
block_vec.push(0);
|
||||
}
|
||||
for _ in 0..(16 * 127 * 15) / 2 {
|
||||
output_vec.push(0);
|
||||
block_vec.push(0);
|
||||
}
|
||||
for _ in 0..(16 * 127 * 15) / 2 {
|
||||
output_vec.push(0);
|
||||
block_vec.push(0);
|
||||
}
|
||||
|
||||
let mut encoder = ZlibEncoder::new(Vec::new(), Compression::default());
|
||||
encoder.write(&output_vec).unwrap();
|
||||
encoder.write(&block_vec).unwrap();
|
||||
let output_buf = encoder.finish().unwrap();
|
||||
|
||||
Self {
|
||||
compressed_size: 1,
|
||||
compressed_data: encoder.finish().unwrap(),
|
||||
compressed_size: output_buf.len() as i32,
|
||||
compressed_data: output_buf,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -87,6 +88,9 @@ impl ToBytes for MapChunk {
|
|||
buffer.write_u8(self.size_y).unwrap();
|
||||
buffer.write_u8(self.size_z).unwrap();
|
||||
|
||||
buffer.write_i32::<BE>(self.compressed_data.compressed_size).unwrap();
|
||||
buffer.write_all(&self.compressed_data.compressed_data).unwrap();
|
||||
|
||||
buffer
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +102,24 @@ pub struct PreChunk {
|
|||
pub mode: bool, // True to load, False to unload
|
||||
}
|
||||
|
||||
impl PreChunk {
|
||||
pub fn new_load(x_coord: i32, z_coord: i32) -> Self {
|
||||
Self {
|
||||
x_coord,
|
||||
z_coord,
|
||||
mode: true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_unload(x_coord: i32, z_coord: i32) -> Self {
|
||||
Self {
|
||||
x_coord,
|
||||
z_coord,
|
||||
mode: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToBytes for PreChunk {
|
||||
type Bytes = [u8; 9];
|
||||
|
||||
|
|
229
src/main.rs
229
src/main.rs
|
@ -1,14 +1,18 @@
|
|||
mod utils;
|
||||
mod to_bytes;
|
||||
mod byte_ops;
|
||||
mod chunk;
|
||||
|
||||
use std::{io::{self, Write}, net::{TcpListener, TcpStream}};
|
||||
use std::{io::{self, Read, Write}, net::{TcpListener, TcpStream}};
|
||||
|
||||
use chunk::PreChunk;
|
||||
use base16ct::lower::encode_string;
|
||||
use chunk::{BlockArray, MapChunk, PreChunk};
|
||||
use log::{info, warn};
|
||||
use byteorder::{ReadBytesExt, WriteBytesExt, BE};
|
||||
use to_bytes::ToBytes;
|
||||
use num_derive::FromPrimitive;
|
||||
use num_traits::FromPrimitive;
|
||||
use byte_ops::ToBytes;
|
||||
use utils::{MCString, ReadMCString, WriteMCString};
|
||||
use rand::random;
|
||||
|
||||
|
||||
fn main() {
|
||||
|
@ -21,71 +25,113 @@ fn main() {
|
|||
for mut connection in listener.incoming().filter_map(|c| c.ok()) {
|
||||
info!("Connected to client @ {}", connection.peer_addr().unwrap());
|
||||
while let Some(cmd) = connection.read_u8().ok() {
|
||||
let command = Command::try_from(cmd);
|
||||
info!("COMMAND: {command:?}");
|
||||
let command = Command::from_u8(cmd);
|
||||
info!("COMMAND: {command:?} (0x{cmd:02X?})");
|
||||
handle_command(&mut connection, command.unwrap()).unwrap();
|
||||
|
||||
}
|
||||
warn!("Lost connection to client");
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_command(connection: &mut TcpStream, command: Command) -> Result<(), io::Error> {
|
||||
fn handle_command(mut connection: &mut TcpStream, command: Command) -> Result<(), io::Error> {
|
||||
match command {
|
||||
Command::KeepAlive => todo!(),
|
||||
Command::Handshake => {
|
||||
let username = connection.read_mcstring()?;
|
||||
info!("Handshake: {username}");
|
||||
let random_number = random::<u128>();
|
||||
let random_hash = encode_string(md5::compute(random_number.to_le_bytes()).as_slice());
|
||||
|
||||
info!("Handshake with {username} successful. Providing hash: {random_hash:?}");
|
||||
|
||||
connection.write_u8(0x02)?;
|
||||
connection.write_mcstring(&MCString::try_from("-").unwrap())?;
|
||||
connection.write_mcstring(&MCString::try_from(random_hash).unwrap())?;
|
||||
},
|
||||
Command::Login => {
|
||||
info!("---");
|
||||
info!("Initiating login");
|
||||
let protocol_version = connection.read_u32::<BE>()?;
|
||||
let username = connection.read_mcstring()?;
|
||||
let _password = connection.read_mcstring()?;
|
||||
let _map_seed = connection.read_i64::<BE>()?;
|
||||
let _dimension = connection.read_i8()?;
|
||||
let password = connection.read_mcstring()?;
|
||||
let map_seed = connection.read_i64::<BE>()?;
|
||||
let dimension = connection.read_i8()?;
|
||||
|
||||
info!("Protocol Version: {protocol_version}");
|
||||
info!("Username: {username}");
|
||||
info!("Password: {password}");
|
||||
info!("Map Seed: {map_seed}");
|
||||
info!("Dimension: {dimension}");
|
||||
|
||||
let login_packet = ServerLoginPacket {
|
||||
entity_id: 1,
|
||||
entity_id: 1200,
|
||||
unknown1: MCString::default(),
|
||||
unknown2: MCString::default(),
|
||||
map_seed: 1715505462032542147,
|
||||
dimension: 0,
|
||||
};
|
||||
login_packet.write_into(connection)?;
|
||||
connection.write_u8(Command::Login as u8).unwrap();
|
||||
connection.write(&login_packet.to_bytes())?;
|
||||
|
||||
info!("Responded to auth request");
|
||||
|
||||
let prechunk = PreChunk {
|
||||
x_coord: 0,
|
||||
z_coord: 0,
|
||||
mode: true,
|
||||
};
|
||||
for i in 0..7 {
|
||||
for o in 0..7 {
|
||||
let x = (-4 + i) * 16;
|
||||
let z = (-5 + o) * 16;
|
||||
|
||||
connection.write_u8(Command::PreChunk as u8)?;
|
||||
connection.write_all(&prechunk.to_bytes())?;
|
||||
connection.write_u8(Command::PreChunk as u8).unwrap();
|
||||
connection.write_all(&PreChunk::new_load(x, z).to_bytes()).unwrap();
|
||||
|
||||
connection.write_u8(Command::MapChunk as u8)?;
|
||||
connection.write_all(&MapChunk::new(x, z, BlockArray::new_air()).to_bytes())?;
|
||||
}
|
||||
}
|
||||
|
||||
connection.write_u8(Command::SpawnPosition as u8)?;
|
||||
connection.write_u32::<BE>(0)?;
|
||||
connection.write_u32::<BE>(70)?;
|
||||
connection.write_u32::<BE>(0)?;
|
||||
|
||||
let playerpos = PlayerPositionAndLook {
|
||||
position_x: 0.0,
|
||||
stance: 0.0,
|
||||
position_y: 70.0,
|
||||
position_z: 0.0,
|
||||
yaw: 0.0,
|
||||
pitch: 0.0,
|
||||
on_ground: true,
|
||||
};
|
||||
connection.write_u8(Command::PlayerPositionAndLook as u8)?;
|
||||
connection.write_all(&playerpos.to_bytes())?;
|
||||
},
|
||||
_ => unimplemented!("This command is probably `Server -> Client` only")
|
||||
Command::PlayerPositionAndLook => {
|
||||
let _poslook = PlayerPositionAndLook::from_bytes(&mut connection);
|
||||
}
|
||||
Command::PlayerPosition => {
|
||||
let _pos = PlayerPosition::from_bytes(&mut connection);
|
||||
}
|
||||
c => unimplemented!("This command ({c:?}) is probably `Server -> Client` only")
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(FromPrimitive)]
|
||||
enum Command {
|
||||
KeepAlive = 0x00,
|
||||
Login = 0x01,
|
||||
Handshake = 0x02,
|
||||
ChatMessage = 0x03,
|
||||
TimeUpdate = 0x04,
|
||||
PlayerInventory = 0x05,
|
||||
SpawnPosition = 0x06,
|
||||
UpdateHealth = 0x08,
|
||||
Respawn = 0x09,
|
||||
PlayerPositionAndLook = 0x0D,
|
||||
PlayerPosition = 0x0B,
|
||||
PreChunk = 0x32,
|
||||
ChunkData = 0x33,
|
||||
Kick = 0xFF,
|
||||
MapChunk = 0x33,
|
||||
Disconnect = 0xFF,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
|
@ -93,24 +139,6 @@ struct CommandError {
|
|||
_id: u8,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for Command {
|
||||
type Error = CommandError;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
Ok(match value {
|
||||
0x00 => Self::KeepAlive,
|
||||
0x01 => Self::Login,
|
||||
0x02 => Self::Handshake,
|
||||
0x32 => Self::PreChunk,
|
||||
0x33 => Self::ChunkData,
|
||||
0xFF => Self::Kick,
|
||||
v => return Err(CommandError{
|
||||
_id: v,
|
||||
}),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct ServerLoginPacket {
|
||||
entity_id: i32,
|
||||
unknown1: MCString,
|
||||
|
@ -119,14 +147,111 @@ struct ServerLoginPacket {
|
|||
dimension: i8,
|
||||
}
|
||||
|
||||
impl ServerLoginPacket {
|
||||
fn write_into<W: Write>(&self, stream: &mut W) -> Result<(), io::Error> {
|
||||
stream.write_i32::<BE>(self.entity_id)?;
|
||||
stream.write_mcstring(&self.unknown1)?;
|
||||
stream.write_mcstring(&self.unknown2)?;
|
||||
stream.write_i64::<BE>(self.map_seed)?;
|
||||
stream.write_i8(self.dimension)?;
|
||||
impl ToBytes for ServerLoginPacket {
|
||||
type Bytes = Vec<u8>;
|
||||
|
||||
Ok(())
|
||||
fn to_bytes(self) -> Self::Bytes {
|
||||
let mut out_buf = Vec::new();
|
||||
out_buf.write_i32::<BE>(self.entity_id).unwrap();
|
||||
out_buf.write_mcstring(&self.unknown1).unwrap();
|
||||
out_buf.write_mcstring(&self.unknown2).unwrap();
|
||||
out_buf.write_i64::<BE>(self.map_seed).unwrap();
|
||||
out_buf.write_i8(self.dimension).unwrap();
|
||||
|
||||
out_buf
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct PlayerPositionAndLook {
|
||||
position_x: f64,
|
||||
stance: f64,
|
||||
position_y: f64,
|
||||
position_z: f64,
|
||||
yaw: f32,
|
||||
pitch: f32,
|
||||
on_ground: bool,
|
||||
}
|
||||
|
||||
impl ToBytes for PlayerPositionAndLook {
|
||||
type Bytes = Vec<u8>;
|
||||
|
||||
fn to_bytes(self) -> Self::Bytes {
|
||||
let mut out_buf = Vec::new();
|
||||
out_buf.write_f64::<BE>(self.position_x).unwrap();
|
||||
out_buf.write_f64::<BE>(self.stance).unwrap();
|
||||
out_buf.write_f64::<BE>(self.position_y).unwrap();
|
||||
out_buf.write_f64::<BE>(self.position_z).unwrap();
|
||||
out_buf.write_f32::<BE>(self.yaw).unwrap();
|
||||
out_buf.write_f32::<BE>(self.pitch).unwrap();
|
||||
out_buf.write_u8(self.on_ground as u8).unwrap();
|
||||
|
||||
out_buf
|
||||
}
|
||||
}
|
||||
|
||||
impl PlayerPositionAndLook {
|
||||
fn from_bytes<R: Read>(stream: &mut R) -> Self {
|
||||
let position_x = stream.read_f64::<BE>().unwrap();
|
||||
let position_y = stream.read_f64::<BE>().unwrap();
|
||||
let stance = stream.read_f64::<BE>().unwrap();
|
||||
let position_z = stream.read_f64::<BE>().unwrap();
|
||||
|
||||
let yaw = stream.read_f32::<BE>().unwrap();
|
||||
let pitch = stream.read_f32::<BE>().unwrap();
|
||||
let on_ground = stream.read_u8().unwrap() != 0;
|
||||
|
||||
Self {
|
||||
position_x,
|
||||
stance,
|
||||
position_y,
|
||||
position_z,
|
||||
yaw,
|
||||
pitch,
|
||||
on_ground
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct PlayerPosition {
|
||||
position_x: f64,
|
||||
position_y: f64,
|
||||
stance: f64,
|
||||
position_z: f64,
|
||||
on_ground: bool,
|
||||
}
|
||||
|
||||
impl ToBytes for PlayerPosition {
|
||||
type Bytes = Vec<u8>;
|
||||
|
||||
fn to_bytes(self) -> Self::Bytes {
|
||||
let mut out_buf = Vec::new();
|
||||
out_buf.write_f64::<BE>(self.position_x).unwrap();
|
||||
out_buf.write_f64::<BE>(self.position_y).unwrap();
|
||||
out_buf.write_f64::<BE>(self.stance).unwrap();
|
||||
out_buf.write_f64::<BE>(self.position_z).unwrap();
|
||||
out_buf.write_u8(self.on_ground as u8).unwrap();
|
||||
|
||||
out_buf
|
||||
}
|
||||
}
|
||||
|
||||
impl PlayerPosition {
|
||||
fn from_bytes<R: Read>(stream: &mut R) -> Self {
|
||||
let position_x = stream.read_f64::<BE>().unwrap();
|
||||
let position_y = stream.read_f64::<BE>().unwrap();
|
||||
let stance = stream.read_f64::<BE>().unwrap();
|
||||
let position_z = stream.read_f64::<BE>().unwrap();
|
||||
|
||||
let on_ground = stream.read_u8().unwrap() != 0;
|
||||
|
||||
Self {
|
||||
position_x,
|
||||
stance,
|
||||
position_y,
|
||||
position_z,
|
||||
on_ground
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
15
src/utils.rs
15
src/utils.rs
|
@ -23,6 +23,21 @@ impl TryFrom<&str> for MCString {
|
|||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for MCString {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
if value.len() > u16::MAX as usize {
|
||||
return Err(())
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
len: value.len() as u16,
|
||||
chars: value.as_bytes().to_vec(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for MCString {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", String::from_utf8(self.chars.clone()).unwrap())
|
||||
|
|
Loading…
Reference in a new issue