Split MCTypes into separate files

This commit is contained in:
Garen Tyler 2021-04-26 14:21:10 -06:00
parent e3541ea38f
commit 811985ad67
6 changed files with 1119 additions and 1109 deletions

View File

@ -3,15 +3,14 @@ extern crate lazy_static;
/// Data types for every entity in the game.
pub mod entity;
/// Implementations of the data types needed for the Minecraft protocol.
/// 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.
/// Data types for blocks, chunks, dimensions, and world files.
pub mod world;
use log::*;
pub use mctypes::*;
use serde::{Deserialize, Serialize};
use std::sync::mpsc::{self, Receiver};

File diff suppressed because it is too large Load Diff

49
src/mctypes/functions.rs Normal file
View File

@ -0,0 +1,49 @@
use super::*;
/// Read a single byte from the given `TcpStream`.
pub async fn read_byte(t: &mut TcpStream) -> tokio::io::Result<u8> {
let mut buffer = [0u8; 1];
t.read_exact(&mut buffer).await?;
Ok(buffer[0])
}
/// Read `l` bytes from the given `TcpStream`.
pub async fn read_bytes(t: &mut TcpStream, l: usize) -> tokio::io::Result<Vec<u8>> {
let mut buffer = vec![];
for _ in 0..l {
buffer.push(read_byte(t).await?);
}
Ok(buffer)
}
/// Write a single byte to the given `TcpStream`.
pub async fn write_byte(t: &mut TcpStream, value: u8) -> tokio::io::Result<()> {
t.write(&[value]).await?;
Ok(())
}
/// Write multiple bytes to the given `TcpStream`.
pub async fn write_bytes(t: &mut TcpStream, bytes: &[u8]) -> tokio::io::Result<()> {
for b in bytes {
write_byte(t, *b).await?;
}
Ok(())
}
/// 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);
while v.len() > l {
v.pop_front();
}
while v.len() < l {
v.push_front(0u8);
}
let mut a = Vec::new();
for b in v {
a.push(b);
}
a.into_boxed_slice()
}
/// Makes returning errors shorter.
pub fn io_error(s: &str) -> tokio::io::Error {
use tokio::io::{Error, ErrorKind};
Error::new(ErrorKind::Other, s)
}

41
src/mctypes/mod.rs Normal file
View File

@ -0,0 +1,41 @@
#![allow(dead_code)]
/// Helper functions.
pub mod functions;
/// All the numbers, from `i8` and `u8` to `i64` and `u64`, plus `VarInt`s.
pub mod numbers;
/// The other types, (booleans and strings).
pub mod other;
pub use functions::*;
pub use numbers::*;
pub use other::*;
use serde_json::json;
use std::{
clone::Clone,
convert::{Into, TryFrom},
fmt::{Debug, Display},
};
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::TcpStream,
};
// /// Make sure all types can serialize and deserialize to/from `Vec<u8>`.
// pub trait MCType: Into<Vec<u8>> + TryFrom<Vec<u8>> + Display {
// pub async fn read(_stream: &mut TcpStream) -> tokio::io::Result<Self>;
// }
pub enum MCTypeError {
NetworkError(tokio::io::Error),
NotEnoughData,
ParseError,
}
#[async_trait::async_trait]
pub trait MCType: Into<Vec<u8>> + TryFrom<Vec<u8>> + Clone + Debug + Display {
fn to_bytes(&self) -> Vec<u8>;
fn from_bytes(bytes: Vec<u8>) -> Result<Self, MCTypeError>;
async fn read(t: &mut TcpStream) -> Result<Self, MCTypeError>;
async fn write(t: &mut TcpStream) -> tokio::io::Result<()>;
}

734
src/mctypes/numbers.rs Normal file
View File

