Refactoring
This commit is contained in:
parent
5a50b46836
commit
2acaea1bd2
|
@ -1,7 +1,6 @@
|
|||
// Yeahbut December 2023
|
||||
|
||||
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
use crate::mc_types;
|
||||
|
||||
|
@ -12,33 +11,33 @@ pub struct Handshake {
|
|||
pub next_state: i32,
|
||||
}
|
||||
|
||||
pub async fn read_handshake(stream: &mut OwnedReadHalf) -> Option<Handshake> {
|
||||
Some(Handshake {
|
||||
protocol_version: mc_types::read_var_int(stream)
|
||||
.await,
|
||||
server_address: mc_types::read_string(stream)
|
||||
.await,
|
||||
server_port: stream.read_u16()
|
||||
.await.expect("Error reading from stream"),
|
||||
next_state: mc_types::read_var_int(stream)
|
||||
.await,
|
||||
})
|
||||
pub async fn read_handshake(stream: &mut OwnedReadHalf) -> Handshake {
|
||||
get_handshake(&mut mc_types::read_packet(stream).await)
|
||||
}
|
||||
|
||||
pub fn get_handshake(data: &mut Vec<u8>) -> Handshake {
|
||||
mc_types::get_var_int(data);
|
||||
Handshake {
|
||||
protocol_version: mc_types::get_var_int(data),
|
||||
server_address: mc_types::get_string(data),
|
||||
server_port: mc_types::get_u16(data),
|
||||
next_state: mc_types::get_var_int(data),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn convert_handshake(handshake: Handshake) -> Vec<u8> {
|
||||
let mut data: Vec<u8> = vec![0];
|
||||
data.append(&mut mc_types::convert_var_int(handshake.protocol_version));
|
||||
data.append(&mut mc_types::convert_string(&handshake.server_address));
|
||||
data.append(&mut mc_types::convert_u16(handshake.server_port));
|
||||
data.append(&mut mc_types::convert_var_int(handshake.next_state));
|
||||
|
||||
data
|
||||
}
|
||||
|
||||
pub async fn write_handshake(
|
||||
stream: &mut OwnedWriteHalf,
|
||||
handshake: Handshake,
|
||||
) {
|
||||
let mut data: Vec<u8> = vec![0];
|
||||
mc_types::write_var_int_bytes(&mut data, handshake.protocol_version);
|
||||
mc_types::write_string_bytes(&mut data, &handshake.server_address);
|
||||
data.append(&mut vec![
|
||||
((handshake.server_port & 0xFF00) >> 8) as u8,
|
||||
(handshake.server_port & 0xFF) as u8,
|
||||
]);
|
||||
mc_types::write_var_int_bytes(&mut data, handshake.next_state);
|
||||
|
||||
mc_types::write_var_int(stream, data.len() as i32).await;
|
||||
stream.write_all(&mut data)
|
||||
.await.expect("Error writing to stream");
|
||||
mc_types::write_packet(stream, &mut convert_handshake(handshake)).await;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
// Yeahbut December 2023
|
||||
|
||||
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
|
||||
use crate::mc_types;
|
||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -1,7 +1,7 @@
|
|||
// Yeahbut December 2023
|
||||
|
||||
use tokio::net::{TcpListener, TcpStream};
|
||||
use tokio::io::{self, AsyncReadExt}; //, AsyncWriteExt};
|
||||
use tokio::io;
|
||||
use std::error::Error;
|
||||
|
||||
mod mc_types;
|
||||
|
@ -27,14 +27,19 @@ async fn handle_client(client_socket: TcpStream) {
|
|||
|
||||
let (mut client_reader, mut client_writer) = client_socket.into_split();
|
||||
if let Ok(backend_socket) = TcpStream::connect(backend_addr).await {
|
||||
let (mut server_reader, mut server_writer) = backend_socket.into_split();
|
||||
let packet_id = client_reader.read_u8()
|
||||
let (mut server_reader, mut server_writer) =
|
||||
backend_socket.into_split();
|
||||
let mut buffer: [u8; 1] = [0; 1];
|
||||
client_reader.peek(&mut buffer)
|
||||
.await.expect("Error reading from stream");
|
||||
let packet_id: u8 = buffer[0];
|
||||
|
||||
println!("Packet ID: {}", packet_id);
|
||||
if packet_id == 0 {
|
||||
if packet_id == 0xFE {
|
||||
status::respond_legacy_status(&mut client_writer).await;
|
||||
return;
|
||||
} else {
|
||||
let handshake_packet = handshake::read_handshake(&mut client_reader)
|
||||
.await.unwrap();
|
||||
.await;
|
||||
println!("Next state: {}", handshake_packet.next_state);
|
||||
if handshake_packet.next_state == 1 {
|
||||
println!("Receiving Status Request");
|
||||
|
@ -50,11 +55,6 @@ async fn handle_client(client_socket: TcpStream) {
|
|||
} else {
|
||||
return;
|
||||
}
|
||||
} else if packet_id == 0xFE {
|
||||
status::respond_legacy_status(&mut client_writer).await;
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Forward from client to backend
|
||||
|
|
194
src/mc_types.rs
194
src/mc_types.rs
|
@ -2,7 +2,7 @@
|
|||
|
||||
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use serde::Serialize;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
pub const VERSION_NAME: &str = "1.19.4";
|
||||
pub const VERSION_PROTOCOL: i32 = 762;
|
||||
|
@ -10,19 +10,153 @@ pub const VERSION_PROTOCOL: i32 = 762;
|
|||
const SEGMENT_BITS: u8 = 0x7F;
|
||||
const CONTINUE_BIT: u8 = 0x80;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Chat {
|
||||
pub text: String,
|
||||
}
|
||||
|
||||
pub async fn read_var_int(stream: &mut OwnedReadHalf) -> i32 {
|
||||
pub async fn read_packet(stream: &mut OwnedReadHalf) -> Vec<u8> {
|
||||
let length = read_var_int_stream(stream).await;
|
||||
let mut buffer: Vec<u8> = vec![0; length as usize];
|
||||
stream.read_exact(&mut buffer)
|
||||
.await.expect("Error reading string from stream");
|
||||
buffer
|
||||
}
|
||||
pub async fn write_packet(stream: &mut OwnedWriteHalf, data: &mut Vec<u8>) {
|
||||
let length = data.len() as i32;
|
||||
stream.write_all(&convert_var_int(length))
|
||||
.await.expect("Error writing to stream");
|
||||
stream.write_all(&data)
|
||||
.await.expect("Error writing to stream");
|
||||
}
|
||||
async fn read_var_int_stream(stream: &mut OwnedReadHalf) -> i32 {
|
||||
let mut data: Vec<u8> = vec![];
|
||||
|
||||
loop {
|
||||
let current_byte = stream.read_u8()
|
||||
.await.expect("Error reading from stream");
|
||||
|
||||
data.append(&mut vec![current_byte]);
|
||||
|
||||
if (current_byte & CONTINUE_BIT) == 0 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
get_var_int(&mut data)
|
||||
}
|
||||
|
||||
pub fn get_bool(data: &mut Vec<u8>) -> bool {
|
||||
data.remove(0) != 0
|
||||
}
|
||||
pub fn convert_bool(value: bool) -> Vec<u8> {
|
||||
vec![value as u8]
|
||||
}
|
||||
|
||||
pub fn get_u8(data: &mut Vec<u8>) -> u8 {
|
||||
data.remove(0)
|
||||
}
|
||||
pub fn convert_u8(value: u8) -> Vec<u8> {
|
||||
vec![value]
|
||||
}
|
||||
|
||||
pub fn get_i8(data: &mut Vec<u8>) -> i8 {
|
||||
get_u8(data) as i8
|
||||
}
|
||||
pub fn convert_i8(value: i8) -> Vec<u8> {
|
||||
convert_u8(value as u8)
|
||||
}
|
||||
|
||||
pub fn get_u16(data: &mut Vec<u8>) -> u16 {
|
||||
((data.remove(0) as u16) << 8) |
|
||||
(data.remove(0) as u16)
|
||||
}
|
||||
pub fn convert_u16(value: u16) -> Vec<u8> {
|
||||
vec![
|
||||
((value & 0xFF00) >> 8) as u8,
|
||||
(value & 0xFF) as u8,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn get_i16(data: &mut Vec<u8>) -> i16 {
|
||||
get_u16(data) as i16
|
||||
}
|
||||
pub fn convert_i16(value: i16) -> Vec<u8> {
|
||||
convert_u16(value as u16)
|
||||
}
|
||||
|
||||
pub fn get_u32(data: &mut Vec<u8>) -> u32 {
|
||||
((data.remove(0) as u32) << 24) |
|
||||
((data.remove(0) as u32) << 16) |
|
||||
((data.remove(0) as u32) << 8) |
|
||||
(data.remove(0) as u32)
|
||||
}
|
||||
pub fn convert_u32(value: u32) -> Vec<u8> {
|
||||
vec![
|
||||
((value & 0xFF0000) >> 24) as u8,
|
||||
((value & 0xFF0000) >> 16) as u8,
|
||||
((value & 0xFF00) >> 8) as u8,
|
||||
(value & 0xFF) as u8,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn get_i32(data: &mut Vec<u8>) -> i32 {
|
||||
get_u32(data) as i32
|
||||
}
|
||||
pub fn convert_i32(value: i32) -> Vec<u8> {
|
||||
convert_u32(value as u32)
|
||||
}
|
||||
|
||||
pub fn get_f32(data: &mut Vec<u8>) -> f32 {
|
||||
get_u32(data) as f32
|
||||
}
|
||||
pub fn convert_f32(value: f32) -> Vec<u8> {
|
||||
convert_u32(value as u32)
|
||||
}
|
||||
|
||||
pub fn get_u64(data: &mut Vec<u8>) -> u64 {
|
||||
((data.remove(0) as u64) << 56) |
|
||||
((data.remove(0) as u64) << 48) |
|
||||
((data.remove(0) as u64) << 40) |
|
||||
((data.remove(0) as u64) << 32) |
|
||||
((data.remove(0) as u64) << 24) |
|
||||
((data.remove(0) as u64) << 16) |
|
||||
((data.remove(0) as u64) << 8) |
|
||||
(data.remove(0) as u64)
|
||||
}
|
||||
pub fn convert_u64(value: u64) -> Vec<u8> {
|
||||
vec![
|
||||
((value & 0xFF00000000000000) >> 56) as u8,
|
||||
((value & 0xFF000000000000) >> 48) as u8,
|
||||
((value & 0xFF0000000000) >> 40) as u8,
|
||||
((value & 0xFF00000000) >> 32) as u8,
|
||||
((value & 0xFF000000) >> 24) as u8,
|
||||
((value & 0xFF0000) >> 16) as u8,
|
||||
((value & 0xFF00) >> 8) as u8,
|
||||
(value & 0xFF) as u8,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn get_i64(data: &mut Vec<u8>) -> i64 {
|
||||
get_u64(data) as i64
|
||||
}
|
||||
pub fn convert_i64(value: i64) -> Vec<u8> {
|
||||
convert_u64(value as u64)
|
||||
}
|
||||
|
||||
pub fn get_f64(data: &mut Vec<u8>) -> f64 {
|
||||
get_u64(data) as f64
|
||||
}
|
||||
pub fn convert_f64(value: f64) -> Vec<u8> {
|
||||
convert_u64(value as u64)
|
||||
}
|
||||
|
||||
pub fn get_var_int(data: &mut Vec<u8>) -> i32 {
|
||||
let mut value: i32 = 0;
|
||||
let mut position: u32 = 0;
|
||||
|
||||
loop {
|
||||
let current_byte = stream.read_u8()
|
||||
.await
|
||||
.expect("Error reading from stream");
|
||||
let current_byte = data.remove(0);
|
||||
value |= ((current_byte & SEGMENT_BITS) as i32) << position;
|
||||
|
||||
if (current_byte & CONTINUE_BIT) == 0 {
|
||||
|
@ -38,52 +172,28 @@ pub async fn read_var_int(stream: &mut OwnedReadHalf) -> i32 {
|
|||
|
||||
value
|
||||
}
|
||||
|
||||
pub async fn write_var_int(stream: &mut OwnedWriteHalf, mut value: i32) {
|
||||
pub fn convert_var_int(mut value: i32) -> Vec<u8> {
|
||||
let mut data: Vec<u8> = vec![];
|
||||
loop {
|
||||
if (value & !(SEGMENT_BITS as i32)) == 0 {
|
||||
stream.write_u8(value as u8)
|
||||
.await.expect("Error writing to stream");
|
||||
return;
|
||||
data.append(&mut vec![value as u8]);
|
||||
return data;
|
||||
}
|
||||
|
||||
stream.write_u8((value & (SEGMENT_BITS as i32)) as u8 | CONTINUE_BIT)
|
||||
.await
|
||||
.expect("Error writing to stream");
|
||||
|
||||
value >>= 7;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_var_int_bytes(stream: &mut Vec<u8>, mut value: i32) {
|
||||
loop {
|
||||
if (value & !(SEGMENT_BITS as i32)) == 0 {
|
||||
stream.append(&mut vec![value as u8]);
|
||||
return;
|
||||
}
|
||||
stream.append(
|
||||
data.append(
|
||||
&mut vec![(value & (SEGMENT_BITS as i32)) as u8 | CONTINUE_BIT]);
|
||||
value >>= 7;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn read_string(stream: &mut OwnedReadHalf) -> String {
|
||||
let length = read_var_int(stream).await;
|
||||
pub fn get_string(data: &mut Vec<u8>) -> String {
|
||||
let length = get_var_int(data);
|
||||
let mut buffer = vec![0; length as usize];
|
||||
stream.read_exact(&mut buffer)
|
||||
.await.expect("Error reading string from stream");
|
||||
data.append(&mut buffer);
|
||||
String::from_utf8_lossy(&buffer).to_string()
|
||||
}
|
||||
|
||||
pub async fn write_string(stream: &mut OwnedWriteHalf, s: &str) {
|
||||
pub fn convert_string(s: &str) -> Vec<u8> {
|
||||
let length = s.len() as i32;
|
||||
write_var_int(stream, length).await;
|
||||
stream.write_all(s.as_bytes())
|
||||
.await.expect("Error writing string to stream");
|
||||
}
|
||||
|
||||
pub fn write_string_bytes(stream: &mut Vec<u8>, s: &str) {
|
||||
let length = s.len() as i32;
|
||||
write_var_int_bytes(stream, length);
|
||||
stream.append(&mut s.as_bytes().to_vec());
|
||||
let mut data = convert_var_int(length);
|
||||
data.append(&mut s.as_bytes().to_vec());
|
||||
data
|
||||
}
|
||||
|
|
|
@ -1,34 +1,32 @@
|
|||
// Yeahbut December 2023
|
||||
|
||||
use std::str::Bytes;
|
||||
|
||||
use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf};
|
||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||
use serde::Serialize;
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
use crate::mc_types;
|
||||
use crate::handshake;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StatusVersion {
|
||||
pub name: String,
|
||||
pub protocol: i32,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StatusPlayerInfo {
|
||||
pub name: String,
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StatusPlayers {
|
||||
pub max: i32,
|
||||
pub online: i32,
|
||||
pub sample: Vec<StatusPlayerInfo>
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StatusResponse {
|
||||
pub version: StatusVersion,
|
||||
pub description: mc_types::Chat,
|
||||
|
@ -93,7 +91,8 @@ pub async fn respond_status(
|
|||
Ok(json) => {
|
||||
client_writer.write_u8(0)
|
||||
.await.expect("Error writing to stream");
|
||||
mc_types::write_string(client_writer, &json).await;
|
||||
client_writer.write_all(&mc_types::convert_string(&json))
|
||||
.await.expect("Error writing to stream");
|
||||
},
|
||||
Err(err) => {
|
||||
eprintln!("Error serializing to JSON: {}", err);
|
||||
|
@ -119,23 +118,21 @@ pub async fn get_upstream_status(
|
|||
server_reader: &mut OwnedReadHalf,
|
||||
server_writer: &mut OwnedWriteHalf,
|
||||
) -> StatusResponse {
|
||||
StatusResponse {
|
||||
version: StatusVersion {
|
||||
name: "1.19.4".to_string(),
|
||||
protocol: 762,
|
||||
},
|
||||
description: mc_types::Chat {
|
||||
text: motd(),
|
||||
},
|
||||
players: StatusPlayers {
|
||||
max: 0,
|
||||
online: 0,
|
||||
sample: vec![],
|
||||
},
|
||||
favicon: favicon(),
|
||||
enforcesSecureChat: false,
|
||||
previewsChat: false,
|
||||
}
|
||||
handshake::write_handshake(server_writer, handshake::Handshake{
|
||||
protocol_version: mc_types::VERSION_PROTOCOL,
|
||||
server_address: "localhost".to_string(),
|
||||
server_port: 25565,
|
||||
next_state: 1,
|
||||
}).await;
|
||||
server_writer.write_u8(0).await.expect("Error writing to stream");
|
||||
|
||||
let mut data = mc_types::read_packet(server_reader).await;
|
||||
mc_types::get_u8(&mut data);
|
||||
let json = mc_types::get_string(&mut data);
|
||||
let status_response: StatusResponse = serde_json::from_str(&json)
|
||||
.expect("Error parsing JSON");
|
||||
|
||||
status_response
|
||||
}
|
||||
|
||||
pub async fn respond_legacy_status(client_writer: &mut OwnedWriteHalf) {
|
||||
|
|
Loading…
Reference in New Issue