From ade535e5568a89c4f35adce61158b6c0005e601d Mon Sep 17 00:00:00 2001 From: "NG (Graham)" Date: Mon, 6 Oct 2025 22:57:19 -0400 Subject: [PATCH] Add Arc CRF username spoofing --- Cargo.lock | 1 + Cargo.toml | 2 ++ rc_auth/Cargo.toml | 2 +- rc_core/Cargo.toml | 4 ++-- rc_core/src/factory/adapter_enum.rs | 2 +- rc_core/src/persist/combat.rs | 2 +- rc_core/src/persist/vehicle_factory.rs | 2 ++ rc_factory/Cargo.toml | 3 ++- rc_factory/src/arc/adapter.rs | 8 +++++--- rc_services_room/Cargo.toml | 2 +- 10 files changed, 18 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d4396e8..6c37936 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2581,6 +2581,7 @@ dependencies = [ "async-trait", "base64 0.22.1", "chrono", + "hex", "libfj", "log", "sea-orm", diff --git a/Cargo.toml b/Cargo.toml index fb5e181..35ac6f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,3 +46,5 @@ chrono = "0.4" git-version = "0.3" rand = { version = "0.9", features = [ "thread_rng" ] } num-quaternion = "1.0" +hex = "0.4" +base64 = "0.22" diff --git a/rc_auth/Cargo.toml b/rc_auth/Cargo.toml index e55a28f..f808054 100644 --- a/rc_auth/Cargo.toml +++ b/rc_auth/Cargo.toml @@ -19,6 +19,6 @@ libfj.workspace = true git-version.workspace = true serde.workspace = true serde_json.workspace = true -hex = "0.4" +hex.workspace = true handlebars = { version = "5", features = ["dir_source"] } diff --git a/rc_core/Cargo.toml b/rc_core/Cargo.toml index a83bd19..9b777e6 100644 --- a/rc_core/Cargo.toml +++ b/rc_core/Cargo.toml @@ -10,8 +10,8 @@ authors.workspace = true [dependencies] log.workspace = true polariton.workspace = true -base64 = "0.22" -hex = "0.4" +base64.workspace = true +hex.workspace = true serde.workspace = true serde_json.workspace = true chrono.workspace = true diff --git a/rc_core/src/factory/adapter_enum.rs b/rc_core/src/factory/adapter_enum.rs index 8a0b156..5f2a278 100644 --- a/rc_core/src/factory/adapter_enum.rs +++ b/rc_core/src/factory/adapter_enum.rs @@ -34,7 +34,7 @@ impl oj_rc_factory::VehicleFactoryAdapter for Factory { impl Factory { pub async fn from_config(conf: &crate::persist::FactoryConfig) -> Result> { Ok(match &conf.adapter { - crate::persist::AdapterSettings::Arc(x) => Self::Arc(oj_rc_factory::arc::ArcAdapter::init(&x.uri, x.show_expired, x.override_cdn.clone()).await?), + crate::persist::AdapterSettings::Arc(x) => Self::Arc(oj_rc_factory::arc::ArcAdapter::init(&x.uri, x.show_expired, x.override_cdn.clone(), x.spoof_username).await?), crate::persist::AdapterSettings::None => Self::None, }) } diff --git a/rc_core/src/persist/combat.rs b/rc_core/src/persist/combat.rs index d643a11..d6e5c92 100644 --- a/rc_core/src/persist/combat.rs +++ b/rc_core/src/persist/combat.rs @@ -509,7 +509,7 @@ fn default_rotation() -> GameEventSequence { fn default_multiplayer() -> super::MultiplayerConfig { super::MultiplayerConfig { - players_per_game: 2, + players_per_game: 1, enabled: true, network: super::multiplayer::default_net_conf(), fakes: super::multiplayer::default_fake_users(), diff --git a/rc_core/src/persist/vehicle_factory.rs b/rc_core/src/persist/vehicle_factory.rs index acfc46c..04bbbab 100644 --- a/rc_core/src/persist/vehicle_factory.rs +++ b/rc_core/src/persist/vehicle_factory.rs @@ -26,6 +26,8 @@ pub struct ArcFactorySettings { /// should probably end with /roboshop/arc/Live/ #[serde(default)] pub override_cdn: Option, + #[serde(default = "default_true")] + pub spoof_username: bool, } fn default_true() -> bool { diff --git a/rc_factory/Cargo.toml b/rc_factory/Cargo.toml index 1127e62..b96aa79 100644 --- a/rc_factory/Cargo.toml +++ b/rc_factory/Cargo.toml @@ -13,4 +13,5 @@ async-trait.workspace = true libfj.workspace = true chrono.workspace = true log.workspace = true -base64 = "0.22" +base64.workspace = true +hex.workspace = true diff --git a/rc_factory/src/arc/adapter.rs b/rc_factory/src/arc/adapter.rs index d90f396..f1828d3 100644 --- a/rc_factory/src/arc/adapter.rs +++ b/rc_factory/src/arc/adapter.rs @@ -4,10 +4,11 @@ pub struct ArcAdapter { orm: sea_orm::DatabaseConnection, ignore_expiry: bool, cdn: Option, + spoof_users: bool, } impl ArcAdapter { - pub async fn init(uri: &str, show_expired: bool, override_cdn: Option) -> Result{ + pub async fn init(uri: &str, show_expired: bool, override_cdn: Option, username_spoofing: bool) -> Result{ log::debug!("Connecting to Archive of RoboCraft (ARC) vehicle factory database URI: {}", uri); let db = sea_orm::Database::connect(uri).await?; let good_cdn = override_cdn.map(|s| if s.ends_with("/") { s } else { format!("{}/", s) }); @@ -15,6 +16,7 @@ impl ArcAdapter { orm: db, ignore_expiry: show_expired, cdn: good_cdn, + spoof_users: username_spoofing, }; // do query to ensure database is ok adapter.default_query().one(&adapter.orm).await?; @@ -57,7 +59,7 @@ impl crate::VehicleFactoryAdapter for ArcAdapter { name: meta.name, description: meta.description, thumbnail: self.thumbnail_url(meta.thumbnail, meta.id), - added_by: meta.added_by, + added_by: if self.spoof_users { hex::encode(meta.added_by.as_bytes()) } else { meta.added_by }, added_by_display_name: meta.added_by_display_name, added_date: crate::traits::parse_rc_date(&meta.added_date).unwrap_or_default(), expiry_date: if self.ignore_expiry { chrono::Utc::now() + chrono::Duration::weeks(2) } else { crate::traits::parse_rc_date(&meta.expiry_date).unwrap_or_default() }, @@ -162,7 +164,7 @@ impl crate::VehicleFactoryAdapter for ArcAdapter { name: meta.name, description: meta.description, thumbnail: meta.thumbnail, - added_by: meta.added_by, + added_by: if self.spoof_users { hex::encode(meta.added_by.as_bytes()) } else { meta.added_by }, added_by_display_name: meta.added_by_display_name, added_date: crate::traits::parse_rc_date(&meta.added_date).unwrap_or_default(), expiry_date: if self.ignore_expiry { chrono::Utc::now() + chrono::Duration::weeks(2) } else { crate::traits::parse_rc_date(&meta.expiry_date).unwrap_or_default() }, diff --git a/rc_services_room/Cargo.toml b/rc_services_room/Cargo.toml index 7116347..6eb6dc7 100644 --- a/rc_services_room/Cargo.toml +++ b/rc_services_room/Cargo.toml @@ -15,7 +15,7 @@ clap.workspace = true polariton.workspace = true oj_polariton_auth = { version = "*", path = "../polariton_auth" } polariton_server.workspace = true -hex = "0.4" +hex.workspace = true serde.workspace = true serde_json.workspace = true chrono.workspace = true