@ -0,0 +1,734 @@
use super::*;
use std::convert::{From, Into, TryFrom};
use std::fmt::Display;
/// The equivalent of an `i8`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCByte {
pub value: i8, // -128 to 127
}
impl MCByte {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCByte> {
Ok(MCByte::from_bytes(vec![read_byte(t).await?]))
}
pub fn from_bytes(v: Vec<u8>) -> MCByte {
MCByte {
value: get_bytes(v, 1)[0] as i8,
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<i8> for MCByte {
fn from(v: i8) -> MCByte {
MCByte { value: v }
}
}
impl Into<i8> for MCByte {
fn into(self) -> i8 {
self.value
}
}
impl PartialEq<i8> for MCByte {
fn eq(&self, other: &i8) -> bool {
self.value == *other
}
}
impl Display for MCByte {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCByte {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.is_empty() {
Err("Not enough bytes")
} else {
let mut a = [0u8; 1];
a.copy_from_slice(&get_bytes(bytes, 1));
Ok(MCByte {
value: i8::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCByte {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// The equivalent of a `u8`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCUnsignedByte {
pub value: u8, // 0 to 255
}
impl MCUnsignedByte {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCUnsignedByte> {
Ok(MCUnsignedByte::from_bytes(vec![read_byte(t).await?]))
}
pub fn from_bytes(v: Vec<u8>) -> MCUnsignedByte {
MCUnsignedByte {
value: get_bytes(v, 1)[0],
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<u8> for MCUnsignedByte {
fn from(v: u8) -> MCUnsignedByte {
MCUnsignedByte { value: v }
}
}
impl Into<u8> for MCUnsignedByte {
fn into(self) -> u8 {
self.value
}
}
impl PartialEq<u8> for MCUnsignedByte {
fn eq(&self, other: &u8) -> bool {
self.value == *other
}
}
impl Display for MCUnsignedByte {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCUnsignedByte {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.is_empty() {
Err("Not enough bytes")
} else {
let mut a = [0u8; 1];
a.copy_from_slice(&get_bytes(bytes, 1));
Ok(MCUnsignedByte {
value: u8::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCUnsignedByte {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// The equivalent of an `i16`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCShort {
pub value: i16, // -32768 to 32767
}
impl MCShort {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCShort> {
let mut bytes = Vec::new();
bytes.push(read_byte(t).await?); // MSD
bytes.push(read_byte(t).await?); // LSD
Ok(MCShort::from_bytes(bytes))
}
pub fn from_bytes(v: Vec<u8>) -> MCShort {
let mut a = [0u8; 2];
a.copy_from_slice(&get_bytes(v, 2));
MCShort {
value: i16::from_be_bytes(a),
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<i16> for MCShort {
fn from(v: i16) -> MCShort {
MCShort { value: v }
}
}
impl Into<i16> for MCShort {
fn into(self) -> i16 {
self.value
}
}
impl PartialEq<i16> for MCShort {
fn eq(&self, other: &i16) -> bool {
self.value == *other
}
}
impl Display for MCShort {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCShort {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.len() < 2 {
Err("Not enough bytes")
} else {
let mut a = [0u8; 2];
a.copy_from_slice(&get_bytes(bytes, 2));
Ok(MCShort {
value: i16::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCShort {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// The equivalent of a `u16`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCUnsignedShort {
pub value: u16, // 0 to 65535
}
impl MCUnsignedShort {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCUnsignedShort> {
let mut bytes = Vec::new();
bytes.push(read_byte(t).await?); // MSD
bytes.push(read_byte(t).await?); // LSD
Ok(MCUnsignedShort::from_bytes(bytes))
}
pub fn from_bytes(v: Vec<u8>) -> MCUnsignedShort {
let mut a = [0u8; 2];
a.copy_from_slice(&get_bytes(v, 2));
MCUnsignedShort {
value: u16::from_be_bytes(a),
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<u16> for MCUnsignedShort {
fn from(v: u16) -> MCUnsignedShort {
MCUnsignedShort { value: v }
}
}
impl Into<u16> for MCUnsignedShort {
fn into(self) -> u16 {
self.value
}
}
impl PartialEq<u16> for MCUnsignedShort {
fn eq(&self, other: &u16) -> bool {
self.value == *other
}
}
impl Display for MCUnsignedShort {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCUnsignedShort {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.len() < 2 {
Err("Not enough bytes")
} else {
let mut a = [0u8; 2];
a.copy_from_slice(&get_bytes(bytes, 2));
Ok(MCUnsignedShort {
value: u16::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCUnsignedShort {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// The equivalent of an `i32`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCInt {
pub value: i32, // -2147483648 to 2147483647
}
impl MCInt {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCInt> {
let mut bytes = Vec::new();
for _ in 0..4 {
bytes.push(read_byte(t).await?);
}
Ok(MCInt::from_bytes(bytes))
}
pub fn from_bytes(v: Vec<u8>) -> MCInt {
let mut a = [0u8; 4];
a.copy_from_slice(&get_bytes(v, 4));
MCInt {
value: i32::from_be_bytes(a),
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<i32> for MCInt {
fn from(v: i32) -> MCInt {
MCInt { value: v }
}
}
impl Into<i32> for MCInt {
fn into(self) -> i32 {
self.value
}
}
impl PartialEq<i32> for MCInt {
fn eq(&self, other: &i32) -> bool {
self.value == *other
}
}
impl Display for MCInt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCInt {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.len() < 4 {
Err("Not enough bytes")
} else {
let mut a = [0u8; 4];
a.copy_from_slice(&get_bytes(bytes, 4));
Ok(MCInt {
value: i32::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCInt {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// The equivalent of a `u32`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCUnsignedInt {
pub value: u32, // 0 to 4294967295
}
impl MCUnsignedInt {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCUnsignedInt> {
let mut bytes = Vec::new();
for _ in 0..4 {
bytes.push(read_byte(t).await?);
}
Ok(MCUnsignedInt::from_bytes(bytes))
}
pub fn from_bytes(v: Vec<u8>) -> MCUnsignedInt {
let mut a = [0u8; 4];
a.copy_from_slice(&get_bytes(v, 4));
MCUnsignedInt {
value: u32::from_be_bytes(a),
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<u32> for MCUnsignedInt {
fn from(v: u32) -> MCUnsignedInt {
MCUnsignedInt { value: v }
}
}
impl Into<u32> for MCUnsignedInt {
fn into(self) -> u32 {
self.value
}
}
impl PartialEq<u32> for MCUnsignedInt {
fn eq(&self, other: &u32) -> bool {
self.value == *other
}
}
impl Display for MCUnsignedInt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCUnsignedInt {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.len() < 4 {
Err("Not enough bytes")
} else {
let mut a = [0u8; 4];
a.copy_from_slice(&get_bytes(bytes, 4));
Ok(MCUnsignedInt {
value: u32::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCUnsignedInt {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// The equivalent of an `864`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCLong {
pub value: i64, // -9223372036854775808 to 9223372036854775807
}
impl MCLong {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCLong> {
let mut bytes = Vec::new();
for _ in 0..8 {
bytes.push(read_byte(t).await?);
}
Ok(MCLong::from_bytes(bytes))
}
pub fn from_bytes(v: Vec<u8>) -> MCLong {
let mut a = [0u8; 8];
a.copy_from_slice(&get_bytes(v, 8));
MCLong {
value: i64::from_be_bytes(a),
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<i64> for MCLong {
fn from(v: i64) -> MCLong {
MCLong { value: v }
}
}
impl Into<i64> for MCLong {
fn into(self) -> i64 {
self.value
}
}
impl PartialEq<i64> for MCLong {
fn eq(&self, other: &i64) -> bool {
self.value == *other
}
}
impl Display for MCLong {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCLong {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.len() < 8 {
Err("Not enough bytes")
} else {
let mut a = [0u8; 8];
a.copy_from_slice(&get_bytes(bytes, 8));
Ok(MCLong {
value: i64::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCLong {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// The equivalent of a `u64`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCUnsignedLong {
pub value: u64, // 0 to 18446744073709551615
}
impl MCUnsignedLong {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCUnsignedLong> {
let mut bytes = Vec::new();
for _ in 0..8 {
bytes.push(read_byte(t).await?);
}
Ok(MCUnsignedLong::from_bytes(bytes))
}
pub fn from_bytes(v: Vec<u8>) -> MCUnsignedLong {
let mut a = [0u8; 8];
a.copy_from_slice(&get_bytes(v, 8));
MCUnsignedLong {
value: u64::from_be_bytes(a),
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<u64> for MCUnsignedLong {
fn from(v: u64) -> MCUnsignedLong {
MCUnsignedLong { value: v }
}
}
impl Into<u64> for MCUnsignedLong {
fn into(self) -> u64 {
self.value
}
}
impl PartialEq<u64> for MCUnsignedLong {
fn eq(&self, other: &u64) -> bool {
self.value == *other
}
}
impl Display for MCUnsignedLong {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCUnsignedLong {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.len() < 8 {
Err("Not enough bytes")
} else {
let mut a = [0u8; 8];
a.copy_from_slice(&get_bytes(bytes, 8));
Ok(MCUnsignedLong {
value: u64::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCUnsignedLong {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// The equivalent of a `f32`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCFloat {
pub value: f32, // 32-bit floating point number
}
impl MCFloat {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCFloat> {
let mut bytes = Vec::new();
for _ in 0..4 {
bytes.push(read_byte(t).await?);
}
Ok(MCFloat::from_bytes(bytes))
}
pub fn from_bytes(v: Vec<u8>) -> MCFloat {
let mut a = [0u8; 4];
a.copy_from_slice(&get_bytes(v, 4));
MCFloat {
value: f32::from_be_bytes(a),
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<f32> for MCFloat {
fn from(v: f32) -> MCFloat {
MCFloat { value: v }
}
}
impl Into<f32> for MCFloat {
fn into(self) -> f32 {
self.value
}
}
impl PartialEq<f32> for MCFloat {
fn eq(&self, other: &f32) -> bool {
self.value == *other
}
}
impl Display for MCFloat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCFloat {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.len() < 4 {
Err("Not enough bytes")
} else {
let mut a = [0u8; 4];
a.copy_from_slice(&get_bytes(bytes, 4));
Ok(MCFloat {
value: f32::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCFloat {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// The equivalent of a `f64`
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCDouble {
pub value: f64, // 64-bit floating point number
}
impl MCDouble {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCDouble> {
let mut bytes = Vec::new();
for _ in 0..8 {
bytes.push(read_byte(t).await?);
}
Ok(MCDouble::from_bytes(bytes))
}
pub fn from_bytes(v: Vec<u8>) -> MCDouble {
let mut a = [0u8; 8];
a.copy_from_slice(&get_bytes(v, 8));
MCDouble {
value: f64::from_be_bytes(a),
}
}
pub fn to_bytes(&self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
impl From<f64> for MCDouble {
fn from(v: f64) -> MCDouble {
MCDouble { value: v }
}
}
impl Into<f64> for MCDouble {
fn into(self) -> f64 {
self.value
}
}
impl PartialEq<f64> for MCDouble {
fn eq(&self, other: &f64) -> bool {
self.value == *other
}
}
impl Display for MCDouble {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCDouble {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.len() < 8 {
Err("Not enough bytes")
} else {
let mut a = [0u8; 8];
a.copy_from_slice(&get_bytes(bytes, 8));
Ok(MCDouble {
value: f64::from_be_bytes(a),
})
}
}
}
impl Into<Vec<u8>> for MCDouble {
fn into(self) -> Vec<u8> {
self.value.to_be_bytes().to_vec()
}
}
/// A variable-length integer.
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct MCVarInt {
pub value: i32, // Variable length 32-bit integer
}
impl MCVarInt {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCVarInt> {
let mut num_read = 0;
let mut result = 0i32;
let mut read = 0u8;
let mut run_once = false;
while (read & 0b10000000) != 0 || !run_once {
run_once = true;
read = read_byte(t).await?;
let value = (read & 0b01111111) as i32;
result |= value << (7 * num_read);
num_read += 1;
if num_read > 5 {
return Err(io_error("MCVarInt is too big"));
}
}
Ok(MCVarInt { value: result })
}
pub fn from_bytes(_v: Vec<u8>) -> MCVarInt {
unimplemented!()
}
pub fn to_bytes(&self) -> Vec<u8> {
unimplemented!()
}
}
impl From<u8> for MCVarInt {
fn from(v: u8) -> MCVarInt {
MCVarInt { value: v as i32 }
}
}
impl Into<u8> for MCVarInt {
fn into(self) -> u8 {
self.value as u8
}
}
impl PartialEq<u8> for MCVarInt {
fn eq(&self, other: &u8) -> bool {
self.value == *other as i32
}
}
impl From<i32> for MCVarInt {
fn from(v: i32) -> MCVarInt {
MCVarInt { value: v }
}
}
impl Into<i32> for MCVarInt {
fn into(self) -> i32 {
self.value
}
}
impl PartialEq<i32> for MCVarInt {
fn eq(&self, other: &i32) -> bool {
self.value == *other
}
}
impl Display for MCVarInt {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCVarInt {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
let mut num_read = 0;
let mut result: i32 = 0;
loop {
let value = bytes[num_read] & 0b01111111;
result |= (value << (7 * num_read)) as i32;
if bytes[num_read] & 0b10000000 == 0x00 {
break;
}
num_read += 1;
if num_read == bytes.len() {
return Err("Not enough bytes");
}
if num_read > 5 {
return Err("VarInt is too big");
}
}
Ok(MCVarInt { value: result })
}
}
impl Into<Vec<u8>> for MCVarInt {
fn into(self) -> Vec<u8> {
let mut value = self.value;
let mut run_once = false;
let mut out: Vec<u8> = Vec::new();
while value != 0 || !run_once {
run_once = true;
let mut temp: u8 = (value & 0b01111111) as u8;
value >>= 7;
if value != 0 {
temp |= 0b10000000;
}
out.push(temp);
}
out
}
}

293
src/mctypes/other.rs Normal file
View File

@ -0,0 +1,293 @@
use super::*;
use std::convert::{From, Into, TryFrom};
use std::fmt::{Debug, Display};
/// The equivalent of a `bool`.
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum MCBoolean {
True,
False,
}
impl From<bool> for MCBoolean {
fn from(v: bool) -> MCBoolean {
if v {
MCBoolean::True
} else {
MCBoolean::False
}
}
}
impl Into<bool> for MCBoolean {
fn into(self) -> bool {
match self {
MCBoolean::True => true,
MCBoolean::False => false,
}
}
}
impl Display for MCBoolean {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
MCBoolean::True => "true",
MCBoolean::False => "false",
}
)
}
}
impl TryFrom<Vec<u8>> for MCBoolean {
type Error = &'static str;
fn try_from(bytes: Vec<u8>) -> Result<Self, Self::Error> {
if bytes.is_empty() {
Err("Not enough bytes")
} else if bytes[0] == 1u8 {
Ok(MCBoolean::True)
} else {
Ok(MCBoolean::False)
}
}
}
impl Into<Vec<u8>> for MCBoolean {
fn into(self) -> Vec<u8> {
match self {
MCBoolean::True => vec![0x01],
MCBoolean::False => vec![0x00],
}
}
}
impl MCBoolean {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<MCBoolean> {
let b = read_byte(t).await?;
Ok(MCBoolean::try_from(vec![b]).unwrap())
}
}
/// The equivalent of a `String`.
#[derive(PartialEq)]
pub struct MCString {
pub value: String,
}
impl From<&str> for MCString {
fn from(s: &str) -> MCString {
MCString {
value: s.to_owned(),
}
}
}
impl From<String> for MCString {
fn from(s: String) -> MCString {
MCString { value: s }
}
}
impl Into<String> for MCString {
fn into(self) -> String {
self.value
}
}
impl PartialEq<&str> for MCString {
fn eq(&self, other: &&str) -> bool {
self.value == **other
}
}
impl PartialEq<String> for MCString {
fn eq(&self, other: &String) -> bool {
self.value == *other
}
}
impl PartialEq<&String> for MCString {
fn eq(&self, other: &&String) -> bool {
self.value == **other
}
}
impl Clone for MCString {
fn clone(&self) -> Self {
MCString {
value: self.value.clone(),
}
}
}
impl Debug for MCString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"MCString {{ \"{}\" ({} chars) }}",
self.value,
self.value.len()
)
}
}
impl Display for MCString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl TryFrom<Vec<u8>> for MCString {
type Error = &'static str;
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
Err("Cannot read MCString from bytes")
}
}
impl Into<Vec<u8>> for MCString {
fn into(self) -> Vec<u8> {
let mut out = vec![];
let str_len: Vec<u8> = MCVarInt::from(self.value.len() as i32).into();
for b in str_len {
out.push(b);
}
for b in self.value.into_bytes() {
out.push(b);
}
out
}
}
impl MCString {
pub async fn read(t: &mut TcpStream) -> tokio::io::Result<Self> {
let str_len = MCVarInt::read(t).await?;
let mut str_bytes = vec![];
for _ in 0i32..str_len.into() {
str_bytes.push(read_byte(t).await?);
}
Ok(MCString {
value: String::from_utf8_lossy(&str_bytes).to_string(),
})
}
}
/// A normal `MCString`, but with extra embedded formatting data.
#[derive(Debug, PartialEq)]
pub struct MCChat {
pub text: MCString,
}
impl From<&str> for MCChat {
fn from(s: &str) -> MCChat {
MCChat { text: s.into() }
}
}
impl From<String> for MCChat {
fn from(s: String) -> MCChat {
MCChat { text: s.into() }
}
}
impl Into<String> for MCChat {
fn into(self) -> String {
self.text.value
}
}
impl PartialEq<&str> for MCChat {
fn eq(&self, other: &&str) -> bool {
self.text.value == **other
}
}
impl PartialEq<String> for MCChat {
fn eq(&self, other: &String) -> bool {
self.text.value == *other
}
}
impl PartialEq<&String> for MCChat {
fn eq(&self, other: &&String) -> bool {
self.text.value == **other
}
}
impl Clone for MCChat {
fn clone(&self) -> Self {
MCChat {
text: self.text.clone(),
}
}
}
impl Display for MCChat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"\"{}\" ({} chars)",
self.text.value,
self.text.value.len()
)
}
}
impl TryFrom<Vec<u8>> for MCChat {
type Error = &'static str;
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
Err("Cannot read MCChat from bytes")
}
}
impl Into<Vec<u8>> for MCChat {
fn into(self) -> Vec<u8> {
// Just output
// {"text": "<data>"}
Into::<MCString>::into(
json!({
"text": self.text.value
})
.to_string(),
)
.into()
}
}
impl MCChat {
pub async fn read(_t: &mut TcpStream) -> tokio::io::Result<Self> {
Err(io_error("Cannot read MCChat from stream"))
}
}
// TODO: Actually make the MCPosition work.
#[derive(Debug, PartialEq, Clone)]
pub struct MCPosition {
x: MCLong,
y: MCLong,
z: MCLong,
}
impl Display for MCPosition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "({}, {}, {})", self.x, self.y, self.z,)
}
}
impl TryFrom<Vec<u8>> for MCPosition {
type Error = &'static str;
fn try_from(_bytes: Vec<u8>) -> Result<Self, Self::Error> {
Err("Cannot read MCPosition from bytes")
}
}
impl Into<Vec<u8>> for MCPosition {
fn into(self) -> Vec<u8> {
// Just output
// {"text": "<data>"}
let mut out = vec![];
let mut temp = vec![];
temp.extend_from_slice(
&((((Into::<i64>::into(self.x) & 0x3FFFFFF) << 38)
| ((Into::<i64>::into(self.y) & 0xFFF) << 26)
| (Into::<i64>::into(self.z) & 0x3FFFFFF)) as u64)
.to_be_bytes(),
);
// temp.extend_from_slice(&"{\"text\": \"".to_owned().into_bytes());
// temp.extend_from_slice(&self.text.value.into_bytes());
// temp.extend_from_slice(&"\"}".to_owned().into_bytes());
out.extend_from_slice(&Into::<Vec<u8>>::into(MCVarInt::from(temp.len() as i32)));
out.extend_from_slice(&temp);
out
}
}
impl MCPosition {
pub fn new() -> MCPosition {
MCPosition {
x: 0.into(),
y: 0.into(),
z: 0.into(),
}
}
pub async fn read(_t: &mut TcpStream) -> tokio::io::Result<Self> {
Err(io_error("Cannot read MCPosition from stream"))
}
}
impl Default for MCPosition {
fn default() -> Self {
MCPosition {
x: 0.into(),
y: 0.into(),
z: 0.into(),
}
}
}