feat: add abstraction for proxying logic + small fixes

and i dont wanna break this up into multiple commits.
This commit is contained in:
Tamipes 2025-12-10 19:25:59 +01:00
parent 5233570675
commit 2892cc3e7b
5 changed files with 204 additions and 160 deletions

View file

@ -1,7 +1,7 @@
use tokio::{io::AsyncWriteExt, net::TcpStream};
use crate::{
packets::{Packet, SendPacket},
packets::{serverbound::handshake::Handshake, Packet, SendPacket},
OpaqueError,
};
@ -43,3 +43,67 @@ pub async fn send_disconnect(
client_stream.flush().await.map_err(|e| e.to_string())?;
Ok(())
}
pub trait MinecraftServerHandle {
async fn start(&self) -> Result<(), OpaqueError>;
async fn stop(&self) -> Result<(), OpaqueError>;
async fn query_status(&self) -> Result<ServerDeploymentStatus, OpaqueError>;
fn get_internal_address(&self) -> Option<String>;
fn get_addr(&self) -> Option<String>;
async fn query_server_connectable(&self) -> Result<TcpStream, OpaqueError> {
let port = self
.get_internal_address()
.ok_or_else(|| "failed to get internal address from server")?;
let server_stream = TcpStream::connect(port)
.await
.map_err(|_| "failed to connect to minecraft server")?;
tracing::trace!(
"successfully connected to backend server; (connectibility check) {:?}",
server_stream.peer_addr()
);
Ok(server_stream)
}
/// Takes the already received packets, sends them to the server,
/// and proceeds to proxy the rest of the connection transparently.
async fn proxy_status(
&self,
handshake: &Handshake,
status_request: &Packet,
client_stream: &mut TcpStream,
server_stream: &mut TcpStream,
) -> Result<(), OpaqueError> {
handshake
.send_packet(server_stream)
.await
.map_err(|_| "failed to forward handshake packet to minecraft server")?;
status_request
.send_packet(server_stream)
.await
.map_err(|_| "failed to forward status request packet to minecraft server")?;
let data_amount = tokio::io::copy_bidirectional(client_stream, server_stream)
.await
.map_err(|e| {
format!(
"error during bidirectional copy between server and client; err={:?}",
e
)
})?;
tracing::trace!("data exchanged while proxying status: {:?}", data_amount);
Ok(())
}
}
pub trait MinecraftAPI<T> {
async fn query_server(&self, addr: String) -> Result<T, OpaqueError>;
}
pub enum ServerDeploymentStatus {
Connectable(TcpStream),
Starting,
PodOk,
Offline,
}