reorganize file structure, define rpc protocol

This commit is contained in:
2026-05-10 18:13:04 +02:00
parent 5324cb8c29
commit 20ce06657d
12 changed files with 591 additions and 48 deletions

View File

@ -1,48 +1,34 @@
use tokio::net::{TcpListener, TcpStream};
mod client;
use client::Client;
use tokio::net::TcpListener;
use std::io;
pub mod varint;
pub mod handshake;
mod minecraft;
use minecraft::process_mc_socket;
async fn process_socket(stream: TcpStream) -> io::Result<()> {
let mut buf = vec![0 as u8; 1024];
let mut client = Client::create(stream);
loop {
client.in_stream.readable().await?;
match client.in_stream.try_read(&mut buf) {
Ok(n) => {
let _ = client.buffer_append((&buf[..n]).to_vec()).await;
if n == 0 {
break;
}
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e.into());
}
}
}
Ok(())
}
mod rpc;
use rpc::process_rpc_socket;
#[tokio::main(flavor = "current_thread")]
async fn main() -> io::Result<()> {
let listener = TcpListener::bind("0.0.0.0:25565").await?;
let mc_listener = TcpListener::bind("0.0.0.0:25565").await?;
let rpc_listener = TcpListener::bind("0.0.0.0:8080").await?;
loop {
let (socket, _) = listener.accept().await?;
tokio::spawn(async move {
if let Err(e) = process_socket(socket).await {
eprintln!("error: {:?}", e);
tokio::select! {
Ok((socket, _)) = mc_listener.accept() => {
tokio::spawn(async move {
if let Err(e) = process_mc_socket(socket).await {
eprintln!("mc error: {:?}", e);
}
});
}
});
Ok((socket, _)) = rpc_listener.accept() => {
tokio::spawn(async move {
if let Err(e) = process_rpc_socket(socket).await {
eprintln!("rpc error: {:?}", e);
}
});
}
}
}
}

View File

@ -1,8 +1,20 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* client.rs :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: tomoron <tomoron@student.42angouleme.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2026/05/07 17:23:09 by tomoron #+# #+# */
/* Updated: 2026/05/07 17:38:13 by tomoron ### ########.fr */
/* */
/* ************************************************************************** */
use json::object;
use tokio::net::TcpStream;
use std::collections::VecDeque;
use crate::handshake::Handshake;
use crate::varint::{varint_read, varint_write};
use crate::minecraft::handshake::Handshake;
use crate::minecraft::varint::{varint_read, varint_write};
pub struct Client {
pub in_stream: TcpStream,
@ -34,7 +46,11 @@ impl Client {
return Ok(());
}
let _ = self.buffer.append(&mut (data.clone()));
if self.buffer.len() + data.len() > 65536 {
return Err("buffer full".to_string());
}
let _ = self.buffer.extend(data);
if self.buffer[0] == 0 {
return Err("invalid packet".to_string());
@ -53,8 +69,8 @@ impl Client {
sent_data.extend(data);
match self.in_stream.try_write(sent_data.as_slice()) {
Ok(len) => { println!("sent {} bytes to the client", len); },
Err(e) => { println!("error while sending response {:?}", e); }
Err(e) => { eprintln!("error while sending response {:?}", e); },
_ => { }
}
}
@ -63,7 +79,6 @@ impl Client {
}
fn handle_packet(&mut self, mut packet: VecDeque<u8>) -> Result<(), String> {
println!("len : {}" , packet.len());
let packet_id = varint_read(&mut packet)?;
if self.handshake.is_none() {
if packet_id != 0 {
@ -83,17 +98,17 @@ impl Client {
Ok(())
}
fn status_intent_handle(&self, mut packet: &mut VecDeque<u8>, packet_id: i32) -> Result<(),String> {
fn status_intent_handle(&self, packet: &mut VecDeque<u8>, packet_id: i32) -> Result<(),String> {
let status_response = object! {
"version": {
"name": "1.21.6",
"name": "idk",
"protocol" : self.handshake.as_ref().unwrap().protocol_version,
},
"players": {
"max": 420,
"online": 69
},
"description": self.handshake.as_ref().unwrap().server_address.clone(),
"description": "§c".to_string() + &self.handshake.as_ref().unwrap().server_address.clone() + "§r:§a" + &self.handshake.as_ref().unwrap().server_port.to_string(),
};
if packet_id == 0 {
let mut response : Vec<u8> = vec![];

View File

@ -1,5 +1,5 @@
use std::collections::VecDeque;
use crate::varint::varint_read;
use crate::minecraft::varint::varint_read;
pub struct Handshake {
pub protocol_version: i32,

7
src/minecraft/mod.rs Normal file
View File

@ -0,0 +1,7 @@
pub mod varint;
pub mod handshake;
pub mod client;
mod socket;
pub use socket::process_mc_socket;

33
src/minecraft/socket.rs Normal file
View File

@ -0,0 +1,33 @@
use std::io::{self, Error};
use crate::minecraft::client::Client;
use tokio::net::TcpStream;
pub async fn process_mc_socket(stream: TcpStream) -> io::Result<()> {
let mut buf = vec![0 as u8; 1024];
let mut client = Client::create(stream);
loop {
client.in_stream.readable().await?;
match client.in_stream.try_read(&mut buf) {
Ok(n) => {
let result = client.buffer_append((&buf[..n]).to_vec()).await;
if let Err(error) = result {
eprintln!("mc error : {}", error);
break;
}
if n == 0 {
break;
}
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(e.into());
}
}
}
Ok(())
}

2
src/rpc/actions/mod.rs Normal file
View File

@ -0,0 +1,2 @@
mod ping;
pub use ping::ping;

5
src/rpc/actions/ping.rs Normal file
View File

@ -0,0 +1,5 @@
use json::object;
pub fn ping(data: json::object) -> json::object {
}

5
src/rpc/mod.rs Normal file
View File

@ -0,0 +1,5 @@
mod socket;
pub use socket::process_rpc_socket;
pub mod actions;

22
src/rpc/socket.rs Normal file
View File

@ -0,0 +1,22 @@
use std::io;
use tokio::net::TcpStream;
use crate::rpc::actions;
/*
* request_format :
* - "action" : 1 byte
* - length : 4 bytes (no more than 1MB)
* - json object : `length` bytes
* containing the parameters for this specific action (will vary
* depending on the action)
*
* response format :
* - response packet : may be more than one depending on the action
* - length: 4 bytes (no more than 1MB)
* - data: json object containing the response data
*/
pub async fn process_rpc_socket(stream: TcpStream) -> io::Result<()> {
panic!("not implemented");
}