some changes refactor and wowowow shkebede lavadovski
This commit is contained in:
parent
df79d3c704
commit
e41c006060
1053
src/lib.rs
1053
src/lib.rs
File diff suppressed because it is too large
Load Diff
25
src/main.rs
25
src/main.rs
@ -8,7 +8,7 @@ use rust_mc_proto::DataBufferReader;
|
|||||||
use simplelog::{
|
use simplelog::{
|
||||||
ColorChoice, CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger,
|
ColorChoice, CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode, WriteLogger,
|
||||||
};
|
};
|
||||||
use std::{error::Error, fs::File};
|
use std::{error::Error, fs::File, sync::atomic::Ordering};
|
||||||
|
|
||||||
pub struct MyEventListener {}
|
pub struct MyEventListener {}
|
||||||
|
|
||||||
@ -22,10 +22,18 @@ impl EventListener for MyEventListener {
|
|||||||
RecvServerPacketEvent { packet, player } => {
|
RecvServerPacketEvent { packet, player } => {
|
||||||
// debug!("recv server packet event");
|
// debug!("recv server packet event");
|
||||||
}
|
}
|
||||||
SendServerPacketEvent { packet, player } => {
|
SendServerPacketEvent {
|
||||||
|
packet,
|
||||||
|
player,
|
||||||
|
cancel,
|
||||||
|
} => {
|
||||||
// debug!("send server packet event");
|
// debug!("send server packet event");
|
||||||
}
|
}
|
||||||
SendClientPacketEvent { packet, player } => {
|
SendClientPacketEvent {
|
||||||
|
packet,
|
||||||
|
player,
|
||||||
|
cancel,
|
||||||
|
} => {
|
||||||
// debug!("send client packet event");
|
// debug!("send client packet event");
|
||||||
}
|
}
|
||||||
RecvClientPacketEvent { packet, player } => {
|
RecvClientPacketEvent { packet, player } => {
|
||||||
@ -35,6 +43,7 @@ impl EventListener for MyEventListener {
|
|||||||
let command = packet.read_string()?;
|
let command = packet.read_string()?;
|
||||||
|
|
||||||
if command == "reconnect" {
|
if command == "reconnect" {
|
||||||
|
println!("reconnect wow");
|
||||||
ProxyPlayer::reconnect(player.clone(), this.clone(), "localhost", 25565)
|
ProxyPlayer::reconnect(player.clone(), this.clone(), "localhost", 25565)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
@ -43,10 +52,14 @@ impl EventListener for MyEventListener {
|
|||||||
PlayerConnectedEvent { player } => {
|
PlayerConnectedEvent { player } => {
|
||||||
debug!("player connected");
|
debug!("player connected");
|
||||||
}
|
}
|
||||||
PlayerConnectingServerEvent { player, server } => {
|
PlayerConnectingServerEvent {
|
||||||
|
player,
|
||||||
|
server,
|
||||||
|
cancel,
|
||||||
|
} => {
|
||||||
debug!("player connecting server");
|
debug!("player connecting server");
|
||||||
}
|
}
|
||||||
PlayerConnectingIPEvent { player, ip } => {
|
PlayerConnectingIPEvent { player, ip, cancel } => {
|
||||||
debug!("player connecting ip");
|
debug!("player connecting ip");
|
||||||
}
|
}
|
||||||
PlayerDisconnectedEvent { player } => {
|
PlayerDisconnectedEvent { player } => {
|
||||||
@ -57,8 +70,10 @@ impl EventListener for MyEventListener {
|
|||||||
client_address,
|
client_address,
|
||||||
server_address,
|
server_address,
|
||||||
server_port,
|
server_port,
|
||||||
|
cancel,
|
||||||
} => {
|
} => {
|
||||||
debug!("status request");
|
debug!("status request");
|
||||||
|
*status = String::from("123123");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
187
src/meexprox/config.rs
Normal file
187
src/meexprox/config.rs
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
use super::ProxyError;
|
||||||
|
use serde_yml::Value;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ProxyServer {
|
||||||
|
name: String,
|
||||||
|
host: String,
|
||||||
|
forced_host: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProxyServer {
|
||||||
|
pub fn new(name: String, host: String, forced_host: Option<String>) -> ProxyServer {
|
||||||
|
ProxyServer {
|
||||||
|
name,
|
||||||
|
host,
|
||||||
|
forced_host,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &str {
|
||||||
|
&self.name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn host(&self) -> &str {
|
||||||
|
&self.host
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn forced_host(&self) -> Option<&String> {
|
||||||
|
self.forced_host.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! extract_string {
|
||||||
|
($data:expr, $key:expr) => {
|
||||||
|
match $data.get(&Value::String($key.to_string())) {
|
||||||
|
Some(Value::String(val)) => Some(val.clone()),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum PlayerForwarding {
|
||||||
|
Handshake,
|
||||||
|
Disabled,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ProxyConfig {
|
||||||
|
host: String,
|
||||||
|
servers: Vec<ProxyServer>,
|
||||||
|
default_server: Option<ProxyServer>,
|
||||||
|
talk_host: Option<String>,
|
||||||
|
talk_secret: Option<String>,
|
||||||
|
player_forwarding: PlayerForwarding,
|
||||||
|
no_pf_for_ip_connect: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProxyConfig {
|
||||||
|
pub fn new(
|
||||||
|
host: String,
|
||||||
|
servers: Vec<ProxyServer>,
|
||||||
|
default_server: Option<ProxyServer>,
|
||||||
|
talk_host: Option<String>,
|
||||||
|
talk_secret: Option<String>,
|
||||||
|
player_forwarding: PlayerForwarding,
|
||||||
|
no_pf_for_ip_connect: bool,
|
||||||
|
) -> ProxyConfig {
|
||||||
|
ProxyConfig {
|
||||||
|
host,
|
||||||
|
servers,
|
||||||
|
default_server,
|
||||||
|
talk_host,
|
||||||
|
talk_secret,
|
||||||
|
player_forwarding,
|
||||||
|
no_pf_for_ip_connect,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn host(&self) -> &str {
|
||||||
|
&self.host
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn servers(&self) -> &Vec<ProxyServer> {
|
||||||
|
&self.servers
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn talk_host(&self) -> Option<&String> {
|
||||||
|
self.talk_host.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn talk_secret(&self) -> Option<&String> {
|
||||||
|
self.talk_secret.as_ref()
|
||||||
|
}
|
||||||
|
pub fn default_server(&self) -> Option<&ProxyServer> {
|
||||||
|
self.default_server.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn player_forwarding(&self) -> &PlayerForwarding {
|
||||||
|
&self.player_forwarding
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn no_pf_for_ip_connect(&self) -> bool {
|
||||||
|
self.no_pf_for_ip_connect
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load(path: &str) -> Result<ProxyConfig, Box<dyn std::error::Error>> {
|
||||||
|
let data = serde_yml::from_str::<Value>(&fs::read_to_string(path)?)?;
|
||||||
|
let data = data.as_mapping().ok_or(ProxyError::ConfigParse)?;
|
||||||
|
|
||||||
|
let host = extract_string!(data, "host").ok_or(ProxyError::ConfigParse)?;
|
||||||
|
let talk_host = extract_string!(data, "talk_host");
|
||||||
|
let talk_secret = extract_string!(data, "talk_secret");
|
||||||
|
let player_forwarding = match extract_string!(data, "player_forwarding") {
|
||||||
|
Some(pf) => match pf.as_str() {
|
||||||
|
"disabled" => PlayerForwarding::Disabled,
|
||||||
|
_ => PlayerForwarding::Handshake,
|
||||||
|
},
|
||||||
|
_ => PlayerForwarding::Handshake,
|
||||||
|
};
|
||||||
|
let no_pf_for_ip_connect = data
|
||||||
|
.get(Value::String("no_pf_for_ip_connect".to_string()))
|
||||||
|
.or(Some(&Value::Bool(true)))
|
||||||
|
.ok_or(ProxyError::ConfigParse)?
|
||||||
|
.as_bool()
|
||||||
|
.ok_or(ProxyError::ConfigParse)?;
|
||||||
|
|
||||||
|
let mut servers = Vec::new();
|
||||||
|
if let Some(servers_map) = data
|
||||||
|
.get(&Value::String("servers".to_string()))
|
||||||
|
.and_then(Value::as_mapping)
|
||||||
|
{
|
||||||
|
for (name, addr) in servers_map {
|
||||||
|
if let (Value::String(name), Value::String(addr)) = (name, addr) {
|
||||||
|
servers.push(ProxyServer::new(name.clone(), addr.clone(), None));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(forced_hosts_map) = data
|
||||||
|
.get(&Value::String("forced_hosts".to_string()))
|
||||||
|
.and_then(Value::as_mapping)
|
||||||
|
{
|
||||||
|
for (name, host) in forced_hosts_map {
|
||||||
|
if let (Value::String(name), Value::String(host)) = (name, host) {
|
||||||
|
if let Some(server) = servers.iter_mut().find(|s| s.name == *name) {
|
||||||
|
server.forced_host = Some(host.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let default_server = extract_string!(data, "default_server")
|
||||||
|
.and_then(|ds| servers.iter().find(|s| s.name == ds).cloned());
|
||||||
|
|
||||||
|
Ok(ProxyConfig::new(
|
||||||
|
host,
|
||||||
|
servers,
|
||||||
|
default_server,
|
||||||
|
talk_host,
|
||||||
|
talk_secret,
|
||||||
|
player_forwarding,
|
||||||
|
no_pf_for_ip_connect,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_server_by_name(&self, name: &str) -> Option<ProxyServer> {
|
||||||
|
for server in &self.servers {
|
||||||
|
if &server.name == name {
|
||||||
|
return Some(server.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_server_by_forced_host(&self, forced_host: &str) -> Option<ProxyServer> {
|
||||||
|
for server in &self.servers {
|
||||||
|
if let Some(server_forced_host) = &server.forced_host {
|
||||||
|
if server_forced_host == forced_host {
|
||||||
|
return Some(server.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
14
src/meexprox/error.rs
Normal file
14
src/meexprox/error.rs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ProxyError {
|
||||||
|
ConfigParse,
|
||||||
|
ServerConnect,
|
||||||
|
EventChanged,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ProxyError {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "({:?})", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::error::Error for ProxyError {}
|
230
src/meexprox/event.rs
Normal file
230
src/meexprox/event.rs
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
use super::{MeexProx, MeexProxMutex, PlayerMutex, ProxyServer};
|
||||||
|
use rust_mc_proto::Packet;
|
||||||
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
net::SocketAddr,
|
||||||
|
sync::atomic::{AtomicBool, Ordering},
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum ProxyEvent {
|
||||||
|
/// client <- proxy <- server \
|
||||||
|
/// | \
|
||||||
|
/// RecvServerPacketEvent
|
||||||
|
RecvServerPacketEvent {
|
||||||
|
packet: Packet,
|
||||||
|
player: PlayerMutex,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// client -> proxy -> server \
|
||||||
|
/// | \
|
||||||
|
/// SendServerPacketEvent
|
||||||
|
SendServerPacketEvent {
|
||||||
|
packet: Packet,
|
||||||
|
player: PlayerMutex,
|
||||||
|
cancel: AtomicBool,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// client <- proxy <- server \
|
||||||
|
/// | \
|
||||||
|
/// SendClientPacketEvent
|
||||||
|
SendClientPacketEvent {
|
||||||
|
packet: Packet,
|
||||||
|
player: PlayerMutex,
|
||||||
|
cancel: AtomicBool,
|
||||||
|
},
|
||||||
|
|
||||||
|
/// client -> proxy -> server \
|
||||||
|
/// | \
|
||||||
|
/// RecvClientPacketEvent
|
||||||
|
RecvClientPacketEvent {
|
||||||
|
packet: Packet,
|
||||||
|
player: PlayerMutex,
|
||||||
|
},
|
||||||
|
|
||||||
|
PlayerConnectedEvent {
|
||||||
|
player: PlayerMutex,
|
||||||
|
},
|
||||||
|
|
||||||
|
PlayerDisconnectedEvent {
|
||||||
|
player: PlayerMutex,
|
||||||
|
},
|
||||||
|
|
||||||
|
PlayerConnectingServerEvent {
|
||||||
|
player: PlayerMutex,
|
||||||
|
server: ProxyServer,
|
||||||
|
cancel: AtomicBool,
|
||||||
|
},
|
||||||
|
|
||||||
|
PlayerConnectingIPEvent {
|
||||||
|
player: PlayerMutex,
|
||||||
|
ip: String,
|
||||||
|
cancel: AtomicBool,
|
||||||
|
},
|
||||||
|
|
||||||
|
StatusRequestEvent {
|
||||||
|
status: String,
|
||||||
|
client_address: SocketAddr,
|
||||||
|
server_address: String,
|
||||||
|
server_port: u16,
|
||||||
|
cancel: AtomicBool,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProxyEvent {
|
||||||
|
pub fn status_request(
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
status: String,
|
||||||
|
client_address: SocketAddr,
|
||||||
|
server_address: String,
|
||||||
|
server_port: u16,
|
||||||
|
) -> (String, bool) {
|
||||||
|
let ProxyEvent::StatusRequestEvent {
|
||||||
|
status,
|
||||||
|
client_address: _,
|
||||||
|
server_address: _,
|
||||||
|
server_port: _,
|
||||||
|
cancel,
|
||||||
|
} = MeexProx::trigger_event(
|
||||||
|
meexprox,
|
||||||
|
ProxyEvent::StatusRequestEvent {
|
||||||
|
status: status.clone(),
|
||||||
|
client_address,
|
||||||
|
server_address,
|
||||||
|
server_port,
|
||||||
|
cancel: AtomicBool::from(false),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else {
|
||||||
|
return (status, false);
|
||||||
|
};
|
||||||
|
(status, cancel.load(Ordering::Relaxed))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn player_connecting_server(
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
player: PlayerMutex,
|
||||||
|
server: ProxyServer,
|
||||||
|
) -> (ProxyServer, bool) {
|
||||||
|
let ProxyEvent::PlayerConnectingServerEvent {
|
||||||
|
server,
|
||||||
|
player: _,
|
||||||
|
cancel,
|
||||||
|
} = MeexProx::trigger_event(
|
||||||
|
meexprox,
|
||||||
|
ProxyEvent::PlayerConnectingServerEvent {
|
||||||
|
server: server.clone(),
|
||||||
|
player,
|
||||||
|
cancel: AtomicBool::from(false),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else {
|
||||||
|
return (server, false);
|
||||||
|
};
|
||||||
|
(server, cancel.load(Ordering::Relaxed))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn player_disconnected(meexprox: MeexProxMutex, player: PlayerMutex) -> () {
|
||||||
|
let ProxyEvent::PlayerDisconnectedEvent { player: _ } =
|
||||||
|
MeexProx::trigger_event(meexprox, ProxyEvent::PlayerDisconnectedEvent { player })
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn player_connected(meexprox: MeexProxMutex, player: PlayerMutex) -> () {
|
||||||
|
let ProxyEvent::PlayerConnectedEvent { player: _ } =
|
||||||
|
MeexProx::trigger_event(meexprox, ProxyEvent::PlayerConnectedEvent { player })
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_client_packet(
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
packet: Packet,
|
||||||
|
player: PlayerMutex,
|
||||||
|
) -> (Packet, bool) {
|
||||||
|
let ProxyEvent::SendClientPacketEvent {
|
||||||
|
packet,
|
||||||
|
player: _,
|
||||||
|
cancel,
|
||||||
|
} = MeexProx::trigger_event(
|
||||||
|
meexprox,
|
||||||
|
ProxyEvent::SendClientPacketEvent {
|
||||||
|
packet: packet.clone(),
|
||||||
|
player,
|
||||||
|
cancel: AtomicBool::from(false),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else {
|
||||||
|
return (packet, false);
|
||||||
|
};
|
||||||
|
(packet, cancel.load(Ordering::Relaxed))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_server_packet(
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
packet: Packet,
|
||||||
|
player: PlayerMutex,
|
||||||
|
) -> (Packet, bool) {
|
||||||
|
let ProxyEvent::SendServerPacketEvent {
|
||||||
|
packet,
|
||||||
|
player: _,
|
||||||
|
cancel,
|
||||||
|
} = MeexProx::trigger_event(
|
||||||
|
meexprox,
|
||||||
|
ProxyEvent::SendServerPacketEvent {
|
||||||
|
packet: packet.clone(),
|
||||||
|
player,
|
||||||
|
cancel: AtomicBool::from(false),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
else {
|
||||||
|
return (packet, false);
|
||||||
|
};
|
||||||
|
(packet, cancel.load(Ordering::Relaxed))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recv_server_packet(
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
packet: Packet,
|
||||||
|
player: PlayerMutex,
|
||||||
|
) -> Packet {
|
||||||
|
let ProxyEvent::RecvServerPacketEvent { packet, player: _ } = MeexProx::trigger_event(
|
||||||
|
meexprox,
|
||||||
|
ProxyEvent::RecvServerPacketEvent {
|
||||||
|
packet: packet.clone(),
|
||||||
|
player,
|
||||||
|
},
|
||||||
|
) else {
|
||||||
|
return packet;
|
||||||
|
};
|
||||||
|
packet
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn recv_client_packet(
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
packet: Packet,
|
||||||
|
player: PlayerMutex,
|
||||||
|
) -> Packet {
|
||||||
|
let ProxyEvent::RecvClientPacketEvent { packet, player: _ } = MeexProx::trigger_event(
|
||||||
|
meexprox,
|
||||||
|
ProxyEvent::RecvClientPacketEvent {
|
||||||
|
packet: packet.clone(),
|
||||||
|
player,
|
||||||
|
},
|
||||||
|
) else {
|
||||||
|
return packet;
|
||||||
|
};
|
||||||
|
packet
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait EventListener {
|
||||||
|
fn on_event(
|
||||||
|
&mut self,
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
event: &mut ProxyEvent,
|
||||||
|
) -> Result<(), Box<dyn Error>>;
|
||||||
|
}
|
665
src/meexprox/meexprox.rs
Normal file
665
src/meexprox/meexprox.rs
Normal file
@ -0,0 +1,665 @@
|
|||||||
|
use super::{EventListener, PlayerForwarding, ProxyConfig, ProxyError, ProxyEvent, ProxyServer};
|
||||||
|
use derivative::Derivative;
|
||||||
|
use log::info;
|
||||||
|
use rust_mc_proto::{
|
||||||
|
DataBufferReader, DataBufferWriter, MinecraftConnection, Packet, ProtocolError, Zigzag,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
error::Error,
|
||||||
|
net::{SocketAddr, TcpListener, TcpStream},
|
||||||
|
sync::{
|
||||||
|
atomic::{AtomicUsize, Ordering},
|
||||||
|
Arc, Mutex,
|
||||||
|
},
|
||||||
|
thread,
|
||||||
|
};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[derive(Derivative)]
|
||||||
|
#[derivative(Debug)]
|
||||||
|
pub struct ProxyPlayer {
|
||||||
|
#[derivative(Debug = "ignore")]
|
||||||
|
client_conn: MinecraftConnection<TcpStream>,
|
||||||
|
#[derivative(Debug = "ignore")]
|
||||||
|
server_conn: MinecraftConnection<TcpStream>,
|
||||||
|
name: Option<String>,
|
||||||
|
uuid: Option<Uuid>,
|
||||||
|
protocol_version: u16,
|
||||||
|
server: Option<ProxyServer>,
|
||||||
|
shared_secret: Option<Vec<u8>>,
|
||||||
|
verify_token: Option<Vec<u8>>,
|
||||||
|
connection_id: Arc<AtomicUsize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ProxyPlayer {
|
||||||
|
pub fn new(
|
||||||
|
client_conn: MinecraftConnection<TcpStream>,
|
||||||
|
server_conn: MinecraftConnection<TcpStream>,
|
||||||
|
name: Option<String>,
|
||||||
|
uuid: Option<Uuid>,
|
||||||
|
protocol_version: u16,
|
||||||
|
server: Option<ProxyServer>,
|
||||||
|
shared_secret: Option<Vec<u8>>,
|
||||||
|
verify_token: Option<Vec<u8>>,
|
||||||
|
connection_id: Arc<AtomicUsize>,
|
||||||
|
) -> ProxyPlayer {
|
||||||
|
ProxyPlayer {
|
||||||
|
client_conn,
|
||||||
|
server_conn,
|
||||||
|
name,
|
||||||
|
uuid,
|
||||||
|
protocol_version,
|
||||||
|
server,
|
||||||
|
shared_secret,
|
||||||
|
verify_token,
|
||||||
|
connection_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn client_conn(&self) -> &MinecraftConnection<TcpStream> {
|
||||||
|
&self.client_conn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn server_conn(&self) -> &MinecraftConnection<TcpStream> {
|
||||||
|
&self.client_conn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn client_conn_mut(&mut self) -> &mut MinecraftConnection<TcpStream> {
|
||||||
|
&mut self.client_conn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn server_conn_mut(&mut self) -> &mut MinecraftConnection<TcpStream> {
|
||||||
|
&mut self.client_conn
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> Option<&String> {
|
||||||
|
self.name.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn uuid(&self) -> Option<&Uuid> {
|
||||||
|
self.uuid.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn protocol_version(&self) -> u16 {
|
||||||
|
self.protocol_version
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn server(&self) -> Option<&ProxyServer> {
|
||||||
|
self.server.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shared_secret(&self) -> Option<&Vec<u8>> {
|
||||||
|
self.shared_secret.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn verify_token(&self) -> Option<&Vec<u8>> {
|
||||||
|
self.verify_token.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn connection_id(&self) -> Arc<AtomicUsize> {
|
||||||
|
self.connection_id.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn connect_to_ip(
|
||||||
|
this: PlayerMutex,
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
ip: &str,
|
||||||
|
server_address: &str,
|
||||||
|
server_port: u16,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
this.lock()
|
||||||
|
.unwrap()
|
||||||
|
.connection_id
|
||||||
|
.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
|
this.lock().unwrap().server_conn.close();
|
||||||
|
this.lock().unwrap().server_conn = MinecraftConnection::connect(ip)?;
|
||||||
|
|
||||||
|
thread::spawn({
|
||||||
|
let player_forwarding = meexprox.lock().unwrap().config.player_forwarding().clone();
|
||||||
|
let server_address = server_address.to_string();
|
||||||
|
|
||||||
|
move || {
|
||||||
|
let _ = ProxyPlayer::connect(
|
||||||
|
this,
|
||||||
|
meexprox,
|
||||||
|
player_forwarding,
|
||||||
|
&server_address,
|
||||||
|
server_port,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn connect_to_server(
|
||||||
|
this: PlayerMutex,
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
server: ProxyServer,
|
||||||
|
server_address: &str,
|
||||||
|
server_port: u16,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
this.lock()
|
||||||
|
.unwrap()
|
||||||
|
.connection_id
|
||||||
|
.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
|
this.lock().unwrap().server = Some(server.clone());
|
||||||
|
|
||||||
|
this.lock().unwrap().server_conn.close();
|
||||||
|
this.lock().unwrap().server_conn = MinecraftConnection::connect(server.host())?;
|
||||||
|
|
||||||
|
thread::spawn({
|
||||||
|
let player_forwarding = meexprox.lock().unwrap().config.player_forwarding().clone();
|
||||||
|
let server_address = server_address.to_string();
|
||||||
|
|
||||||
|
move || {
|
||||||
|
let _ = ProxyPlayer::connect(
|
||||||
|
this,
|
||||||
|
meexprox,
|
||||||
|
player_forwarding,
|
||||||
|
&server_address,
|
||||||
|
server_port,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reconnect(
|
||||||
|
this: PlayerMutex,
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
server_address: &str,
|
||||||
|
server_port: u16,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
this.lock()
|
||||||
|
.unwrap()
|
||||||
|
.connection_id
|
||||||
|
.fetch_add(1, Ordering::Relaxed);
|
||||||
|
|
||||||
|
this.lock().unwrap().server_conn.close();
|
||||||
|
this.lock().unwrap().server_conn =
|
||||||
|
MinecraftConnection::connect(this.lock().unwrap().server().unwrap().host())?;
|
||||||
|
|
||||||
|
thread::spawn({
|
||||||
|
let player_forwarding = meexprox.lock().unwrap().config.player_forwarding().clone();
|
||||||
|
let server_address = server_address.to_string();
|
||||||
|
|
||||||
|
move || {
|
||||||
|
let _ = ProxyPlayer::connect(
|
||||||
|
this,
|
||||||
|
meexprox,
|
||||||
|
player_forwarding,
|
||||||
|
&server_address,
|
||||||
|
server_port,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_handshake(
|
||||||
|
this: PlayerMutex,
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
player_forwarding: PlayerForwarding,
|
||||||
|
addr: SocketAddr,
|
||||||
|
server_address: &str,
|
||||||
|
server_port: u16,
|
||||||
|
) -> Result<(), ProtocolError> {
|
||||||
|
let protocol_version = this.lock().unwrap().protocol_version;
|
||||||
|
|
||||||
|
let packet = Packet::build(0x00, move |packet| {
|
||||||
|
packet.write_u16_varint(protocol_version)?;
|
||||||
|
packet.write_string(&server_address)?;
|
||||||
|
packet.write_unsigned_short(server_port)?;
|
||||||
|
packet.write_u8_varint(2)?;
|
||||||
|
|
||||||
|
if let PlayerForwarding::Handshake = player_forwarding {
|
||||||
|
if let SocketAddr::V4(addr) = addr {
|
||||||
|
packet.write_boolean(false)?; // is ipv6
|
||||||
|
packet.write_unsigned_short(addr.port())?; // port
|
||||||
|
packet.write_bytes(&addr.ip().octets())?; // octets
|
||||||
|
} else if let SocketAddr::V6(addr) = addr {
|
||||||
|
packet.write_boolean(true)?;
|
||||||
|
packet.write_unsigned_short(addr.port())?;
|
||||||
|
packet.write_bytes(&addr.ip().octets())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let (packet, cancel) = ProxyEvent::send_server_packet(meexprox, packet, this.clone());
|
||||||
|
|
||||||
|
if !cancel {
|
||||||
|
this.lock().unwrap().server_conn.write_packet(&packet)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_login(this: PlayerMutex, meexprox: MeexProxMutex) -> Result<(), ProtocolError> {
|
||||||
|
if let Some(player_name) = this.lock().unwrap().name.as_ref() {
|
||||||
|
if let Some(player_uuid) = this.lock().unwrap().uuid.as_ref() {
|
||||||
|
let packet = Packet::build(0x00, move |packet| {
|
||||||
|
packet.write_string(&player_name)?;
|
||||||
|
packet.write_uuid(&player_uuid)?;
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let (packet, cancel) =
|
||||||
|
ProxyEvent::send_server_packet(meexprox, packet, this.clone());
|
||||||
|
|
||||||
|
if !cancel {
|
||||||
|
this.lock().unwrap().server_conn.write_packet(&packet)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn connect(
|
||||||
|
this: PlayerMutex,
|
||||||
|
meexprox: MeexProxMutex,
|
||||||
|
player_forwarding: PlayerForwarding,
|
||||||
|
server_address: &str,
|
||||||
|
server_port: u16,
|
||||||
|
logged: bool,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
|
let mut client_conn = this.lock().unwrap().client_conn.try_clone().unwrap();
|
||||||
|
let mut server_conn = this.lock().unwrap().server_conn.try_clone().unwrap();
|
||||||
|
|
||||||
|
let server = this.lock().unwrap().server.clone();
|
||||||
|
|
||||||
|
let addr = client_conn.get_ref().peer_addr().unwrap();
|
||||||
|
let Some(name) = this.lock().unwrap().name.clone() else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
let server_config = meexprox.lock().unwrap().config.clone();
|
||||||
|
|
||||||
|
let atomic_connection_id = this.lock().unwrap().connection_id.clone();
|
||||||
|
let connection_id = this.lock().unwrap().connection_id.load(Ordering::Relaxed);
|
||||||
|
|
||||||
|
if !logged {
|
||||||
|
ProxyPlayer::send_handshake(
|
||||||
|
this.clone(),
|
||||||
|
meexprox.clone(),
|
||||||
|
player_forwarding,
|
||||||
|
addr,
|
||||||
|
server_address,
|
||||||
|
server_port,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
ProxyPlayer::send_login(this.clone(), meexprox.clone())?;
|
||||||
|
|
||||||
|
while let Ok(mut packet) = server_conn.read_packet() {
|
||||||
|
if packet.id() == 0x01 {
|
||||||
|
if let Some(shared_secret) = this.lock().unwrap().shared_secret.clone() {
|
||||||
|
if let Some(verify_token) = this.lock().unwrap().verify_token.clone() {
|
||||||
|
let mut enc_response = Packet::empty(0x01);
|
||||||
|
|
||||||
|
enc_response.write_usize_varint(shared_secret.len())?;
|
||||||
|
enc_response.write_bytes(&shared_secret)?;
|
||||||
|
enc_response.write_usize_varint(shared_secret.len())?;
|
||||||
|
enc_response.write_bytes(&verify_token)?;
|
||||||
|
|
||||||
|
let (enc_response, cancel) = ProxyEvent::send_server_packet(
|
||||||
|
meexprox.clone(),
|
||||||
|
enc_response,
|
||||||
|
this.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if !cancel {
|
||||||
|
server_conn.write_packet(&enc_response)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if packet.id() == 0x03 {
|
||||||
|
let threshold = packet.read_isize_varint()?;
|
||||||
|
|
||||||
|
if threshold >= 0 {
|
||||||
|
let threshold = threshold.zigzag();
|
||||||
|
|
||||||
|
server_conn.set_compression(Some(threshold));
|
||||||
|
client_conn.set_compression(Some(threshold));
|
||||||
|
} else {
|
||||||
|
server_conn.set_compression(None);
|
||||||
|
client_conn.set_compression(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if packet.id() == 0x02 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let login_ack = Packet::empty(0x03);
|
||||||
|
|
||||||
|
let (login_ack, cancel) =
|
||||||
|
ProxyEvent::send_server_packet(meexprox.clone(), login_ack, this.clone());
|
||||||
|
|
||||||
|
if !cancel {
|
||||||
|
server_conn.write_packet(&login_ack)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
thread::spawn({
|
||||||
|
let mut client_conn = client_conn.try_clone().unwrap();
|
||||||
|
let mut server_conn = server_conn.try_clone().unwrap();
|
||||||
|
|
||||||
|
let this = this.clone();
|
||||||
|
let meexprox = meexprox.clone();
|
||||||
|
let name = name.clone();
|
||||||
|
let atomic_connection_id = atomic_connection_id.clone();
|
||||||
|
|
||||||
|
move || {
|
||||||
|
let _ = || -> Result<(), ProtocolError> {
|
||||||
|
while atomic_connection_id.load(Ordering::Relaxed) == connection_id {
|
||||||
|
let packet = match client_conn.read_packet() {
|
||||||
|
Ok(packet) => packet,
|
||||||
|
Err(_) => break,
|
||||||
|
};
|
||||||
|
|
||||||
|
let packet =
|
||||||
|
ProxyEvent::recv_client_packet(meexprox.clone(), packet, this.clone());
|
||||||
|
|
||||||
|
let (packet, cancel) =
|
||||||
|
ProxyEvent::send_server_packet(meexprox.clone(), packet, this.clone());
|
||||||
|
|
||||||
|
if !cancel {
|
||||||
|
server_conn.write_packet(&packet)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}();
|
||||||
|
|
||||||
|
if atomic_connection_id.load(Ordering::Relaxed) == connection_id {
|
||||||
|
if meexprox.lock().unwrap().remove_player(this.clone()) {
|
||||||
|
info!("{} disconnected player {}", addr.to_string(), name);
|
||||||
|
ProxyEvent::player_disconnected(meexprox.clone(), this.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let _ = || -> Result<(), ProtocolError> {
|
||||||
|
while atomic_connection_id.load(Ordering::Relaxed) == connection_id {
|
||||||
|
let packet = match server_conn.read_packet() {
|
||||||
|
Ok(packet) => packet,
|
||||||
|
Err(_) => break,
|
||||||
|
};
|
||||||
|
|
||||||
|
let packet = ProxyEvent::recv_server_packet(meexprox.clone(), packet, this.clone());
|
||||||
|
|
||||||
|
let (packet, cancel) =
|
||||||
|
ProxyEvent::send_client_packet(meexprox.clone(), packet, this.clone());
|
||||||
|
|
||||||
|
if !cancel {
|
||||||
|
client_conn.write_packet(&packet)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}();
|
||||||
|
|
||||||
|
if atomic_connection_id.load(Ordering::Relaxed) == connection_id {
|
||||||
|
if meexprox.lock().unwrap().remove_player(this.clone()) {
|
||||||
|
info!("{} disconnected player {}", addr.to_string(), name);
|
||||||
|
ProxyEvent::player_disconnected(meexprox.clone(), this.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MeexProx {
|
||||||
|
config: ProxyConfig,
|
||||||
|
players: Vec<PlayerMutex>,
|
||||||
|
event_listeners: Vec<Box<dyn EventListener + Send + Sync>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MeexProx {
|
||||||
|
pub fn new(config: ProxyConfig) -> MeexProx {
|
||||||
|
MeexProx {
|
||||||
|
config,
|
||||||
|
players: Vec::new(),
|
||||||
|
event_listeners: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_event_listener(&mut self, event_listener: Box<dyn EventListener + Send + Sync>) {
|
||||||
|
self.event_listeners.push(event_listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn trigger_event(this: MeexProxMutex, mut event: ProxyEvent) -> ProxyEvent {
|
||||||
|
for event_listener in &mut this.lock().unwrap().event_listeners {
|
||||||
|
let _ = event_listener.on_event(this.clone(), &mut event);
|
||||||
|
}
|
||||||
|
event
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_player(&self, uuid: Uuid) -> Option<PlayerMutex> {
|
||||||
|
for player in &self.players {
|
||||||
|
if let Some(player_uuid) = player.lock().unwrap().uuid {
|
||||||
|
if player_uuid == uuid {
|
||||||
|
return Some(player.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_player(&mut self, player: PlayerMutex) -> bool {
|
||||||
|
match self.players.iter().position(|x| Arc::ptr_eq(x, &player)) {
|
||||||
|
Some(i) => {
|
||||||
|
self.players.remove(i);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
None => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn accept_client(this: MeexProxMutex, stream: TcpStream) -> Result<(), Box<dyn Error>> {
|
||||||
|
let Ok(addr) = stream.peer_addr() else {
|
||||||
|
return Ok(());
|
||||||
|
};
|
||||||
|
|
||||||
|
let server_config = this.lock().unwrap().config.clone();
|
||||||
|
|
||||||
|
let mut client_conn = MinecraftConnection::new(stream);
|
||||||
|
|
||||||
|
let mut handshake = client_conn.read_packet()?;
|
||||||
|
|
||||||
|
if handshake.id() != 0x00 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let protocol_version = handshake.read_u16_varint()?;
|
||||||
|
let server_address = handshake.read_string()?;
|
||||||
|
let server_port = handshake.read_unsigned_short()?;
|
||||||
|
let next_state = handshake.read_u8_varint()?;
|
||||||
|
|
||||||
|
let server = server_config
|
||||||
|
.get_server_by_forced_host(&server_address)
|
||||||
|
.or(server_config.default_server().cloned())
|
||||||
|
.ok_or(ProxyError::ConfigParse)?;
|
||||||
|
|
||||||
|
let mut server_conn = MinecraftConnection::connect(&server.host())?;
|
||||||
|
|
||||||
|
let handshake = Packet::build(0x00, |handshake| {
|
||||||
|
handshake.write_u16_varint(protocol_version)?;
|
||||||
|
handshake.write_string(&server_address)?;
|
||||||
|
handshake.write_unsigned_short(server_port)?;
|
||||||
|
handshake.write_u8_varint(next_state)?;
|
||||||
|
|
||||||
|
if let PlayerForwarding::Handshake = server_config.player_forwarding() {
|
||||||
|
if let SocketAddr::V4(addr) = addr {
|
||||||
|
handshake.write_boolean(false)?; // is ipv6
|
||||||
|
handshake.write_unsigned_short(addr.port())?; // port
|
||||||
|
handshake.write_bytes(&addr.ip().octets())?; // octets
|
||||||
|
} else if let SocketAddr::V6(addr) = addr {
|
||||||
|
handshake.write_boolean(true)?;
|
||||||
|
handshake.write_unsigned_short(addr.port())?;
|
||||||
|
handshake.write_bytes(&addr.ip().octets())?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
})?;
|
||||||
|
|
||||||
|
server_conn.write_packet(&handshake)?;
|
||||||
|
|
||||||
|
if next_state == 1 {
|
||||||
|
loop {
|
||||||
|
let client_packet = client_conn.read_packet()?;
|
||||||
|
|
||||||
|
server_conn.write_packet(&client_packet)?;
|
||||||
|
|
||||||
|
let mut server_packet = server_conn.read_packet()?;
|
||||||
|
|
||||||
|
if client_packet.id() == 0x00 {
|
||||||
|
let server_status = server_packet.read_string()?;
|
||||||
|
|
||||||
|
let (status, cancel) = ProxyEvent::status_request(
|
||||||
|
this.clone(),
|
||||||
|
server_status.clone(),
|
||||||
|
addr.clone(),
|
||||||
|
server_address.clone(),
|
||||||
|
server_port,
|
||||||
|
);
|
||||||
|
|
||||||
|
if cancel {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
server_packet = Packet::build(0x00, |p| p.write_string(&status))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
client_conn.write_packet(&server_packet)?;
|
||||||
|
}
|
||||||
|
} else if next_state == 2 {
|
||||||
|
let player = Arc::new(Mutex::new(ProxyPlayer::new(
|
||||||
|
client_conn.try_clone().unwrap(),
|
||||||
|
server_conn.try_clone().unwrap(),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
protocol_version,
|
||||||
|
Some(server.clone()),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
Arc::new(AtomicUsize::new(0)),
|
||||||
|
)));
|
||||||
|
|
||||||
|
this.lock().unwrap().players.push(player.clone());
|
||||||
|
|
||||||
|
let mut login_start = client_conn.read_packet()?;
|
||||||
|
|
||||||
|
player.lock().unwrap().name = Some(login_start.read_string()?);
|
||||||
|
player.lock().unwrap().uuid = Some(login_start.read_uuid()?);
|
||||||
|
|
||||||
|
server_conn.write_packet(&login_start)?;
|
||||||
|
|
||||||
|
while let Ok(mut packet) = server_conn.read_packet() {
|
||||||
|
client_conn.write_packet(&packet)?;
|
||||||
|
|
||||||
|
if packet.id() == 0x01 {
|
||||||
|
let mut enc_response = client_conn.read_packet()?;
|
||||||
|
|
||||||
|
let shared_secret_length = enc_response.read_usize_varint()?;
|
||||||
|
player.lock().unwrap().shared_secret =
|
||||||
|
Some(enc_response.read_bytes(shared_secret_length)?);
|
||||||
|
let verify_token_length = enc_response.read_usize_varint()?;
|
||||||
|
player.lock().unwrap().verify_token =
|
||||||
|
Some(enc_response.read_bytes(verify_token_length)?);
|
||||||
|
|
||||||
|
server_conn.write_packet(&enc_response)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if packet.id() == 0x03 {
|
||||||
|
let threshold = packet.read_isize_varint()?;
|
||||||
|
|
||||||
|
if threshold >= 0 {
|
||||||
|
let threshold = threshold.zigzag();
|
||||||
|
|
||||||
|
server_conn.set_compression(Some(threshold));
|
||||||
|
client_conn.set_compression(Some(threshold));
|
||||||
|
} else {
|
||||||
|
server_conn.set_compression(None);
|
||||||
|
client_conn.set_compression(None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if packet.id() == 0x02 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// println!("lac re");
|
||||||
|
// let login_ack = client_conn.read_packet()?;
|
||||||
|
// println!("lac {}", login_ack.id());
|
||||||
|
// if login_ack.id() != 0x03 {
|
||||||
|
// return Ok(());
|
||||||
|
// }
|
||||||
|
|
||||||
|
thread::spawn({
|
||||||
|
let this = this.clone();
|
||||||
|
|
||||||
|
move || {
|
||||||
|
info!(
|
||||||
|
"{} connected player {}",
|
||||||
|
addr.to_string(),
|
||||||
|
player.lock().unwrap().name.clone().unwrap()
|
||||||
|
);
|
||||||
|
ProxyEvent::player_connected(this.clone(), player.clone());
|
||||||
|
|
||||||
|
let _ = ProxyPlayer::connect(
|
||||||
|
player,
|
||||||
|
this,
|
||||||
|
server_config.player_forwarding().clone(),
|
||||||
|
&server_address,
|
||||||
|
server_port,
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(self) {
|
||||||
|
let listener = TcpListener::bind(self.config.host()).expect("invalid host");
|
||||||
|
|
||||||
|
info!("meexprox started on {}", self.config.host());
|
||||||
|
|
||||||
|
let mutex_self = Arc::new(Mutex::new(self));
|
||||||
|
|
||||||
|
for client in listener.incoming() {
|
||||||
|
if let Ok(client) = client {
|
||||||
|
let mutex_self_clone = mutex_self.clone();
|
||||||
|
thread::spawn(move || {
|
||||||
|
match Self::accept_client(mutex_self_clone, client) {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(_) => {
|
||||||
|
// error!("connection error: {:?}", e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type PlayerMutex = Arc<Mutex<ProxyPlayer>>;
|
||||||
|
pub type MeexProxMutex = Arc<Mutex<MeexProx>>;
|
9
src/meexprox/mod.rs
Normal file
9
src/meexprox/mod.rs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
pub mod config;
|
||||||
|
pub mod error;
|
||||||
|
pub mod event;
|
||||||
|
pub mod meexprox;
|
||||||
|
|
||||||
|
pub use config::*;
|
||||||
|
pub use error::*;
|
||||||
|
pub use event::*;
|
||||||
|
pub use meexprox::*;
|
Loading…
Reference in New Issue
Block a user