velocity player forwarding
This commit is contained in:
parent
7a12dfb51d
commit
700bf95a5d
72
Cargo.lock
generated
72
Cargo.lock
generated
@ -29,6 +29,15 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@ -78,6 +87,17 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.1"
|
||||
@ -141,9 +161,11 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
name = "meexprox"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bytebuffer",
|
||||
"ignore-result",
|
||||
"log",
|
||||
"random-string",
|
||||
"ring",
|
||||
"rust_mc_proto",
|
||||
"serde_yml",
|
||||
"simplelog",
|
||||
@ -213,6 +235,21 @@ dependencies = [
|
||||
"fastrand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust_mc_proto"
|
||||
version = "0.1.16"
|
||||
@ -264,6 +301,12 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "simplelog"
|
||||
version = "0.12.2"
|
||||
@ -275,6 +318,12 @@ dependencies = [
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.87"
|
||||
@ -334,6 +383,12 @@ version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.11.0"
|
||||
@ -346,13 +401,28 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -11,3 +11,5 @@ log = "0.4.22"
|
||||
simplelog = "0.12.2"
|
||||
ignore-result = "0.2.0"
|
||||
random-string = "1.1.0"
|
||||
ring = "0.17.8"
|
||||
bytebuffer = "2.3.0"
|
@ -30,5 +30,5 @@ incoming_forwarding: # player forwarding for incoming connections
|
||||
# player forwarding types:
|
||||
# - velocity (or "modern" in Velocity config) (secret is required)
|
||||
# - bungeecord (or "legacy" in Velocity config) (secret is optional)
|
||||
# - meexprox (best) (secret is required)
|
||||
# - meexprox (open-source protocol) (secret is required)
|
||||
# - none (enabled: false)
|
@ -1,11 +1,13 @@
|
||||
use std::{net::{SocketAddr, TcpStream}, sync::{Arc, Mutex}, thread};
|
||||
|
||||
use bytebuffer::ByteBuffer;
|
||||
use ignore_result::Ignore;
|
||||
use log::debug;
|
||||
use log::info;
|
||||
use ring::hmac;
|
||||
use rust_mc_proto::{DataBufferReader, DataBufferWriter, MCConnTcp, Packet, ProtocolError};
|
||||
use uuid::Uuid;
|
||||
|
||||
use super::{config::{ProxyConfig, ServerInfo}, error::{AsProxyResult, ProxyError}};
|
||||
use super::{config::{PlayerForwarding, ProxyConfig, ServerInfo}, error::{AsProxyResult, ProxyError}};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct LoginInfo {
|
||||
@ -74,6 +76,7 @@ pub struct Player {
|
||||
|
||||
impl Player {
|
||||
pub fn read(
|
||||
_config: &ProxyConfig,
|
||||
protocol_version: u16,
|
||||
server_address: String,
|
||||
server_port: u16,
|
||||
@ -98,7 +101,7 @@ impl Player {
|
||||
login_info: None,
|
||||
name: name.clone(),
|
||||
uuid,
|
||||
server: Some(server),
|
||||
server: Some(server.clone()),
|
||||
protocol_version
|
||||
};
|
||||
|
||||
@ -128,6 +131,47 @@ impl Player {
|
||||
player.set_server_compression(compression);
|
||||
player.set_client_compression(compression);
|
||||
}
|
||||
0x04 => { // login plugin request
|
||||
let message_id = packet.read_isize_varint().as_proxy()?;
|
||||
let channel = packet.read_string().as_proxy()?;
|
||||
|
||||
if channel == "velocity:player_info" {
|
||||
if let PlayerForwarding::Velocity(secret) = &server.player_forwarding {
|
||||
let version: u8 = if packet.buffer().len() - packet.buffer().get_rpos() == 1 {
|
||||
packet.read_byte().as_proxy()?
|
||||
} else {
|
||||
1
|
||||
};
|
||||
|
||||
let response = Packet::build(0x02, |p| {
|
||||
p.write_isize_varint(message_id)?;
|
||||
p.write_boolean(true)?;
|
||||
|
||||
let mut buf = ByteBuffer::new();
|
||||
DataBufferWriter::write_u8_varint(&mut buf, version)?;
|
||||
DataBufferWriter::write_string(&mut buf, &addr.to_string())?;
|
||||
DataBufferWriter::write_uuid(&mut buf, &uuid)?;
|
||||
DataBufferWriter::write_string(&mut buf, &name)?;
|
||||
DataBufferWriter::write_u8_varint(&mut buf, 0)?; // properties // maybe fix later
|
||||
let buf = buf.as_bytes();
|
||||
|
||||
let key = hmac::Key::new(hmac::HMAC_SHA256, secret.as_bytes());
|
||||
let sig = hmac::sign(&key, &buf);
|
||||
|
||||
p.write_bytes(sig.as_ref())?;
|
||||
p.write_bytes(buf.as_ref())?;
|
||||
|
||||
Ok(())
|
||||
}).as_proxy()?;
|
||||
|
||||
player.write_server_packet(&response)?;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
player.write_client_packet(&packet)?;
|
||||
player.write_server_packet(&player.read_client_packet()?)?;
|
||||
}
|
||||
_ => {
|
||||
return Err(ProxyError::LoginPacket);
|
||||
},
|
||||
@ -144,8 +188,6 @@ impl Player {
|
||||
verify_token
|
||||
});
|
||||
|
||||
debug!("player connected");
|
||||
|
||||
player.client_recv_loop();
|
||||
player.server_recv_loop();
|
||||
|
||||
@ -155,40 +197,58 @@ impl Player {
|
||||
pub fn client_recv_loop(&self) {
|
||||
let mut client: rust_mc_proto::MinecraftConnection<TcpStream> = self.client_conn.clone().lock().unwrap().try_clone().unwrap();
|
||||
let server = self.server_conn.clone();
|
||||
let name = self.name.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
info!("Player {} connected", name);
|
||||
while let Ok(packet) = client.read_packet() {
|
||||
while !server.lock().unwrap().is_alive() {}
|
||||
server.lock().unwrap().write_packet(&packet).ignore();
|
||||
}
|
||||
info!("Player {} disconnected", name);
|
||||
server.lock().unwrap().close();
|
||||
});
|
||||
}
|
||||
|
||||
pub fn disconnect(&self) {
|
||||
self.client_conn.lock().unwrap().close();
|
||||
self.server_conn.lock().unwrap().close();
|
||||
}
|
||||
|
||||
pub fn kick(&self, text: String) -> Result<(), ProxyError> {
|
||||
self.write_client_packet(&Packet::build(
|
||||
0x1D, |p| p.write_string(&text)
|
||||
).as_proxy()?)?;
|
||||
self.disconnect();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn server_recv_loop(&self) {
|
||||
let mut server = self.server_conn.clone().lock().unwrap().try_clone().unwrap();
|
||||
let client = self.client_conn.clone();
|
||||
let server_name = self.server.as_ref().unwrap().name.clone();
|
||||
let name = self.name.clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
info!("Server {} connected player {}", server_name, name);
|
||||
while let Ok(packet) = server.read_packet() {
|
||||
client.lock().unwrap().write_packet(&packet).ignore();
|
||||
}
|
||||
info!("Server {} disconnected player {}", server_name, name);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn connect(&self, config: &ProxyConfig, server_conn: TcpStream) -> Result<(), ProxyError> {
|
||||
pub fn connect_server(&self, config: &ProxyConfig, server: ServerInfo) -> Result<(), ProxyError> {
|
||||
self.server_conn.lock().unwrap().close();
|
||||
let mut server_conn = MCConnTcp::new(server_conn);
|
||||
let mut server_conn = MCConnTcp::connect(&server.host).as_proxy()?;
|
||||
if let Some(login_info) = &self.login_info {
|
||||
login_info.write(config, &mut server_conn).as_proxy()?;
|
||||
}
|
||||
*self.server_conn.lock().unwrap() = server_conn;
|
||||
self.server_recv_loop();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn connect_server(&self, config: &ProxyConfig, server: ServerInfo) -> Result<(), ProxyError> {
|
||||
self.connect(config, TcpStream::connect(&server.host).map_err(|_| ProxyError::ServerConnect)?)
|
||||
}
|
||||
|
||||
pub fn write_client_packet(&self, packet: &Packet) -> Result<(), ProxyError> {
|
||||
self.client_conn.lock().unwrap().write_packet(packet).as_proxy()
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use log::{debug, error, info};
|
||||
use log::{error, info};
|
||||
use rust_mc_proto::{
|
||||
read_packet, write_packet, DataBufferReader, DataBufferWriter, MCConnTcp, Packet
|
||||
};
|
||||
@ -89,6 +89,7 @@ impl MeexProx {
|
||||
}
|
||||
} else if next_state == 2 {
|
||||
self.players.write().unwrap().push(Player::read(
|
||||
&self.config,
|
||||
protocol_version,
|
||||
server_address,
|
||||
server_port,
|
||||
|
Loading…
Reference in New Issue
Block a user