mc wii u matchmaking functions
All checks were successful
Build and Test / splatoon-testfire (push) Successful in 4m28s
Build and Test / splatoon (push) Successful in 4m39s
Build and Test / minecraft-wiiu (push) Successful in 5m4s
Build and Test / sonic-transformed (push) Successful in 5m5s
Build and Test / fast-racing-neo (push) Successful in 5m11s
Build and Test / puyopuyo (push) Successful in 5m11s
Build and Test / mario-tennis (push) Successful in 5m11s
Build and Test / wii-sports-club (push) Successful in 5m12s
Build and Test / wii-u-chat (push) Successful in 5m24s
Build and Test / friends (push) Successful in 5m37s
Build and Test / super-mario-maker (push) Successful in 5m48s

This commit is contained in:
Maple Nebel 2026-07-08 19:43:09 +02:00
commit b3f2dd8e78
4 changed files with 113 additions and 40 deletions

View file

@ -100,6 +100,38 @@ impl MatchmakeManager {
}
});
}
// this could be far more efficient but it is INCREDIBLY difficult to iterate over something
// asyncronously propperly
pub async fn search_by_criteria(
&self,
criterias: &[MatchmakeSessionSearchCriteria],
) -> Result<Vec<Arc<Mutex<ExtendedMatchmakeSession>>>, ErrorCode> {
let sessions = self.sessions.read().await;
let mut list = Vec::with_capacity(sessions.len());
for session in sessions.values() {
let inner_session = session.lock().await;
if !inner_session.is_joinable() {
continue;
}
let mut bool_matched_criteria = false;
for criteria in criterias {
if inner_session.matches_criteria(criteria)? {
bool_matched_criteria = true;
}
}
if bool_matched_criteria {
println!("matched session: {:?}", session);
list.push(session.clone());
}
}
drop(sessions);
Ok(list)
}
}
#[derive(Default, Debug)]

View file

@ -72,6 +72,8 @@ use rnex_core::{
use std::sync::{Arc, Weak};
use tokio::sync::{Mutex, RwLock};
use crate::rmc::structures::resultsrange::ResultsRange;
cfg_if! {
if #[cfg(feature = "datastore")] {
use rnex_core::rmc::protocols::datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore};
@ -216,6 +218,27 @@ impl MatchmakeExtension for User {
Ok(())
}
async fn browse_matchmake_session(
&self,
browse_criteria: MatchmakeSessionSearchCriteria,
result_range: ResultsRange,
) -> Result<Vec<Any<Gathering>>, ErrorCode> {
let results = self
.matchmake_manager
.search_by_criteria(&[browse_criteria])
.await?;
let mm_list = result_range.make_from_list(&results[..]);
let mut list = Vec::with_capacity(mm_list.len());
for mm_sess in mm_list {
let mm_sess = mm_sess.lock().await;
list.push(Any::new(&mm_sess.session).expect("type error"));
}
Ok(list)
}
async fn get_playing_session(&self, _pids: Vec<u32>) -> Result<Vec<()>, ErrorCode> {
Ok(Vec::new())
}
@ -376,45 +399,18 @@ impl MatchmakeExtension for User {
drop(users);
let sessions = self.matchmake_manager.sessions.read().await;
for session in sessions.values() {
let sessions = self
.matchmake_manager
.search_by_criteria(&param.search_criteria[..])
.await?;
if let Some(session) = sessions.get(0) {
let mut session = session.lock().await;
if !session.is_joinable() {
continue;
}
println!("checking session!");
session
.add_players(&joining_players, param.join_message)
.await;
let mut bool_matched_criteria = false;
for criteria in &param.search_criteria {
if session.matches_criteria(criteria)? {
bool_matched_criteria = true;
}
}
if bool_matched_criteria {
println!("matched session: {:?}", session);
let is_joinable_by_all = join_all(
joining_players
.iter()
.filter_map(|f| f.upgrade())
.map(|v| session.is_joinable_by(v)),
)
.await
.iter()
.copied()
.fold(true, |a, b| a && b);
if is_joinable_by_all {
warn!(
"tripped unreachable host detection for one of the users who were trying to join"
);
}
session
.add_players(&joining_players, param.join_message)
.await;
return Ok(session.session.clone());
}
return Ok(session.session.clone());
}
drop(sessions);
@ -546,6 +542,27 @@ impl MatchmakeExtension for User {
Ok(())
}
async fn update_application_buffer(
&self,
gid: u32,
application_buffer: Vec<u8>,
) -> Result<(), ErrorCode> {
let session = self.matchmake_manager.get_session(gid).await?;
let mut session = session.lock().await;
if session.session.gathering.host_pid == self.pid {
return Err(ErrorCode::RendezVous_PermissionDenied);
}
if session.session.gathering.owner_pid == self.pid {
return Err(ErrorCode::RendezVous_PermissionDenied);
}
session.session.application_buffer = application_buffer;
Ok(())
}
async fn join_matchmake_session_ex(
&self,
gid: u32,

View file

@ -7,6 +7,7 @@ use rnex_core::rmc::structures::matchmake::{
use crate::rmc::protocols::notifications::NotificationEvent;
use crate::rmc::structures::any::Any;
use crate::rmc::structures::matchmake::{Gathering, MatchmakeSessionSearchCriteria};
use crate::rmc::structures::resultsrange::ResultsRange;
#[rmc_proto(109)]
pub trait MatchmakeExtension {
@ -15,6 +16,13 @@ pub trait MatchmakeExtension {
#[method_id(2)]
async fn open_participation(&self, gid: u32) -> Result<(), ErrorCode>;
#[method_id(4)]
async fn browse_matchmake_session(
&self,
borwse_criteria: MatchmakeSessionSearchCriteria,
result_range: ResultsRange,
) -> Result<Vec<Any<Gathering>>, ErrorCode>;
#[method_id(6)]
async fn create_matchmake_session(
&self,
@ -36,6 +44,12 @@ pub trait MatchmakeExtension {
&self,
ty: i32,
) -> Result<Vec<NotificationEvent>, ErrorCode>;
#[method_id(11)]
async fn update_application_buffer(
&self,
gid: u32,
application_buffer: Vec<u8>,
) -> Result<(), ErrorCode>;
#[method_id(15)]
async fn auto_matchmake_with_search_criteria_postpone(
&self,

View file

@ -2,7 +2,17 @@ use macros::RmcSerialize;
#[derive(RmcSerialize, Debug, Default, Clone)]
#[rmc_struct(0)]
pub struct ResultsRange{
pub struct ResultsRange {
pub offset: u32,
pub size: u32
}
pub size: u32,
}
impl ResultsRange {
pub fn make_from_list<T: Clone>(&self, list: &[T]) -> Vec<T> {
let end = usize::max(list.len(), self.offset as usize + self.size as usize);
list.get(self.offset as usize..end)
.unwrap_or_default()
.into()
}
}