This commit is contained in:
ElementG9 2020-05-26 16:24:49 -06:00
parent ef86b059c5
commit 7be571f198
2 changed files with 80 additions and 107 deletions

View File

@ -64,13 +64,11 @@ impl MCBoolean {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MCByte { pub struct MCByte {
pub value: i8 // -128 to 127 pub value: i8, // -128 to 127
} }
impl From<i8> for MCByte { impl From<i8> for MCByte {
fn from(v: i8) -> MCByte { fn from(v: i8) -> MCByte {
MCByte { MCByte { value: v }
value: v
}
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -80,7 +78,7 @@ impl MCByte {
} }
pub fn from_bytes(v: Vec<u8>) -> MCByte { pub fn from_bytes(v: Vec<u8>) -> MCByte {
MCByte { MCByte {
value: get_bytes(v, 1)[0] as i8 value: get_bytes(v, 1)[0] as i8,
} }
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -90,13 +88,11 @@ impl MCByte {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MCUnsignedByte { pub struct MCUnsignedByte {
pub value: u8 // 0 to 255 pub value: u8, // 0 to 255
} }
impl From<u8> for MCUnsignedByte { impl From<u8> for MCUnsignedByte {
fn from(v: u8) -> MCUnsignedByte { fn from(v: u8) -> MCUnsignedByte {
MCUnsignedByte { MCUnsignedByte { value: v }
value: v
}
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -106,7 +102,7 @@ impl MCUnsignedByte {
} }
pub fn from_bytes(v: Vec<u8>) -> MCUnsignedByte { pub fn from_bytes(v: Vec<u8>) -> MCUnsignedByte {
MCUnsignedByte { MCUnsignedByte {
value: get_bytes(v, 1)[0] value: get_bytes(v, 1)[0],
} }
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -116,13 +112,11 @@ impl MCUnsignedByte {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MCShort { pub struct MCShort {
pub value: i16 // -32768 to 32767 pub value: i16, // -32768 to 32767
} }
impl From<i16> for MCShort { impl From<i16> for MCShort {
fn from(v: i16) -> MCShort { fn from(v: i16) -> MCShort {
MCShort { MCShort { value: v }
value: v
}
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -137,7 +131,7 @@ impl MCShort {
let mut a = [0u8; 2]; let mut a = [0u8; 2];
a.copy_from_slice(&get_bytes(v, 2)); a.copy_from_slice(&get_bytes(v, 2));
MCShort { MCShort {
value: i16::from_be_bytes(a) value: i16::from_be_bytes(a),
} }
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -147,13 +141,11 @@ impl MCShort {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MCUnsignedShort { pub struct MCUnsignedShort {
pub value: u16 // 0 to 65535 pub value: u16, // 0 to 65535
} }
impl From<u16> for MCUnsignedShort { impl From<u16> for MCUnsignedShort {
fn from(v: u16) -> MCUnsignedShort { fn from(v: u16) -> MCUnsignedShort {
MCUnsignedShort { MCUnsignedShort { value: v }
value: v
}
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -168,7 +160,7 @@ impl MCUnsignedShort {
let mut a = [0u8; 2]; let mut a = [0u8; 2];
a.copy_from_slice(&get_bytes(v, 2)); a.copy_from_slice(&get_bytes(v, 2));
MCUnsignedShort { MCUnsignedShort {
value: u16::from_be_bytes(a) value: u16::from_be_bytes(a),
} }
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -178,13 +170,11 @@ impl MCUnsignedShort {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MCInt { pub struct MCInt {
pub value: i32 // -2147483648 to 2147483647 pub value: i32, // -2147483648 to 2147483647
} }
impl From<i32> for MCInt { impl From<i32> for MCInt {
fn from(v: i32) -> MCInt { fn from(v: i32) -> MCInt {
MCInt { MCInt { value: v }
value: v
}
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -200,7 +190,7 @@ impl MCInt {
let mut a = [0u8; 4]; let mut a = [0u8; 4];
a.copy_from_slice(&get_bytes(v, 4)); a.copy_from_slice(&get_bytes(v, 4));
MCInt { MCInt {
value: i32::from_be_bytes(a) value: i32::from_be_bytes(a),
} }
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -210,13 +200,11 @@ impl MCInt {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MCLong { pub struct MCLong {
pub value: i64 // -9223372036854775808 to 9223372036854775807 pub value: i64, // -9223372036854775808 to 9223372036854775807
} }
impl From<i64> for MCLong { impl From<i64> for MCLong {
fn from(v: i64) -> MCLong { fn from(v: i64) -> MCLong {
MCLong { MCLong { value: v }
value: v
}
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -232,7 +220,7 @@ impl MCLong {
let mut a = [0u8; 8]; let mut a = [0u8; 8];
a.copy_from_slice(&get_bytes(v, 8)); a.copy_from_slice(&get_bytes(v, 8));
MCLong { MCLong {
value: i64::from_be_bytes(a) value: i64::from_be_bytes(a),
} }
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -242,13 +230,11 @@ impl MCLong {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MCFloat { pub struct MCFloat {
pub value: f32 // 32-bit floating point number pub value: f32, // 32-bit floating point number
} }
impl From<f32> for MCFloat { impl From<f32> for MCFloat {
fn from(v: f32) -> MCFloat { fn from(v: f32) -> MCFloat {
MCFloat { MCFloat { value: v }
value: v
}
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -264,7 +250,7 @@ impl MCFloat {
let mut a = [0u8; 4]; let mut a = [0u8; 4];
a.copy_from_slice(&get_bytes(v, 4)); a.copy_from_slice(&get_bytes(v, 4));
MCFloat { MCFloat {
value: f32::from_be_bytes(a) value: f32::from_be_bytes(a),
} }
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -274,13 +260,11 @@ impl MCFloat {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MCDouble { pub struct MCDouble {
pub value: f64 // 64-bit floating point number pub value: f64, // 64-bit floating point number
} }
impl From<f64> for MCDouble { impl From<f64> for MCDouble {
fn from(v: f64) -> MCDouble { fn from(v: f64) -> MCDouble {
MCDouble { MCDouble { value: v }
value: v
}
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -296,7 +280,7 @@ impl MCDouble {
let mut a = [0u8; 8]; let mut a = [0u8; 8];
a.copy_from_slice(&get_bytes(v, 8)); a.copy_from_slice(&get_bytes(v, 8));
MCDouble { MCDouble {
value: f64::from_be_bytes(a) value: f64::from_be_bytes(a),
} }
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
@ -306,21 +290,17 @@ impl MCDouble {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MCVarInt { pub struct MCVarInt {
pub value: i32 // Variable length 32-bit integer pub value: i32, // Variable length 32-bit integer
} }
impl From<i32> for MCVarInt { impl From<i32> for MCVarInt {
fn from(v: i32) -> MCVarInt { fn from(v: i32) -> MCVarInt {
MCVarInt { MCVarInt { value: v }
value: v
}
} }
} }
#[allow(dead_code)] #[allow(dead_code)]
impl MCVarInt { impl MCVarInt {
pub fn new(i: i32) -> MCVarInt { pub fn new(i: i32) -> MCVarInt {
MCVarInt { MCVarInt { value: i }
value: i
}
} }
pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCVarInt> { pub fn from_stream(t: &mut TcpStream) -> std::io::Result<MCVarInt> {
let mut numRead = 0; let mut numRead = 0;
@ -337,9 +317,7 @@ impl MCVarInt {
return Err(io_error("MCVarInt is too big")); return Err(io_error("MCVarInt is too big"));
} }
} }
Ok(MCVarInt { Ok(MCVarInt { value: result })
value: result
})
} }
pub fn from_bytes(_: Vec<u8>) -> MCVarInt { pub fn from_bytes(_: Vec<u8>) -> MCVarInt {
panic!("Cannot construct MCVarInt from raw bytes"); panic!("Cannot construct MCVarInt from raw bytes");
@ -368,7 +346,7 @@ impl std::fmt::Display for MCVarInt {
#[allow(dead_code)] #[allow(dead_code)]
#[derive(Debug)] #[derive(Debug)]
pub struct MCString { pub struct MCString {
pub value: String pub value: String,
} }
#[allow(dead_code)] #[allow(dead_code)]
impl MCString { impl MCString {
@ -381,7 +359,7 @@ impl MCString {
let value = String::from_utf8(bytes); let value = String::from_utf8(bytes);
if value.is_ok() { if value.is_ok() {
Ok(MCString { Ok(MCString {
value: value.unwrap() value: value.unwrap(),
}) })
} else { } else {
return Err(io_error("MCString contains invalid utf-8")); return Err(io_error("MCString contains invalid utf-8"));
@ -393,7 +371,7 @@ impl MCString {
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
let mut out = Vec::new(); let mut out = Vec::new();
let length = MCVarInt { let length = MCVarInt {
value: self.value.len() as i32 value: self.value.len() as i32,
}; };
for b in length.to_bytes() { for b in length.to_bytes() {
out.push(b); out.push(b);
@ -407,21 +385,19 @@ impl MCString {
impl From<&str> for MCString { impl From<&str> for MCString {
fn from(s: &str) -> MCString { fn from(s: &str) -> MCString {
MCString { MCString {
value: s.to_owned() value: s.to_owned(),
} }
} }
} }
impl From<String> for MCString { impl From<String> for MCString {
fn from(s: String) -> MCString { fn from(s: String) -> MCString {
MCString { MCString { value: s.clone() }
value: s.clone()
}
} }
} }
impl Clone for MCString { impl Clone for MCString {
fn clone(&self) -> Self { fn clone(&self) -> Self {
MCString { MCString {
value: self.value.clone() value: self.value.clone(),
} }
} }
} }

View File

@ -2,16 +2,16 @@ pub static SERVER_LISTENER_ADDRESS: &str = "127.0.0.1:25565";
pub static SOCKET_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5); pub static SOCKET_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5);
extern crate serde; extern crate serde;
extern crate serde_json; extern crate serde_json;
use crate::mctypes::*;
use serde::Serialize; use serde::Serialize;
use serde_json::json; use serde_json::json;
use std::io::prelude::*; use std::io::prelude::*;
use std::net::{TcpStream, TcpListener}; use std::net::{TcpListener, TcpStream};
use std::thread; use std::thread;
use crate::mctypes::*;
pub struct MCPacket { pub struct MCPacket {
pub id: MCVarInt, pub id: MCVarInt,
pub data: Vec<u8> pub data: Vec<u8>,
} }
#[allow(dead_code)] #[allow(dead_code)]
impl MCPacket { impl MCPacket {
@ -33,10 +33,7 @@ impl MCPacket {
} }
pub fn to_bytes(&self) -> Vec<u8> { pub fn to_bytes(&self) -> Vec<u8> {
let mut bytes = Vec::new(); let mut bytes = Vec::new();
for b in MCVarInt::new(( for b in MCVarInt::new((self.id.to_bytes().len() + self.data.len()) as i32).to_bytes() {
self.id.to_bytes().len() +
self.data.len()
) as i32).to_bytes() {
bytes.push(b); bytes.push(b);
} }
for b in self.id.to_bytes() { for b in self.id.to_bytes() {
@ -55,7 +52,7 @@ pub enum GameState {
Status, Status,
Login, Login,
Play, Play,
Closed Closed,
} }
#[allow(dead_code)] #[allow(dead_code)]
pub struct GameConnection { pub struct GameConnection {
@ -71,22 +68,24 @@ pub fn start_listener() -> std::io::Result<()> {
// Spawn a new thread for each connection. // Spawn a new thread for each connection.
for stream in listener.incoming() { for stream in listener.incoming() {
let stream = stream?; let stream = stream?;
thread::Builder::new().name(format!("GameConnection {}", stream.peer_addr().unwrap())).spawn(move || -> std::io::Result<()> { thread::Builder::new()
if crate::DEBUG_LOGGING { .name(format!("GameConnection {}", stream.peer_addr().unwrap()))
println!("Client connected at {}", stream.peer_addr().unwrap()); .spawn(move || -> std::io::Result<()> {
} if crate::DEBUG_LOGGING {
stream println!("Client connected at {}", stream.peer_addr().unwrap());
.set_read_timeout(Some(SOCKET_TIMEOUT)) }
.expect("set_read_timeout call failed"); stream
stream .set_read_timeout(Some(SOCKET_TIMEOUT))
.set_write_timeout(Some(SOCKET_TIMEOUT)) .expect("set_read_timeout call failed");
.expect("set_write_timeout call failed"); stream
handle_client(GameConnection { .set_write_timeout(Some(SOCKET_TIMEOUT))
stream: stream, .expect("set_write_timeout call failed");
state: GameState::Handshake, handle_client(GameConnection {
stream: stream,
state: GameState::Handshake,
})?;
Ok(())
})?; })?;
Ok(())
})?;
} }
Ok(()) Ok(())
} }
@ -94,30 +93,29 @@ pub fn handle_client(mut gc: GameConnection) -> std::io::Result<()> {
loop { loop {
let (packet_length, packet_id) = MCPacket::read_header(&mut gc.stream)?; let (packet_length, packet_id) = MCPacket::read_header(&mut gc.stream)?;
if crate::DEBUG_LOGGING { if crate::DEBUG_LOGGING {
println!("Packet Length: {}, Packet ID: {}", packet_length.value, packet_id.value); println!(
"Packet Length: {}, Packet ID: {}",
packet_length.value, packet_id.value
);
} }
match gc.state { match gc.state {
GameState::Handshake => { GameState::Handshake => match packet_id.value {
match packet_id.value { 0x00 => {
0x00 => { handshake(&mut gc)?;
handshake(&mut gc)?; }
}, _ => {
_ => { if crate::DEBUG_LOGGING {
if crate::DEBUG_LOGGING { println!("Unknown packet id {} in Handshake", packet_id);
println!("Unknown packet id {} in Handshake", packet_id);
}
} }
} }
}, },
GameState::Login => { GameState::Login => match packet_id.value {
match packet_id.value { 0x00 => {
0x00 => { login(&mut gc)?;
login(&mut gc)?; }
}, _ => {
_ => { if crate::DEBUG_LOGGING {
if crate::DEBUG_LOGGING { println!("Unknown packet id {} in Login", packet_id);
println!("Unknown packet id {} in Login", packet_id);
}
} }
} }
}, },
@ -146,12 +144,13 @@ pub fn handle_client(mut gc: GameConnection) -> std::io::Result<()> {
} }
// No favicon for now. // No favicon for now.
// "favicon": "data:image/png;base64,<data>" // "favicon": "data:image/png;base64,<data>"
}).to_string(); })
.to_string();
packet.write(MCVarInt::new(json_response.len() as i32).to_bytes()); packet.write(MCVarInt::new(json_response.len() as i32).to_bytes());
packet.write(MCString::from(json_response.clone()).to_bytes()); packet.write(MCString::from(json_response.clone()).to_bytes());
gc.stream.write(&packet.to_bytes())?; gc.stream.write(&packet.to_bytes())?;
println!("=== SENT SERVER RESPONSE ===\n{}", json_response); println!("=== SENT SERVER RESPONSE ===\n{}", json_response);
}, }
_ => { _ => {
if crate::DEBUG_LOGGING { if crate::DEBUG_LOGGING {
println!("Unknown packet id {} in Status", packet_id); println!("Unknown packet id {} in Status", packet_id);
@ -183,11 +182,9 @@ pub fn handshake(gc: &mut GameConnection) -> std::io::Result<()> {
} }
}; };
if crate::DEBUG_LOGGING { if crate::DEBUG_LOGGING {
println!("Handshake: Protocol Version: {}, Server Address: {}:{}, Next State: {:?}", println!(
protocol_version.value, "Handshake: Protocol Version: {}, Server Address: {}:{}, Next State: {:?}",
server_address.value, protocol_version.value, server_address.value, server_port.value, next_state
server_port.value,
next_state
); );
} }
gc.state = next_state; gc.state = next_state;