Add NEX results and fix timers
This commit is contained in:
parent
aa18d1ee3e
commit
55b3959797
8 changed files with 586 additions and 52 deletions
|
|
@ -247,27 +247,29 @@ impl ExtendedMatchmakeSession {
|
|||
param_3: self.connected_players.len() as _,
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for old_conns in &old_particip {
|
||||
let Some(old_conns) = old_conns.upgrade() else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let older_pid = old_conns.pid;
|
||||
|
||||
initiating_user
|
||||
.remote
|
||||
.process_notification_event(NotificationEvent {
|
||||
pid_source: initiating_pid,
|
||||
notif_type: 3001,
|
||||
param_1: self.session.gathering.self_gid as PID,
|
||||
param_2: older_pid,
|
||||
str_param: join_msg.clone(),
|
||||
param_3: self.connected_players.len() as _,
|
||||
})
|
||||
.await;
|
||||
if old_conns.pid != self.session.gathering.host_pid{
|
||||
continue;
|
||||
}
|
||||
for new_conn_pid in conns.iter().filter_map(Weak::upgrade).map(|c| c.pid){
|
||||
old_conns
|
||||
.remote
|
||||
.process_notification_event(NotificationEvent {
|
||||
pid_source: initiating_pid,
|
||||
notif_type: 3001,
|
||||
param_1: self.session.gathering.self_gid as PID,
|
||||
param_2: new_conn_pid,
|
||||
str_param: join_msg.clone(),
|
||||
param_3: self.connected_players.len() as _,
|
||||
})
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn has_active_players(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,14 @@ use crate::nex::remote_console::RemoteConsole;
|
|||
use crate::rmc::protocols::matchmake::{
|
||||
Matchmake, RawMatchmake, RawMatchmakeInfo, RemoteMatchmake,
|
||||
};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use std::env;
|
||||
use std::str::FromStr;
|
||||
use crate::rmc::protocols::nat_traversal::{
|
||||
NatTraversal, RawNatTraversal, RawNatTraversalInfo, RemoteNatTraversal,
|
||||
RemoteNatTraversalConsole,
|
||||
};
|
||||
use rnex_core::kerberos::KerberosDateTime;
|
||||
use rnex_core::PID;
|
||||
use rnex_core::prudp::station_url::StationUrl;
|
||||
use rnex_core::prudp::station_url::UrlOptions::{
|
||||
|
|
@ -29,12 +33,15 @@ use rnex_core::rmc::structures::matchmake::{
|
|||
};
|
||||
|
||||
use crate::rmc::protocols::notifications::{NotificationEvent, RemoteNotification};
|
||||
use log::info;
|
||||
use log::{info, error};
|
||||
use macros::rmc_struct;
|
||||
use rnex_core::rmc::structures::qbuffer::QBuffer;
|
||||
use rnex_core::prudp::socket_addr::PRUDPSockAddr;
|
||||
use rnex_core::rmc::response::ErrorCode::{Core_InvalidArgument, RendezVous_AccountExpired};
|
||||
use rnex_core::rmc::structures::qresult::QResult;
|
||||
use std::sync::{Arc, Weak};
|
||||
use rnex_core::rmc::protocols::ranking::{CompetitionRankingScoreData, CompetitionRankingGetParam, CompetitionRankingScoreInfo};
|
||||
use rnex_core::rmc::structures::ranking::{UploadCompetitionData};
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
|
||||
define_rmc_proto!(
|
||||
|
|
@ -582,4 +589,145 @@ impl NatTraversal for User {
|
|||
}
|
||||
}
|
||||
|
||||
impl Ranking for User {}
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct CompetitionPostResults {
|
||||
pub splatfest_id: u32,
|
||||
pub score: u32,
|
||||
pub team_id: u8,
|
||||
pub team_win: u8,
|
||||
pub user: PID,
|
||||
}
|
||||
|
||||
// Seperate function because I cannot give a fuck right now
|
||||
fn fetch_team_votes(fest_id: u32) -> Result<Vec<u32>, ErrorCode> {
|
||||
let endpoint_votes = env::var("RNEX_SPLATOON_RESULTS_VOTES_GET").map_err(|_| {
|
||||
error!("RNEX_SPLATOON_RESULTS_VOTES_GET not set");
|
||||
ErrorCode::RendezVous_InvalidConfiguration
|
||||
})?;
|
||||
|
||||
let url_votes = format!("{}?splatfest_id={}", endpoint_votes, fest_id);
|
||||
let mut response = ureq::get(&url_votes).call().map_err(|e| {
|
||||
error!("GET for votes failed: {:?}", e);
|
||||
ErrorCode::RendezVous_InvalidConfiguration
|
||||
})?;
|
||||
|
||||
let body = response.body_mut().read_to_string().map_err(|e| {
|
||||
error!("failed to read votes body: {:?}", e);
|
||||
ErrorCode::RendezVous_InvalidConfiguration
|
||||
})?;
|
||||
|
||||
let body = body.trim().trim_start_matches('[').trim_end_matches(']');
|
||||
let votes: Result<Vec<u32>, _> = body
|
||||
.split(',')
|
||||
.map(|s| u32::from_str(s.trim()))
|
||||
.collect();
|
||||
|
||||
votes.map_err(|e| {
|
||||
error!("failed to parse votes: {:?}", e);
|
||||
ErrorCode::RendezVous_InvalidConfiguration
|
||||
})
|
||||
}
|
||||
|
||||
impl Ranking for User {
|
||||
async fn competition_ranking_get_param(
|
||||
&self,
|
||||
param: CompetitionRankingGetParam,
|
||||
) -> Result<Vec<CompetitionRankingScoreInfo>, ErrorCode> {
|
||||
let fest_id = param.festival_ids.get(0).copied().unwrap_or(0);
|
||||
|
||||
let endpoint_results = env::var("RNEX_SPLATOON_RESULTS_GET")
|
||||
.map_err(|_| {
|
||||
error!("RNEX_SPLATOON_RESULTS_GET not set");
|
||||
ErrorCode::RendezVous_InvalidConfiguration
|
||||
})?;
|
||||
|
||||
let url_results = format!("{}?splatfest_id={}", endpoint_results, fest_id);
|
||||
let response_results = ureq::get(&url_results).call();
|
||||
|
||||
let results: Vec<CompetitionPostResults> = match response_results {
|
||||
Ok(mut res) => res
|
||||
.body_mut()
|
||||
.read_json()
|
||||
.map_err(|e| {
|
||||
error!("failed to parse JSON: {:?}", e);
|
||||
ErrorCode::RendezVous_InvalidConfiguration
|
||||
})?,
|
||||
Err(e) => {
|
||||
error!("GET failed: {:?}", e);
|
||||
return Err(ErrorCode::RendezVous_InvalidConfiguration);
|
||||
}
|
||||
};
|
||||
|
||||
let team_votes = fetch_team_votes(fest_id)?;
|
||||
|
||||
let score_data: Vec<CompetitionRankingScoreData> = results
|
||||
.iter()
|
||||
.map(|r| CompetitionRankingScoreData {
|
||||
unk: 1,
|
||||
pid: r.user,
|
||||
score: r.score,
|
||||
modified: KerberosDateTime::now(),
|
||||
unk2: 1,
|
||||
appdata: QBuffer(vec![]),
|
||||
})
|
||||
.collect();
|
||||
|
||||
let info = CompetitionRankingScoreInfo {
|
||||
fest_id,
|
||||
score_data,
|
||||
unk: 0,
|
||||
team_wins: results.iter().map(|r| r.team_win as u32).collect(),
|
||||
team_votes,
|
||||
};
|
||||
|
||||
Ok(vec![info])
|
||||
}
|
||||
|
||||
async fn upload_competition_ranking_score(&self, param: UploadCompetitionData) -> Result<bool, ErrorCode> {
|
||||
info!("fest results for user {:?}:", self.pid);
|
||||
info!("fest id: {:?}", param.splatfest_id);
|
||||
info!("score: {:?}", param.score);
|
||||
info!("team id: {:?}", param.team_id);
|
||||
info!("did current team win: {:?}", param.team_win);
|
||||
|
||||
let endpoint = match env::var("RNEX_SPLATOON_RESULTS_POST") {
|
||||
Ok(url) => url,
|
||||
Err(_) => {
|
||||
error!("RNEX_SPLATOON_RESULTS_POST not set");
|
||||
return Ok(false);
|
||||
}
|
||||
};
|
||||
|
||||
let payload = CompetitionPostResults {
|
||||
splatfest_id: param.splatfest_id,
|
||||
score: param.score,
|
||||
team_id: param.team_id,
|
||||
team_win: param.team_win,
|
||||
user: self.pid,
|
||||
};
|
||||
|
||||
let json_body = match serde_json::to_string(&payload) {
|
||||
Ok(j) => j,
|
||||
Err(e) => {
|
||||
error!("error making json_body: {:?}", e);
|
||||
return Ok(false);
|
||||
}
|
||||
};
|
||||
|
||||
let response = ureq::post(&endpoint)
|
||||
.header("Content-Type", "application/json")
|
||||
.send(json_body);
|
||||
|
||||
match response {
|
||||
Ok(res) => {
|
||||
info!("POST worked: {}", res.status());
|
||||
}
|
||||
Err(e) => {
|
||||
error!("POST borked: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,8 @@ impl RMCMessage{
|
|||
error!("received incorrect rmc packet: expected size {} but found {}", size, header_size + rest_of_data.len());
|
||||
}
|
||||
|
||||
|
||||
// println!("rmc packet: protoid: {}, method id: {}", protocol_id, method_id);
|
||||
// println!("{}", hex::encode(&rest_of_data));
|
||||
|
||||
//stream.
|
||||
Ok(Self{
|
||||
|
|
|
|||
|
|
@ -1,33 +1,51 @@
|
|||
use macros::{rmc_struct, rmc_proto, RmcSerialize};
|
||||
use macros::{rmc_struct, rmc_proto, RmcSerialize, method_id};
|
||||
|
||||
use rnex_core::kerberos::KerberosDateTime;
|
||||
use rnex_core::rmc::structures::qbuffer::QBuffer;
|
||||
|
||||
use rnex_core::rmc::response::ErrorCode;
|
||||
use rnex_core::rmc::structures::ranking::UploadCompetitionData;
|
||||
|
||||
#[derive(RmcSerialize, Debug, Default, Clone)]
|
||||
struct ResultsRange{
|
||||
offset: u32,
|
||||
size: u32
|
||||
#[rmc_struct(0)]
|
||||
pub struct ResultsRange{
|
||||
pub offset: u32,
|
||||
pub size: u32
|
||||
}
|
||||
|
||||
#[derive(RmcSerialize, Debug, Default, Clone)]
|
||||
#[rmc_struct(1)]
|
||||
struct CompetitionRankingGetParam{
|
||||
unk: u32,
|
||||
range: ResultsRange,
|
||||
festival_ids: Vec<u32>,
|
||||
pub struct CompetitionRankingGetParam {
|
||||
pub unk: u32,
|
||||
pub range: ResultsRange,
|
||||
pub festival_ids: Vec<u32>,
|
||||
}
|
||||
|
||||
#[derive(RmcSerialize, Debug, Default, Clone)]
|
||||
#[rmc_struct(0)]
|
||||
struct CompetitionRankingScoreInfo{
|
||||
fest_id: u32,
|
||||
score_data: Vec<u32>,
|
||||
unk: u32,
|
||||
team_wins: Vec<u32>,
|
||||
team_votes: Vec<u32>
|
||||
pub struct CompetitionRankingScoreInfo{
|
||||
pub fest_id: u32,
|
||||
pub score_data: Vec<CompetitionRankingScoreData>,
|
||||
pub unk: u32,
|
||||
pub team_wins: Vec<u32>,
|
||||
pub team_votes: Vec<u32>
|
||||
}
|
||||
|
||||
|
||||
#[derive(RmcSerialize, Debug, Clone)]
|
||||
#[rmc_struct(0)]
|
||||
pub struct CompetitionRankingScoreData{
|
||||
pub unk: u32,
|
||||
pub pid: u32,
|
||||
pub score: u32,
|
||||
pub modified: KerberosDateTime,
|
||||
pub unk2: u8,
|
||||
pub appdata: QBuffer
|
||||
}
|
||||
|
||||
#[rmc_proto(112)]
|
||||
pub trait Ranking{
|
||||
//#[method_id(16)]
|
||||
//async fn competition_ranking_get_param(&self, param: CompetitionRankingGetParam) -> Result<Vec<CompetitionRankingScoreInfo>,ErrorCode>;
|
||||
}
|
||||
#[method_id(16)]
|
||||
async fn competition_ranking_get_param(&self, param: CompetitionRankingGetParam) -> Result<Vec<CompetitionRankingScoreInfo>,ErrorCode>;
|
||||
#[method_id(18)]
|
||||
async fn upload_competition_ranking_score(&self, param: UploadCompetitionData) -> Result<bool, ErrorCode>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,7 @@ use bytemuck::bytes_of;
|
|||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::rmc::structures::{Result, RmcSerialize};
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct QBuffer(pub Vec<u8>);
|
||||
|
||||
impl RmcSerialize for QBuffer{
|
||||
|
|
|
|||
|
|
@ -4,15 +4,15 @@ use rnex_core::rmc::structures::qbuffer::QBuffer;
|
|||
|
||||
#[derive(RmcSerialize, Debug)]
|
||||
#[rmc_struct(0)]
|
||||
struct UploadCompetitionData {
|
||||
winning_team: u32,
|
||||
splatfest_id: u32,
|
||||
unk_2: u32,
|
||||
unk_3: u32,
|
||||
team_id_1: u8,
|
||||
team_id_2: u8,
|
||||
unk_5: u32,
|
||||
player_data: QBuffer,
|
||||
pub struct UploadCompetitionData{
|
||||
pub unk_1/*?*/: u32,
|
||||
pub splatfest_id: u32,
|
||||
pub unk_2/*?*/: u32,
|
||||
pub score: u32,
|
||||
pub team_id: u8,
|
||||
pub team_win: u8,
|
||||
pub is_first_upload: bool,
|
||||
pub appdata: QBuffer,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Pod, Zeroable)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue