1
0
Fork 0
mirror of https://github.com/azalea-rs/azalea-viaversion.git synced 2025-08-02 23:44:39 +00:00

Support Socks5 proxies (#14)

* add support for socks5 proxies

* update Cargo.lock and fix doctest

* make cli example docs use a code block for example usage
This commit is contained in:
mat 2025-05-07 16:50:14 -05:00 committed by GitHub
commit b847cc2bf1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 126 additions and 46 deletions

42
Cargo.lock generated
View file

@ -160,7 +160,7 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "azalea"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-auth",
"azalea-block",
@ -197,7 +197,7 @@ dependencies = [
[[package]]
name = "azalea-auth"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-buf",
"azalea-crypto",
@ -217,7 +217,7 @@ dependencies = [
[[package]]
name = "azalea-block"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-block-macros",
"azalea-buf",
@ -227,7 +227,7 @@ dependencies = [
[[package]]
name = "azalea-block-macros"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"proc-macro2",
"quote",
@ -237,7 +237,7 @@ dependencies = [
[[package]]
name = "azalea-brigadier"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-buf",
"azalea-chat",
@ -247,7 +247,7 @@ dependencies = [
[[package]]
name = "azalea-buf"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-buf-macros",
"byteorder",
@ -261,7 +261,7 @@ dependencies = [
[[package]]
name = "azalea-buf-macros"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"proc-macro2",
"quote",
@ -271,7 +271,7 @@ dependencies = [
[[package]]
name = "azalea-chat"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-buf",
"azalea-language",
@ -285,7 +285,7 @@ dependencies = [
[[package]]
name = "azalea-client"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"async-compat",
"azalea-auth",
@ -321,7 +321,7 @@ dependencies = [
[[package]]
name = "azalea-core"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-buf",
"azalea-chat",
@ -338,7 +338,7 @@ dependencies = [
[[package]]
name = "azalea-crypto"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"aes",
"azalea-buf",
@ -355,7 +355,7 @@ dependencies = [
[[package]]
name = "azalea-entity"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-block",
"azalea-buf",
@ -379,7 +379,7 @@ dependencies = [
[[package]]
name = "azalea-inventory"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-buf",
"azalea-chat",
@ -395,7 +395,7 @@ dependencies = [
[[package]]
name = "azalea-inventory-macros"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"proc-macro2",
"quote",
@ -405,7 +405,7 @@ dependencies = [
[[package]]
name = "azalea-language"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"compact_str",
"serde",
@ -415,7 +415,7 @@ dependencies = [
[[package]]
name = "azalea-physics"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-block",
"azalea-core",
@ -432,7 +432,7 @@ dependencies = [
[[package]]
name = "azalea-protocol"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"async-recursion",
"azalea-auth",
@ -467,7 +467,7 @@ dependencies = [
[[package]]
name = "azalea-protocol-macros"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"proc-macro2",
"quote",
@ -477,7 +477,7 @@ dependencies = [
[[package]]
name = "azalea-registry"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-buf",
"azalea-registry-macros",
@ -488,7 +488,7 @@ dependencies = [
[[package]]
name = "azalea-registry-macros"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"quote",
"syn",
@ -515,7 +515,7 @@ dependencies = [
[[package]]
name = "azalea-world"
version = "0.12.0+mc1.21.5"
source = "git+https://github.com/azalea-rs/azalea#5d799be9dbfe2fd50aa2bdf30100f4df7e114674"
source = "git+https://github.com/azalea-rs/azalea#1493c06de597fc320b79212d133f08c678763a6b"
dependencies = [
"azalea-block",
"azalea-buf",

View file

@ -1,7 +1,10 @@
//! A swarm bot that allows you to modify the accounts being used and the target version and the server address from the CLI.
//! A swarm bot that allows you to modify the accounts being used and the target
//! version and the server address from the CLI.
//!
//! Example usage:
//! ```sh
//! cargo r -r --example cli -- --account bot --server localhost --version 1.21.5
//! ```
use std::{env, process, time::Duration};

View file

@ -1,7 +1,9 @@
//! A super basic example of adding a `ViaVersionPlugin` to a `ClientBuilder` and connecting to a localhost server.
//! A super basic example of adding a `ViaVersionPlugin` to a `ClientBuilder`
//! and connecting to a localhost server.
//!
//! # Note
//! The `never_type` feature is completely optional, see how the `swarm` example does not use it.
//! The `never_type` feature is completely optional, see how the `swarm` example
//! does not use it.
#![feature(never_type)]
use azalea::{StartError, prelude::*};

View file

@ -1,7 +1,8 @@
//! An [`azalea`] bot that repeats chat messages sent by other players.
//!
//! # Note
//! The `never_type` feature is completely optional, see how the `swarm` example does not use it.
//! The `never_type` feature is completely optional, see how the `swarm` example
//! does not use it.
#![feature(never_type)]
use azalea::{NoState, StartError, prelude::*};

View file

@ -1,4 +1,5 @@
//! A super basic example of adding a `ViaVersionPlugin` to a `SwarmBuilder` and connecting to a localhost server.
//! A super basic example of adding a `ViaVersionPlugin` to a `SwarmBuilder` and
//! connecting to a localhost server.
use azalea::{prelude::*, swarm::SwarmBuilder};
use azalea_viaversion::ViaVersionPlugin;

2
rustfmt.toml Normal file
View file

@ -0,0 +1,2 @@
wrap_comments = true
group_imports = "StdExternalCrate"

View file

@ -1,17 +1,19 @@
use std::{io::Cursor, net::SocketAddr, path::Path, process::Stdio};
use anyhow::{Context, Result};
use azalea::app::Update;
use azalea::bevy_tasks::{IoTaskPool, Task, futures_lite::future};
use azalea::packet::login::{ReceiveCustomQueryEvent, SendLoginPacketEvent};
use azalea::{
app::{App, Plugin, Startup},
app::{App, Plugin, Startup, prelude::*},
auth::sessionserver::{
ClientSessionServerError::{ForbiddenOperation, InvalidSession},
join_with_server_id_hash,
},
bevy_tasks::{IoTaskPool, Task, futures_lite::future},
buf::AzaleaRead,
ecs::prelude::*,
join::StartJoinServerEvent,
packet::login::{ReceiveCustomQueryEvent, SendLoginPacketEvent},
prelude::*,
protocol::{ServerAddress, packets::login::ServerboundCustomQueryAnswer},
protocol::{ServerAddress, connect::Proxy, packets::login::ServerboundCustomQueryAnswer},
swarm::Swarm,
};
use futures_util::StreamExt;
@ -19,7 +21,6 @@ use kdam::{BarExt, tqdm};
use lazy_regex::regex_captures;
use reqwest::IntoUrl;
use semver::Version;
use std::{io::Cursor, net::SocketAddr, path::Path, process::Stdio};
use tokio::{
fs::File,
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
@ -36,6 +37,7 @@ const VIA_PROXY_VERSION: Version = Version::new(3, 4, 1);
pub struct ViaVersionPlugin {
bind_addr: SocketAddr,
mc_version: String,
proxy: Option<azalea::protocol::connect::Proxy>,
}
impl Plugin for ViaVersionPlugin {
@ -47,6 +49,7 @@ impl Plugin for ViaVersionPlugin {
(
Self::handle_oauth.before(azalea::login::reply_to_custom_queries),
Self::poll_all_oam_join_tasks,
Self::warn_about_proxy.after(azalea::auto_reconnect::rejoin_after_delay),
),
);
}
@ -56,15 +59,67 @@ impl ViaVersionPlugin {
/// Download and start a ViaProxy instance.
///
/// # Panics
/// Will panic if java fails to parse, files fail to download, or ViaProxy fails to start.
///
/// Will panic if Java fails to parse, files fail to download, or ViaProxy
/// fails to start.
pub async fn start(mc_version: impl ToString) -> Self {
let bind_addr = try_find_free_addr().await.expect("Failed to bind");
let mc_version = mc_version.to_string();
let plugin = Self {
bind_addr,
mc_version,
proxy: None,
};
plugin.start_with_self().await
}
/// Same as [`Self::start`], but allows you to pass a Socks5 proxy.
///
/// This is necessary if you want to use Azalea with a proxy and ViaVersion
/// at the same time. This is incompatible with `JoinOpts::proxy`.
///
/// ```no_run
/// # use azalea::{prelude::*, protocol::connect::Proxy};
/// # use azalea_viaversion::ViaVersionPlugin;;
/// #[tokio::main]
/// async fn main() {
/// let account = Account::offline("bot");
///
/// ClientBuilder::new()
/// .set_handler(handle)
/// .add_plugins(
/// ViaVersionPlugin::start_with_proxy(
/// "1.21.5",
/// Proxy::new("10.124.1.186:1080".parse().unwrap(), None),
/// )
/// .await,
/// )
/// .start(account, "6.tcp.ngrok.io:14910")
/// .await
/// .unwrap();
/// }
/// # async fn handle(mut bot: Client, event: Event, state: azalea::NoState) { }
/// ```
pub async fn start_with_proxy(mc_version: impl ToString, proxy: Proxy) -> Self {
let bind_addr = try_find_free_addr().await.expect("Failed to bind");
let mc_version = mc_version.to_string();
let plugin = Self {
bind_addr,
mc_version,
proxy: Some(proxy),
};
plugin.start_with_self().await
}
async fn start_with_self(self) -> Self {
let Some(java_version) = try_find_java_version().await.expect("Failed to parse") else {
panic!(
"Java installation not found! Please download Java from {JAVA_DOWNLOAD_URL} or use your system's package manager."
);
};
let mc_version = mc_version.to_string();
let mc_path = minecraft_folder_path::minecraft_dir().expect("Unsupported Platform");
#[rustfmt::skip]
@ -87,17 +142,24 @@ impl ViaVersionPlugin {
.await
.expect("Failed to download ViaProxyOpenAuthMod");
let bind_addr = try_find_free_addr().await.expect("Failed to bind");
let mut child = Command::new("java")
let mut command = Command::new("java");
command
/* Java Args */
.args(["-jar", &via_proxy_name])
/* ViaProxy Args */
.arg("cli")
.args(["--auth-method", "OPENAUTHMOD"])
.args(["--bind-address", &bind_addr.to_string()])
.args(["--bind-address", &self.bind_addr.to_string()])
.args(["--target-address", "127.0.0.1:0"])
.args(["--target-version", &mc_version])
.args(["--wildcard-domain-handling", "INTERNAL"])
.args(["--target-version", &self.mc_version])
.args(["--wildcard-domain-handling", "INTERNAL"]);
if let Some(proxy) = &self.proxy {
trace!("Starting ViaProxy with proxy: {proxy}");
command.args(["--backend-proxy-url", &proxy.to_string()]);
}
let mut child = command
.current_dir(via_proxy_path)
.stdout(Stdio::piped())
.spawn()
@ -123,18 +185,15 @@ impl ViaVersionPlugin {
/* Wait until ViaProxy is ready */
let _ = rx.changed().await;
Self {
bind_addr,
mc_version,
}
self
}
#[allow(clippy::needless_pass_by_value)]
pub fn handle_change_address(plugin: Res<Self>, swarm: Res<Swarm>) {
let ServerAddress { host, port } = swarm.address.read().clone();
// sadly, the first part of the resolved address is unused as viaproxy will resolve it on its own
// more info: https://github.com/ViaVersion/ViaProxy/issues/338
// sadly, the first part of the resolved address is unused as viaproxy will
// resolve it on its own more info: https://github.com/ViaVersion/ViaProxy/issues/338
let data_after_null_byte = host.split_once('\x07').map(|(_, data)| data);
let mut connection_host = format!(
@ -175,7 +234,8 @@ impl ViaVersionPlugin {
continue;
};
// this makes it so azalea doesn't reply to the query so we can handle it ourselves
// this makes it so azalea doesn't reply to the query so we can handle it
// ourselves
event.disabled = true;
let Some(access_token) = &account.access_token else {
@ -242,6 +302,17 @@ impl ViaVersionPlugin {
commands.trigger(SendLoginPacketEvent::new(entity, packet))
}
}
fn warn_about_proxy(mut events: EventReader<StartJoinServerEvent>) {
for event in events.read() {
if event.connect_opts.proxy.is_some() {
warn!(
"You are using JoinOpts::proxy and ViaVersionPlugin at the same time, which is not a supported configuration. \
Please set your proxy with `ViaVersionPlugin::start_with_proxy` instead."
);
}
}
}
}
#[derive(Component)]