From d4ede0ca834e52b5a6ea500825975e9034971957 Mon Sep 17 00:00:00 2001 From: red binder Date: Mon, 10 Aug 2026 20:48:31 +0200 Subject: [PATCH] add basic wii sports club support --- editions.yaml | 3 +- rnex-protocols/auth-protos/Cargo.toml | 1 + rnex-protocols/base-protos/Cargo.toml | 1 + rnex-protocols/ds-protos/Cargo.toml | 1 + rnex-protocols/fpd-protos/Cargo.toml | 1 + rnex-protocols/mm-protos/Cargo.toml | 1 + rnex-protocols/mm-protos/src/matchmake.rs | 34 +++++++ rnex-protocols/msg-protos/Cargo.toml | 1 + rnex-protocols/rk-protos/Cargo.toml | 1 + rnex-prudp/Cargo.toml | 1 + rnex-rmc/Cargo.toml | 1 + rnex-server-nex-modules/rnex-auth/Cargo.toml | 1 + rnex-server-nex-modules/rnex-base/Cargo.toml | 1 + rnex-server-nex-modules/rnex-ds/Cargo.toml | 1 + rnex-server-nex-modules/rnex-fpd/Cargo.toml | 1 + rnex-server-nex-modules/rnex-mm/Cargo.toml | 3 +- .../rnex-mm/src/matchmake.rs | 94 +++++++++++++++---- rnex-server-nex-modules/rnex-mm/src/user.rs | 31 ++++-- rnex-server-nex-modules/rnex-msg/Cargo.toml | 1 + rnex-server-nex-modules/rnex-rk/Cargo.toml | 1 + rnex-server/Cargo.toml | 1 + rnex-server/backend-auth/Cargo.toml | 1 + rnex-server/backend-secure/Cargo.toml | 1 + rnex-util/Cargo.toml | 1 + 24 files changed, 152 insertions(+), 32 deletions(-) diff --git a/editions.yaml b/editions.yaml index e5badf1..c5c605d 100644 --- a/editions.yaml +++ b/editions.yaml @@ -27,8 +27,7 @@ wii-sports-club: include-in-checkall: true features: - prudpv1 - - third-notif-param - - v3-8-15 + - v3-4-7 - match-making - ranking - datastore diff --git a/rnex-protocols/auth-protos/Cargo.toml b/rnex-protocols/auth-protos/Cargo.toml index 2581ab4..246ca66 100644 --- a/rnex-protocols/auth-protos/Cargo.toml +++ b/rnex-protocols/auth-protos/Cargo.toml @@ -18,6 +18,7 @@ database-support = [] nx = [] third-notif-param = [] v3-3-2 = [] +v3-4-7 = ["v3-3-2"] v3-4-0 = ["v3-3-2", "third-notif-param"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] diff --git a/rnex-protocols/base-protos/Cargo.toml b/rnex-protocols/base-protos/Cargo.toml index a4898ec..417470a 100644 --- a/rnex-protocols/base-protos/Cargo.toml +++ b/rnex-protocols/base-protos/Cargo.toml @@ -17,6 +17,7 @@ nx = [] third-notif-param = [] friends = [] v3-3-2 = [] +v3-4-7 = ["v3-3-2"] v3-4-0 = ["v3-3-2", "third-notif-param"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] diff --git a/rnex-protocols/ds-protos/Cargo.toml b/rnex-protocols/ds-protos/Cargo.toml index fde23a0..5a912a8 100644 --- a/rnex-protocols/ds-protos/Cargo.toml +++ b/rnex-protocols/ds-protos/Cargo.toml @@ -17,6 +17,7 @@ nx = [] third-notif-param = [] friends = [] v3-3-2 = [] +v3-4-7 = ["v3-3-2"] v3-4-0 = ["v3-3-2", "third-notif-param"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] diff --git a/rnex-protocols/fpd-protos/Cargo.toml b/rnex-protocols/fpd-protos/Cargo.toml index 88924a3..3171e07 100644 --- a/rnex-protocols/fpd-protos/Cargo.toml +++ b/rnex-protocols/fpd-protos/Cargo.toml @@ -16,6 +16,7 @@ nx = [] third-notif-param = [] friends = [] v3-3-2 = [] +v3-4-7 = ["v3-3-2"] v3-4-0 = ["v3-3-2", "third-notif-param"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] diff --git a/rnex-protocols/mm-protos/Cargo.toml b/rnex-protocols/mm-protos/Cargo.toml index 9f82b37..8c2fec3 100644 --- a/rnex-protocols/mm-protos/Cargo.toml +++ b/rnex-protocols/mm-protos/Cargo.toml @@ -14,6 +14,7 @@ tracing = "0.1.44" [features] third-notif-param = [] v3-3-2 = [] +v3-4-7 = ["v3-3-2"] v3-4-0 = ["v3-3-2", "third-notif-param"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] diff --git a/rnex-protocols/mm-protos/src/matchmake.rs b/rnex-protocols/mm-protos/src/matchmake.rs index 39c8886..0daa2b7 100644 --- a/rnex-protocols/mm-protos/src/matchmake.rs +++ b/rnex-protocols/mm-protos/src/matchmake.rs @@ -59,6 +59,23 @@ cfg_if! { pub user_password_enabled: bool, pub system_password_enabled: bool, } + } else if #[cfg(feature = "v3-4-7")] { + #[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] + #[rmc_struct(0)] + pub struct MatchmakeSession { + //inherits from + #[extends] + pub gathering: Gathering, + + pub gamemode: u32, + pub attributes: Vec, + pub open_participation: bool, + pub matchmake_system_type: u32, + pub application_buffer: Vec, + pub participation_count: u32, + pub progress_score: u8, + pub session_key: Vec, + } } else { #[derive(RmcSerialize, Debug, Clone, Default, PartialEq)] #[rmc_struct(0)] @@ -98,6 +115,21 @@ cfg_if! { pub exclude_system_password_set: bool, pub refer_gid: u32, } + } else if #[cfg(feature = "v3-4-7")] { + #[derive(RmcSerialize, Debug, Clone)] + #[rmc_struct(0)] + pub struct MatchmakeSessionSearchCriteria { + pub attribs: Vec, + pub game_mode: String, + pub minimum_participants: String, + pub maximum_participants: String, + pub matchmake_system_type: String, + pub vacant_only: bool, + pub exclude_locked: bool, + pub exclude_non_host_pid: bool, + pub selection_method: u32, + pub vacant_participants: u16, + } } else { #[derive(RmcSerialize, Debug, Clone)] #[rmc_struct(3)] @@ -213,6 +245,8 @@ pub trait Matchmake { async fn get_detailed_participants(&self, gid: u32) -> Result, ErrorCode>; #[method_id(21)] async fn find_by_single_id(&self, gid: u32) -> Result<(bool, Any), ErrorCode>; + #[method_id(40)] + async fn update_session_host_v1(&self, gid: u32) -> Result<(), ErrorCode>; #[method_id(41)] async fn get_session_urls(&self, gid: u32) -> Result, ErrorCode>; #[method_id(42)] diff --git a/rnex-protocols/msg-protos/Cargo.toml b/rnex-protocols/msg-protos/Cargo.toml index 598f848..97495ce 100644 --- a/rnex-protocols/msg-protos/Cargo.toml +++ b/rnex-protocols/msg-protos/Cargo.toml @@ -15,6 +15,7 @@ database-support = [] nx = [] third-notif-param = [] v3-3-2 = [] +v3-4-7 = ["v3-3-2"] v3-4-0 = ["v3-3-2", "third-notif-param"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] diff --git a/rnex-protocols/rk-protos/Cargo.toml b/rnex-protocols/rk-protos/Cargo.toml index 9f4d705..aee92c1 100644 --- a/rnex-protocols/rk-protos/Cargo.toml +++ b/rnex-protocols/rk-protos/Cargo.toml @@ -17,6 +17,7 @@ database-support = [] nx = [] third-notif-param = [] v3-3-2 = [] +v3-4-7 = ["v3-3-2"] v3-4-0 = ["v3-3-2", "third-notif-param"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] diff --git a/rnex-prudp/Cargo.toml b/rnex-prudp/Cargo.toml index 11c41ee..e2216e2 100644 --- a/rnex-prudp/Cargo.toml +++ b/rnex-prudp/Cargo.toml @@ -23,6 +23,7 @@ nx = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-rmc/Cargo.toml b/rnex-rmc/Cargo.toml index c952cee..ac99318 100644 --- a/rnex-rmc/Cargo.toml +++ b/rnex-rmc/Cargo.toml @@ -24,6 +24,7 @@ nx = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-server-nex-modules/rnex-auth/Cargo.toml b/rnex-server-nex-modules/rnex-auth/Cargo.toml index 5fd969b..f934498 100644 --- a/rnex-server-nex-modules/rnex-auth/Cargo.toml +++ b/rnex-server-nex-modules/rnex-auth/Cargo.toml @@ -26,6 +26,7 @@ big_pid = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-server-nex-modules/rnex-base/Cargo.toml b/rnex-server-nex-modules/rnex-base/Cargo.toml index f5dfcb6..f17abb1 100644 --- a/rnex-server-nex-modules/rnex-base/Cargo.toml +++ b/rnex-server-nex-modules/rnex-base/Cargo.toml @@ -21,6 +21,7 @@ nx = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-server-nex-modules/rnex-ds/Cargo.toml b/rnex-server-nex-modules/rnex-ds/Cargo.toml index fc7590f..c13cb56 100644 --- a/rnex-server-nex-modules/rnex-ds/Cargo.toml +++ b/rnex-server-nex-modules/rnex-ds/Cargo.toml @@ -30,6 +30,7 @@ nx = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-server-nex-modules/rnex-fpd/Cargo.toml b/rnex-server-nex-modules/rnex-fpd/Cargo.toml index 39c23d6..9f43f9b 100644 --- a/rnex-server-nex-modules/rnex-fpd/Cargo.toml +++ b/rnex-server-nex-modules/rnex-fpd/Cargo.toml @@ -31,6 +31,7 @@ big_pid = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-server-nex-modules/rnex-mm/Cargo.toml b/rnex-server-nex-modules/rnex-mm/Cargo.toml index a4add3a..56c7f83 100644 --- a/rnex-server-nex-modules/rnex-mm/Cargo.toml +++ b/rnex-server-nex-modules/rnex-mm/Cargo.toml @@ -26,6 +26,7 @@ big_pid = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] @@ -33,7 +34,7 @@ v3-10-22 = ["v3-8-15"] v4-3-11 = ["v3-8-15"] nx = ["big_pid"] splatoon = ["v3-5-0"] -datastore = ["database-support", "v3-8-15"] +datastore = ["database-support"] database-support = [] [lints] diff --git a/rnex-server-nex-modules/rnex-mm/src/matchmake.rs b/rnex-server-nex-modules/rnex-mm/src/matchmake.rs index ff46ebf..9476614 100644 --- a/rnex-server-nex-modules/rnex-mm/src/matchmake.rs +++ b/rnex-server-nex-modules/rnex-mm/src/matchmake.rs @@ -70,7 +70,7 @@ impl MatchmakeManager { } async fn garbage_collect(&self) { - info!("running rnex garbage collector over all sessions and users"); + println!("running rnex garbage collector over all sessions and users"); let mut idx = 0; @@ -121,24 +121,35 @@ impl MatchmakeManager { ) -> Result>>, ErrorCode> { let sessions = self.sessions.read().await; let mut list = Vec::with_capacity(sessions.len()); - for session in sessions.values() { + + for (key, session) in sessions.iter() { let inner_session = session.lock().await; + if !inner_session.is_joinable() { + println!("dropped session {:?}: not joinable", key); continue; } let mut bool_matched_criteria = false; for criteria in criterias { - if inner_session.matches_criteria(criteria)? { - bool_matched_criteria = true; + match inner_session.matches_criteria(criteria) { + Ok(true) => { + bool_matched_criteria = true; + } + Ok(false) => {} + Err(e) => { + println!("dropped session {:?}: criteria check returned error {:?}", key, e); + return Err(e); + } } } if bool_matched_criteria { println!("matched session: {:?}", session); - list.push(session.clone()); + } else { + println!("dropped session {:?}: did not match any criteria", key); } } @@ -357,11 +368,23 @@ impl ExtendedMatchmakeSession { } pub fn has_min_active_players(&self) -> bool { - self.connected_players + let required = self.session.gathering.minimum_participants as usize; + + let active_count = self + .connected_players .iter() - .filter(|v| v.upgrade().is_some()) - .count() - >= self.session.gathering.minimum_participants as _ + .filter_map(|v| v.upgrade()) + .filter(|player| { + true + }) + .count(); + + println!( + "[DEBUG] has_min_active_players: active_count={}, required={}", + active_count, required + ); + + active_count >= required } #[inline] @@ -372,20 +395,53 @@ impl ExtendedMatchmakeSession { #[inline] pub fn is_reachable(&self) -> bool { - self.get_active_players() - .any(|v| v.base.pid == self.session.gathering.host_pid) - && (if self.session.gathering.flags & PERSISTENT_GATHERING != 0 { - if self.has_min_active_players() { - true - } else { - self.session.open_participation - } + let host_pid = self.session.gathering.host_pid; + let host_active = self + .get_active_players() + .any(|v| v.base.pid == host_pid); + + let is_persistent = (self.session.gathering.flags & PERSISTENT_GATHERING) != 0; + let has_min_players = self.has_min_active_players(); + let open_part = self.session.open_participation; + + #[cfg(feature = "v3-4-7")] + let persistent_check_passed = if is_persistent || open_part { + has_min_players || open_part + } else { + has_min_players + }; + + #[cfg(not(feature = "v3-4-7"))] + let persistent_check_passed = (if is_persistent { + if has_min_players { + true } else { - self.has_min_active_players() - }) & self.has_min_active_players() + open_part + } + } else { + has_min_players + }) & has_min_players; + + let result = host_active && persistent_check_passed; + + println!( + "[DEBUG] is_reachable: host_active={}, host_pid={}, is_persistent={}, has_min_players={}, open_participation={}, persistent_check_passed={}, final_result={}", + host_active, + host_pid, + is_persistent, + has_min_players, + open_part, + persistent_check_passed, + result + ); + + result } + #[inline] pub fn is_joinable(&self) -> bool { + #[cfg(feature = "v3-4-7")] + let is_open = true; #[cfg(not(feature = "splatoon"))] let is_open = self.session.open_participation; #[cfg(feature = "splatoon")] diff --git a/rnex-server-nex-modules/rnex-mm/src/user.rs b/rnex-server-nex-modules/rnex-mm/src/user.rs index 2e2f380..5e42d3e 100644 --- a/rnex-server-nex-modules/rnex-mm/src/user.rs +++ b/rnex-server-nex-modules/rnex-mm/src/user.rs @@ -24,7 +24,7 @@ use rnex_util::{ }; use tokio::sync::Mutex; use tracing::info; - +use rnex_mm_protos::matchmake::gathering_flags; use crate::matchmake::{ExtendedMatchmakeSession, MatchmakeManager}; /*cfg_if! { @@ -108,7 +108,7 @@ impl MatchmakeExtension for MatchmakeUser { browse_criteria: MatchmakeSessionSearchCriteria, result_range: ResultsRange, ) -> Result>, ErrorCode> { - info!("browsing matchmake sessions with criteria: {:?}", browse_criteria); + println!("browsing matchmake sessions with criteria: {:?}", browse_criteria); let results = self .matchmake_manager @@ -116,20 +116,20 @@ impl MatchmakeExtension for MatchmakeUser { .await?; let mm_list = result_range.make_from_list(&results[..]); - info!("filtered mm_list count: {}", mm_list.len()); + println!("filtered mm_list count: {}", mm_list.len()); let mut list = Vec::with_capacity(mm_list.len()); for (index, mm_sess) in mm_list.iter().enumerate() { let mm_sess_guard = mm_sess.lock().await; - info!("processing session [{}]: {:?}", index, *mm_sess_guard); + println!("processing session [{}]: {:?}", index, *mm_sess_guard); let gathering_any = Any::new(&mm_sess_guard.session).expect("type error"); list.push(gathering_any); } - info!("successfully collected {} sessions into output list", list.len()); + println!("successfully collected {} sessions into output list", list.len()); Ok(list) } @@ -153,7 +153,7 @@ impl MatchmakeExtension for MatchmakeUser { &self, create_session_param: CreateMatchmakeSessionParam, ) -> Result { - info!("session paramater: {:?}", create_session_param); + println!("session paramater: {:?}", create_session_param); let gid = self.matchmake_manager.next_gid(); @@ -269,7 +269,7 @@ impl MatchmakeExtension for MatchmakeUser { &self, param: AutoMatchmakeParam, ) -> Result { - info!("autommparam: {:?}", param); + println!("autommparam: {:?}", param); let mut joining_players = vec![self.this.clone()]; @@ -315,7 +315,7 @@ impl MatchmakeExtension for MatchmakeUser { drop(sessions); - info!("making new session!"); + println!("making new session!"); let AutoMatchmakeParam { join_message, @@ -366,7 +366,7 @@ impl MatchmakeExtension for MatchmakeUser { gathering: Any, message: String, ) -> Result<(u32, Vec), ErrorCode> { - info!("gathering: {:?}", gathering); + println!("gathering: {:?}", gathering); let session: MatchmakeSession = gathering.try_get_as()?; let session = self @@ -485,7 +485,7 @@ impl MatchmakeExtension for MatchmakeUser { ) -> Result, ErrorCode> { let session: MatchmakeSession = gathering.try_get_as()?; - info!("automm criteria: {:?}", criteria); + println!("automm criteria: {:?}", criteria); let session = self .auto_matchmake_with_param_postpone(AutoMatchmakeParam { @@ -654,6 +654,17 @@ impl Matchmake for MatchmakeUser { Ok(participant_details) } + + async fn update_session_host_v1(&self, gid: u32) -> Result<(), ErrorCode> { + let should_migrate_owner = { + let session = self.matchmake_manager.get_session(gid).await?; + let session = session.lock().await; + + (session.session.gathering.flags & gathering_flags::PARTICIPANTS_CHANGE_OWNER) != 0 + }; + + self.update_session_host(gid, should_migrate_owner).await + } } impl MatchmakeExt for MatchmakeUser { diff --git a/rnex-server-nex-modules/rnex-msg/Cargo.toml b/rnex-server-nex-modules/rnex-msg/Cargo.toml index 0f3afdf..7948373 100644 --- a/rnex-server-nex-modules/rnex-msg/Cargo.toml +++ b/rnex-server-nex-modules/rnex-msg/Cargo.toml @@ -11,6 +11,7 @@ big_pid = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-server-nex-modules/rnex-rk/Cargo.toml b/rnex-server-nex-modules/rnex-rk/Cargo.toml index 542a6ef..d3247dd 100644 --- a/rnex-server-nex-modules/rnex-rk/Cargo.toml +++ b/rnex-server-nex-modules/rnex-rk/Cargo.toml @@ -11,6 +11,7 @@ big_pid = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-server/Cargo.toml b/rnex-server/Cargo.toml index 222c387..073be36 100644 --- a/rnex-server/Cargo.toml +++ b/rnex-server/Cargo.toml @@ -24,6 +24,7 @@ nx = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-server/backend-auth/Cargo.toml b/rnex-server/backend-auth/Cargo.toml index da3ea5a..03886ed 100644 --- a/rnex-server/backend-auth/Cargo.toml +++ b/rnex-server/backend-auth/Cargo.toml @@ -11,6 +11,7 @@ nx = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-server/backend-secure/Cargo.toml b/rnex-server/backend-secure/Cargo.toml index 4d53aba..15eecc3 100644 --- a/rnex-server/backend-secure/Cargo.toml +++ b/rnex-server/backend-secure/Cargo.toml @@ -25,6 +25,7 @@ nx = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"] diff --git a/rnex-util/Cargo.toml b/rnex-util/Cargo.toml index 83e6bb1..2322a6f 100644 --- a/rnex-util/Cargo.toml +++ b/rnex-util/Cargo.toml @@ -20,6 +20,7 @@ big_pid = [] third-notif-param = [] v3-3-2 = [] v3-4-0 = ["v3-3-2", "third-notif-param", "rmc_struct_header"] +v3-4-7 = ["v3-3-2"] v3-5-0 = ["v3-4-0"] v3-8-13 = ["v3-5-0"] v3-8-15 = ["v3-5-0"]