progress
Some checks failed
Build and Test / puyopuyo (push) Failing after 26s
Build and Test / splatoon-testfire (push) Failing after 27s
Build and Test / minecraft-wiiu (push) Failing after 2m34s
Build and Test / fast-racing-neo (push) Failing after 2m36s
Build and Test / mario-tennis (push) Failing after 2m38s
Build and Test / splatoon (push) Failing after 2m38s
Build and Test / wii-u-chat (push) Failing after 5m25s
Build and Test / friends (push) Successful in 6m34s
Build and Test / super-mario-maker (push) Failing after 6m43s
Build and Test / sonic-transformed (push) Failing after 6m58s
Build and Test / wii-sports-club (push) Failing after 7m9s
Some checks failed
Build and Test / puyopuyo (push) Failing after 26s
Build and Test / splatoon-testfire (push) Failing after 27s
Build and Test / minecraft-wiiu (push) Failing after 2m34s
Build and Test / fast-racing-neo (push) Failing after 2m36s
Build and Test / mario-tennis (push) Failing after 2m38s
Build and Test / splatoon (push) Failing after 2m38s
Build and Test / wii-u-chat (push) Failing after 5m25s
Build and Test / friends (push) Successful in 6m34s
Build and Test / super-mario-maker (push) Failing after 6m43s
Build and Test / sonic-transformed (push) Failing after 6m58s
Build and Test / wii-sports-club (push) Failing after 7m9s
This commit is contained in:
parent
3f07e45f08
commit
f1d16e40a1
36 changed files with 730 additions and 1392 deletions
1079
Cargo.lock
generated
1079
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -13,6 +13,8 @@ prudpv1 = { path = "../prudpv1", optional = true }
|
|||
proxy-common = { path = "../proxy-common" }
|
||||
cfg-if = "1.0.4"
|
||||
rnex-prudp = { path = "../rnex-prudp" }
|
||||
rnex-server = { path = "../rnex-server" }
|
||||
tracing = "0.1.44"
|
||||
|
||||
[features]
|
||||
prudpv0 = ["dep:prudpv0"]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use proxy::edge_node_dc_callback;
|
||||
use proxy_common::{ProxyStartupParam, setup_edge_node_connection};
|
||||
use rnex_core::common::with_setup;
|
||||
use rnex_server::with_setup;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
|
@ -11,6 +11,7 @@ async fn main() {
|
|||
setup_edge_node_connection(¶m, edge_node_dc_callback).await;
|
||||
|
||||
proxy::start_insecure(param).await;
|
||||
Ok(())
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::process::abort;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use log::error;
|
||||
use tracing::error;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "prudpv0")]{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use proxy::edge_node_dc_callback;
|
||||
use proxy_common::{ProxyStartupParam, setup_edge_node_connection};
|
||||
use rnex_core::common::with_setup;
|
||||
use rnex_server::with_setup;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
|
|
@ -10,6 +10,7 @@ async fn main() {
|
|||
|
||||
setup_edge_node_connection(¶m, edge_node_dc_callback).await;
|
||||
proxy::start_secure(param).await;
|
||||
Ok(())
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,17 @@ workspace = true
|
|||
|
||||
[dependencies]
|
||||
rnex-prudp = { path = "../rnex-prudp" }
|
||||
rnex-util = { path = "../rnex-util" }
|
||||
rnex-rmc = { path = "../rnex-rmc" }
|
||||
tokio = { version = "1.47.0", features = ["full"] }
|
||||
bytemuck = { version = "1.23.1", features = ["derive"] }
|
||||
typenum = "1.18.0"
|
||||
rc4 = "0.1.0"
|
||||
rc4 = "0.2.0"
|
||||
cfg-if = "1.0.4"
|
||||
proxy-common = {path = "../proxy-common"}
|
||||
hmac = "0.12.1"
|
||||
md-5 = "^0.10.6"
|
||||
hmac = "0.13.0"
|
||||
md-5 = "0.11.0"
|
||||
tracing = "0.1.44"
|
||||
|
||||
[features]
|
||||
prudpv0 = []
|
||||
|
|
|
|||
|
|
@ -3,13 +3,11 @@ use std::io::Write;
|
|||
use hmac::Mac;
|
||||
use md5::{Digest, Md5};
|
||||
use rc4::{KeyInit, Rc4, StreamCipher};
|
||||
use rnex_core::{
|
||||
PID,
|
||||
prudp::{
|
||||
encryption::{DEFAULT_KEY, EncryptionPair},
|
||||
types_flags::{TypesFlags, types::DATA},
|
||||
},
|
||||
use rnex_prudp::{
|
||||
encryption::{DEFAULT_KEY, EncryptionPair},
|
||||
types_flags::{TypesFlags, types::DATA},
|
||||
};
|
||||
use rnex_util::PID;
|
||||
use typenum::U5;
|
||||
|
||||
use crate::crypto::{
|
||||
|
|
@ -19,7 +17,7 @@ use crate::crypto::{
|
|||
};
|
||||
|
||||
pub struct InsecureInstance {
|
||||
pair: EncryptionPair<Rc4<U5>>,
|
||||
pair: EncryptionPair<Rc4>,
|
||||
self_signat: [u8; 4],
|
||||
#[allow(dead_code)]
|
||||
remote_signat: [u8; 4],
|
||||
|
|
@ -41,8 +39,8 @@ impl CryptoInstance for InsecureInstance {
|
|||
[0x78, 0x56, 0x34, 0x12]
|
||||
} else {
|
||||
let mut hash = Md5::new();
|
||||
hash.write(ACCESS_KEY.as_bytes()).unwrap();
|
||||
let mut hmac = <HmacMd5 as Mac>::new_from_slice(&hash.finalize().as_slice())
|
||||
hash.update(ACCESS_KEY.as_bytes());
|
||||
let mut hmac = HmacMd5::new_from_slice(&hash.finalize().as_slice())
|
||||
.expect("unable to create hmac md5");
|
||||
hmac.update(data);
|
||||
hmac.finalize().into_bytes()[0..4].try_into().unwrap()
|
||||
|
|
@ -57,7 +55,7 @@ pub struct Insecure();
|
|||
|
||||
impl Crypto for Insecure {
|
||||
type Instance = InsecureInstance;
|
||||
fn new() -> Self {
|
||||
async fn new() -> Self {
|
||||
Self()
|
||||
}
|
||||
fn calculate_checksum(&self, data: &[u8]) -> u8 {
|
||||
|
|
@ -72,7 +70,9 @@ impl Crypto for Insecure {
|
|||
) -> Option<(Self::Instance, Vec<u8>)> {
|
||||
Some((
|
||||
InsecureInstance {
|
||||
pair: EncryptionPair::init_both(|| Rc4::new(&DEFAULT_KEY)),
|
||||
pair: EncryptionPair::init_both(|| {
|
||||
Rc4::new_from_slice(DEFAULT_KEY).expect("incorrect key size")
|
||||
}),
|
||||
self_signat,
|
||||
remote_signat,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,17 +1,13 @@
|
|||
use hmac::Mac;
|
||||
use md5::{Digest, Md5};
|
||||
use rc4::{KeyInit, Rc4, StreamCipher};
|
||||
use rnex_core::{
|
||||
PID,
|
||||
executables::common::SECURE_SERVER_ACCOUNT,
|
||||
nex::account::Account,
|
||||
prudp::{
|
||||
encryption::EncryptionPair,
|
||||
ticket::read_secure_connection_data,
|
||||
types_flags::{TypesFlags, types::DATA},
|
||||
},
|
||||
rmc::structures::RmcSerialize,
|
||||
use rnex_prudp::{
|
||||
encryption::EncryptionPair,
|
||||
ticket::read_secure_connection_data,
|
||||
types_flags::{TypesFlags, types::DATA},
|
||||
};
|
||||
use rnex_rmc::serialization::RmcSerialize;
|
||||
use rnex_util::{PID, account::Account};
|
||||
use std::io::Write;
|
||||
use typenum::U16;
|
||||
|
||||
|
|
@ -22,7 +18,7 @@ use crate::crypto::{
|
|||
};
|
||||
|
||||
pub struct SecureInstance {
|
||||
pair: EncryptionPair<Rc4<U16>>,
|
||||
pair: EncryptionPair<Rc4>,
|
||||
uid: PID,
|
||||
self_signat: [u8; 4],
|
||||
#[allow(dead_code)]
|
||||
|
|
@ -45,8 +41,8 @@ impl CryptoInstance for SecureInstance {
|
|||
[0x78, 0x56, 0x34, 0x12]
|
||||
} else {
|
||||
let mut hash = Md5::new();
|
||||
hash.write(ACCESS_KEY.as_bytes()).unwrap();
|
||||
let mut hmac = <HmacMd5 as Mac>::new_from_slice(&hash.finalize().as_slice())
|
||||
hash.update(ACCESS_KEY.as_bytes());
|
||||
let mut hmac = HmacMd5::new_from_slice(&hash.finalize().as_slice())
|
||||
.expect("unable to create hmac md5");
|
||||
hmac.update(data);
|
||||
hmac.finalize().into_bytes()[0..4].try_into().unwrap()
|
||||
|
|
@ -57,12 +53,16 @@ impl CryptoInstance for SecureInstance {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct Secure(&'static Account);
|
||||
pub struct Secure(Account);
|
||||
|
||||
impl Crypto for Secure {
|
||||
type Instance = SecureInstance;
|
||||
fn new() -> Self {
|
||||
Self(&SECURE_SERVER_ACCOUNT)
|
||||
async fn new() -> Self {
|
||||
Self(
|
||||
Account::from_nexact(2, "Quazal Rendez-Vous")
|
||||
.await
|
||||
.expect("unable to get account info"),
|
||||
)
|
||||
}
|
||||
fn calculate_checksum(&self, data: &[u8]) -> u8 {
|
||||
common_checksum(ACCESS_KEY, data)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use cfg_if::cfg_if;
|
||||
use rnex_core::{PID, prudp::types_flags::TypesFlags};
|
||||
use rnex_prudp::types_flags::TypesFlags;
|
||||
use rnex_util::PID;
|
||||
|
||||
mod common_crypto;
|
||||
|
||||
|
|
@ -12,7 +13,7 @@ pub trait CryptoInstance: Send + 'static {
|
|||
|
||||
pub trait Crypto: Send + Sync + 'static {
|
||||
type Instance: CryptoInstance;
|
||||
fn new() -> Self;
|
||||
async fn new() -> Self;
|
||||
fn calculate_checksum(&self, data: &[u8]) -> u8;
|
||||
fn instantiate(
|
||||
&self,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use cfg_if::cfg_if;
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "prudpv0")] {
|
||||
use log::info;
|
||||
use tracing::info;
|
||||
use proxy_common::ProxyStartupParam;
|
||||
use std::env;
|
||||
use std::net::SocketAddrV4;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use bytemuck::{Pod, Zeroable, try_from_bytes, try_from_bytes_mut};
|
||||
use log::{info, warn};
|
||||
use rnex_core::prudp::{
|
||||
use rnex_prudp::{
|
||||
types_flags::{
|
||||
TypesFlags,
|
||||
flags::HAS_SIZE,
|
||||
|
|
@ -8,6 +7,7 @@ use rnex_core::prudp::{
|
|||
},
|
||||
virtual_port::VirtualPort,
|
||||
};
|
||||
use tracing::{info, warn};
|
||||
|
||||
use crate::crypto::{Crypto, CryptoInstance};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,24 +5,22 @@ use std::{
|
|||
time::Duration,
|
||||
};
|
||||
|
||||
use log::{error, info, warn};
|
||||
use proxy_common::{ProxyStartupParam, new_backend_connection};
|
||||
use rnex_core::{
|
||||
prudp::{
|
||||
socket_addr::PRUDPSockAddr,
|
||||
types_flags::{
|
||||
flags::{ACK, NEED_ACK, RELIABLE},
|
||||
types::{CONNECT, DATA, DISCONNECT, PING, SYN},
|
||||
},
|
||||
use rnex_prudp::{
|
||||
socket_addr::PRUDPSockAddr,
|
||||
types_flags::{
|
||||
flags::{ACK, NEED_ACK, RELIABLE},
|
||||
types::{CONNECT, DATA, DISCONNECT, PING, SYN},
|
||||
},
|
||||
util::{SendingBufferConnection, SplittableBufferConnection},
|
||||
};
|
||||
use rnex_util::{SendingBufferConnection, SplittableBufferConnection};
|
||||
use tokio::{
|
||||
net::UdpSocket,
|
||||
spawn,
|
||||
sync::{Mutex, RwLock},
|
||||
time::{Instant, sleep},
|
||||
};
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
use crate::{
|
||||
crypto::{Crypto, CryptoInstance},
|
||||
|
|
@ -528,7 +526,7 @@ impl<C: Crypto> Server<C> {
|
|||
.expect("unable to bind socket");
|
||||
Self {
|
||||
socket,
|
||||
crypto: C::new(),
|
||||
crypto: C::new().await,
|
||||
connections: RwLock::new(HashMap::new()),
|
||||
param,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,6 @@
|
|||
#![allow(async_fn_in_trait)]
|
||||
//#![warn(missing_docs)]
|
||||
|
||||
#[cfg(feature = "big_pid")]
|
||||
pub type PID = i64;
|
||||
#[cfg(not(feature = "big_pid"))]
|
||||
pub type PID = i32;
|
||||
|
||||
pub use ctor::ctor;
|
||||
|
||||
pub mod prudp;
|
||||
|
|
|
|||
|
|
@ -8,5 +8,8 @@ ctor = "1.0.8"
|
|||
rnex-rmc = { path = "../../rnex-rmc" }
|
||||
rnex-base-protos = { path = "../base-protos" }
|
||||
|
||||
[feature]
|
||||
datastore = []
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
|
|
@ -22,14 +22,14 @@ pub struct Permission {
|
|||
pub recipient_ids: Vec<PID>,
|
||||
}
|
||||
|
||||
#[derive(RmcSerialize, Clone, Default)]
|
||||
#[derive(RmcSerialize, Clone, Default, Debug)]
|
||||
#[rmc_struct(0)]
|
||||
pub struct RatingInfoWithSlot {
|
||||
pub slot: i8,
|
||||
pub rating: RatingInfo,
|
||||
}
|
||||
|
||||
#[derive(RmcSerialize, Clone, Default)]
|
||||
#[derive(RmcSerialize, Clone, Default, Debug)]
|
||||
#[rmc_struct(0)]
|
||||
pub struct RatingInfo {
|
||||
pub total_value: i64,
|
||||
|
|
@ -46,7 +46,7 @@ pub struct GetMetaParam {
|
|||
pub access_password: i64,
|
||||
}
|
||||
|
||||
#[derive(RmcSerialize, Clone, Default)]
|
||||
#[derive(RmcSerialize, Clone, Default, Debug)]
|
||||
#[rmc_struct(0)]
|
||||
pub struct GetMetaInfo {
|
||||
pub dataid: i64,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#![allow(async_fn_in_trait)]
|
||||
#![cfg(feature = "datastore")]
|
||||
|
||||
pub mod datastore;
|
||||
use datastore::{DataStore, RawDataStore, RawDataStoreInfo, RemoteDataStore};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#[cfg(not(feature = "rmc_struct_header"))]
|
||||
use std::io::Read;
|
||||
use std::{
|
||||
fmt::Arguments,
|
||||
|
|
@ -102,7 +101,7 @@ pub fn read_struct<T: Sized, R: Read + ?Sized>(
|
|||
version: u8,
|
||||
pred: impl FnOnce(&mut SubRead<R>) -> Result<T>,
|
||||
) -> Result<T> {
|
||||
use crate::rmc::structures::Error::VersionMismatch;
|
||||
use crate::serialization::Error::VersionMismatch;
|
||||
use v_byte_helpers::IS_BIG_ENDIAN;
|
||||
use v_byte_helpers::ReadExtensions;
|
||||
let ver: u8 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
|
|
|||
|
|
@ -122,13 +122,7 @@ impl Secure for BaseUser {
|
|||
println!("{:?}", station_urls);
|
||||
|
||||
/*
|
||||
let mut users = self.matchmake_manager.users.write().await;
|
||||
users.insert(cid, self.this.clone());
|
||||
drop(users);
|
||||
let mut users = self.matchmake_manager.users_by_pid.write().await;
|
||||
users.insert(self.pid, self.this.clone());
|
||||
drop(users);
|
||||
*/
|
||||
*/
|
||||
|
||||
let stations = get_station_urls(&station_urls, self.addr, self.pid, cid).await?;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,10 @@ rnex-base = { path = "../rnex-base" }
|
|||
rnex-base-protos = { path = "../../rnex-protocols/base-protos" }
|
||||
rnex-ds-protos = { path = "../../rnex-protocols/ds-protos" }
|
||||
rnex-server = { path = "../../rnex-server" }
|
||||
sqlx = "0.9.0"
|
||||
sqlx = { version = "0.9.0", features = ["chrono"] }
|
||||
tracing = "0.1.44"
|
||||
thiserror = "2.0.18"
|
||||
chrono = "0.4.45"
|
||||
aws-sdk-s3 = "1.138.0"
|
||||
aws-config = "1.9.0"
|
||||
sha2 = "0.11.0"
|
||||
hmac = "0.13.0"
|
||||
base64 = "0.22.1"
|
||||
|
|
@ -24,5 +22,8 @@ hex = "0.4.3"
|
|||
urlencoding = "2.1.3"
|
||||
futures = "0.3.32"
|
||||
|
||||
[features]
|
||||
datastore = []
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use chrono::Utc;
|
||||
use futures::future::join_all;
|
||||
use futures::{TryStreamExt, future::join_all};
|
||||
use rnex_base::user::BaseUser;
|
||||
use rnex_ds_protos::{
|
||||
LocalDatastoreProtocol,
|
||||
|
|
@ -11,8 +11,8 @@ use rnex_ds_protos::{
|
|||
DataStorePrepareGetParam, DataStoreRateObjectParam, DataStoreRatingTarget,
|
||||
DataStoreReportCourseParam, DataStoreReqGetInfo, DataStoreSearchParam,
|
||||
DataStoreUploadCourseRecordParam, GetMetaInfo, GetMetaParam, KeyValue, Permission,
|
||||
PersistenceTarget, PreparePostParam, RatingInfo, RatingInfoWithSlot,
|
||||
RatingInitParamWithSlot, ReqPostInfo,
|
||||
PersistenceTarget, PreparePostParam, RateCustomRankingParam, RatingInfo,
|
||||
RatingInfoWithSlot, RatingInitParamWithSlot, ReqPostInfo,
|
||||
},
|
||||
};
|
||||
use rnex_rmc::{qbuffer::QBuffer, qresult::QResult, response::ErrorCode, rmc_struct};
|
||||
|
|
@ -20,12 +20,13 @@ use rnex_server::PassthroughInitModule;
|
|||
use rnex_util::{PID, date_time::DateTime};
|
||||
use sqlx::query;
|
||||
use std::convert;
|
||||
use tracing::{error, info, warn};
|
||||
use tracing::{error, info, instrument, warn};
|
||||
|
||||
use crate::{DatastoreManager, s3presigner::S3Presigner};
|
||||
// todo: refactor this further to make some of the helper functions attached to the user and some to
|
||||
// the manager and also move the usages of pid into the helper functions attached to user
|
||||
|
||||
#[derive(Debug)]
|
||||
#[rmc_struct(DatastoreProtocol)]
|
||||
pub struct DatastoreUser {
|
||||
pub base: PassthroughInitModule<BaseUser>,
|
||||
|
|
@ -33,6 +34,7 @@ pub struct DatastoreUser {
|
|||
}
|
||||
|
||||
impl DatastoreUser {
|
||||
#[instrument]
|
||||
fn map_row_to_meta_info(
|
||||
&self,
|
||||
row_data_id: i64,
|
||||
|
|
@ -88,6 +90,7 @@ impl DatastoreUser {
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn check_object_availability(
|
||||
&self,
|
||||
data_id: i64,
|
||||
|
|
@ -121,6 +124,7 @@ impl DatastoreUser {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn get_object_ratings(
|
||||
&self,
|
||||
data_id: i64,
|
||||
|
|
@ -158,6 +162,7 @@ impl DatastoreUser {
|
|||
Ok(ratings)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn get_object_info_by_data_id(
|
||||
&self,
|
||||
data_id: i64,
|
||||
|
|
@ -210,6 +215,7 @@ impl DatastoreUser {
|
|||
))
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn get_object_info_by_persistence_target(
|
||||
&self,
|
||||
target: PersistenceTarget,
|
||||
|
|
@ -271,6 +277,7 @@ impl DatastoreUser {
|
|||
))
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn get_buffer_queues_by_data_id_and_slot(
|
||||
&self,
|
||||
data_id: i64,
|
||||
|
|
@ -300,13 +307,13 @@ impl DatastoreUser {
|
|||
Ok(buffer_queues)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn verify_object_permission(
|
||||
&self,
|
||||
owner_id: PID,
|
||||
viewer_id: PID,
|
||||
permission: &Permission,
|
||||
) -> Result<(), ErrorCode> {
|
||||
if owner_id == viewer_id {
|
||||
if owner_id == self.base.pid {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
@ -315,7 +322,7 @@ impl DatastoreUser {
|
|||
1 => Err(ErrorCode::DataStore_PermissionDenied), // Friends only, unimplemented
|
||||
2 => {
|
||||
// Recipient IDs can read
|
||||
if permission.recipient_ids.contains(&viewer_id) {
|
||||
if permission.recipient_ids.contains(&self.base.pid) {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorCode::DataStore_PermissionDenied)
|
||||
|
|
@ -327,6 +334,7 @@ impl DatastoreUser {
|
|||
}
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn filter_properties_by_result_option(&self, meta_info: &mut GetMetaInfo, result_option: u8) {
|
||||
if (result_option & 0x01) == 0 {
|
||||
meta_info.meta_binary = QBuffer(Vec::new());
|
||||
|
|
@ -339,6 +347,7 @@ impl DatastoreUser {
|
|||
// No idea what the other things do. :shrug:
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn init_object_rating_slot(&self, data_id: i64, rating_param: RatingInitParamWithSlot) {
|
||||
info!("running init object rating slot");
|
||||
sqlx::query!(
|
||||
|
|
@ -376,11 +385,12 @@ impl DatastoreUser {
|
|||
.map_err(|e| {
|
||||
error!("DB Error: {:?}", e);
|
||||
ErrorCode::DataStore_NotFound
|
||||
});
|
||||
})?;
|
||||
info!("done running");
|
||||
}
|
||||
|
||||
// Dawg...
|
||||
#[instrument]
|
||||
async fn get_custom_rankings_by_data_ids(
|
||||
&self,
|
||||
application_id: u32,
|
||||
|
|
@ -431,6 +441,7 @@ impl DatastoreUser {
|
|||
results
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn get_user_course_object_ids(&self, owner_pid: PID) -> Result<Vec<i64>, ErrorCode> {
|
||||
let rows = sqlx::query!(
|
||||
r#"
|
||||
|
|
@ -459,6 +470,7 @@ impl DatastoreUser {
|
|||
Ok(valid_ids)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn get_blacklist_1(&self) -> Vec<String> {
|
||||
vec![
|
||||
"けされ",
|
||||
|
|
@ -533,6 +545,7 @@ impl DatastoreUser {
|
|||
.collect()
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn get_blacklist_2(&self) -> Vec<String> {
|
||||
vec![
|
||||
"ゼロから",
|
||||
|
|
@ -548,6 +561,7 @@ impl DatastoreUser {
|
|||
.collect()
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
fn get_blacklist_3(&self) -> Vec<String> {
|
||||
vec![
|
||||
"いいね",
|
||||
|
|
@ -617,6 +631,7 @@ impl DatastoreUser {
|
|||
.collect()
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
// couldn't find a better way to do this im going crazyy
|
||||
async fn rate_object(
|
||||
&self,
|
||||
|
|
@ -651,6 +666,7 @@ impl DatastoreUser {
|
|||
Ok(rating)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn change_meta_object_check(
|
||||
&self,
|
||||
param: &DataStoreChangeMetaParam,
|
||||
|
|
@ -679,6 +695,7 @@ impl DatastoreUser {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
async fn get_rating_with_slot_data_id(
|
||||
&self,
|
||||
dataid: i64,
|
||||
|
|
@ -713,6 +730,7 @@ impl DatastoreUser {
|
|||
Ok(ratings)
|
||||
}
|
||||
|
||||
#[instrument]
|
||||
pub async fn insert_buffer(&self, dataid: i64, slot: i32, buffer: &QBuffer) {
|
||||
let db_now = Utc::now().naive_utc();
|
||||
|
||||
|
|
@ -756,8 +774,7 @@ impl DataStore for DatastoreUser {
|
|||
.await?
|
||||
};
|
||||
|
||||
let current_pid = self.pid;
|
||||
self.verify_object_permission(meta_info.owner, current_pid, &meta_info.permission)?;
|
||||
self.verify_object_permission(meta_info.owner, &meta_info.permission)?;
|
||||
|
||||
self.filter_properties_by_result_option(&mut meta_info, metaparam.result_option);
|
||||
|
||||
|
|
@ -794,7 +811,7 @@ impl DataStore for DatastoreUser {
|
|||
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17
|
||||
) RETURNING data_id
|
||||
"#,
|
||||
self.pid as i32,
|
||||
self.base.pid as i32,
|
||||
postparam.size as i32,
|
||||
postparam.name,
|
||||
postparam.data_type as i32,
|
||||
|
|
@ -815,7 +832,7 @@ impl DataStore for DatastoreUser {
|
|||
.fetch_one(&self.dm.db_pool)
|
||||
.await
|
||||
.map_err(|e| {
|
||||
log::error!("DB Error: {:?}", e);
|
||||
error!("DB Error: {:?}", e);
|
||||
ErrorCode::DataStore_NotFound
|
||||
})?;
|
||||
|
||||
|
|
@ -998,7 +1015,7 @@ impl DataStore for DatastoreUser {
|
|||
],
|
||||
10 => vec![35, 75, 96, 40, 5, 6],
|
||||
_ => {
|
||||
log::error!("unknown SMM app id: {}", appid);
|
||||
error!("unknown SMM app id: {}", appid);
|
||||
return Err(ErrorCode::DataStore_Unknown);
|
||||
}
|
||||
};
|
||||
|
|
@ -1081,7 +1098,7 @@ impl DataStore for DatastoreUser {
|
|||
};
|
||||
|
||||
info!("verifying object permission");
|
||||
self.verify_object_permission(meta_info.owner, self.base.pid, &meta_info.permission)?;
|
||||
self.verify_object_permission(meta_info.owner, &meta_info.permission)?;
|
||||
|
||||
let key = format!("data/{}.bin", meta_info.dataid);
|
||||
let download_url = self.dm.s3_presigner.generate_presigned_get(&key);
|
||||
|
|
@ -1123,8 +1140,7 @@ impl DataStore for DatastoreUser {
|
|||
res.meta_info.ratings = Vec::new();
|
||||
}
|
||||
if course_search_param.result_option & 0x4 == 0 {
|
||||
res.meta_info.meta_binary =
|
||||
rnex_core::rmc::structures::qbuffer::QBuffer(Vec::new());
|
||||
res.meta_info.meta_binary = QBuffer(Vec::new());
|
||||
}
|
||||
if course_search_param.result_option & 0x20 == 0 {
|
||||
res.score = 0;
|
||||
|
|
@ -1180,9 +1196,7 @@ impl DataStore for DatastoreUser {
|
|||
|
||||
match info_result {
|
||||
Ok(mut meta) => {
|
||||
if let Err(e) =
|
||||
self.verify_object_permission(meta.owner, self.base.pid, &meta.permission)
|
||||
{
|
||||
if let Err(e) = self.verify_object_permission(meta.owner, &meta.permission) {
|
||||
metas.push(GetMetaInfo::default());
|
||||
results.push(QResult::error(e));
|
||||
} else {
|
||||
|
|
@ -1255,7 +1269,7 @@ impl DataStore for DatastoreUser {
|
|||
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17
|
||||
) RETURNING data_id
|
||||
"#,
|
||||
self.pid as i32,
|
||||
self.base.pid as i32,
|
||||
param.post_param.size as i32,
|
||||
param.post_param.name,
|
||||
param.post_param.data_type as i32,
|
||||
|
|
@ -1349,11 +1363,7 @@ impl DataStore for DatastoreUser {
|
|||
.get_object_info_by_data_id(target.dataid, param.access_password)
|
||||
.await?;
|
||||
info!("object info get complete");
|
||||
self.verify_object_permission(
|
||||
object_info.owner,
|
||||
self.base.pid,
|
||||
&object_info.permission,
|
||||
)?;
|
||||
self.verify_object_permission(object_info.owner, &object_info.permission)?;
|
||||
info!("object permission complete");
|
||||
|
||||
if fetch_ratings {
|
||||
|
|
@ -1386,11 +1396,11 @@ impl DataStore for DatastoreUser {
|
|||
}
|
||||
|
||||
async fn change_meta(&self, param: DataStoreChangeMetaParam) -> Result<(), ErrorCode> {
|
||||
let object_info = get_object_info_by_data_id(param.dataid, 0).await?;
|
||||
verify_object_permission(object_info.owner, self.pid, &object_info.permission).await?;
|
||||
let object_info = self.get_object_info_by_data_id(param.dataid, 0).await?;
|
||||
self.verify_object_permission(object_info.owner, &object_info.permission)?;
|
||||
|
||||
if param.modifies_flag & 0x08 != 0 {
|
||||
change_meta_object_check(¶m).await?;
|
||||
self.change_meta_object_check(¶m).await?;
|
||||
|
||||
sqlx::query!(
|
||||
r#"UPDATE datastore.objects SET period=$1 WHERE data_id=$2"#,
|
||||
|
|
@ -1406,7 +1416,7 @@ impl DataStore for DatastoreUser {
|
|||
}
|
||||
|
||||
if param.modifies_flag & 0x10 != 0 {
|
||||
change_meta_object_check(¶m).await?;
|
||||
self.change_meta_object_check(¶m).await?;
|
||||
|
||||
sqlx::query!(
|
||||
r#"UPDATE datastore.objects SET meta_binary=$1 WHERE data_id=$2"#,
|
||||
|
|
@ -1422,7 +1432,7 @@ impl DataStore for DatastoreUser {
|
|||
}
|
||||
|
||||
if param.modifies_flag & 0x80 != 0 {
|
||||
change_meta_object_check(¶m).await?;
|
||||
self.change_meta_object_check(¶m).await?;
|
||||
|
||||
sqlx::query!(
|
||||
r#"UPDATE datastore.objects SET data_type=$1 WHERE data_id=$2"#,
|
||||
|
|
@ -1583,8 +1593,8 @@ impl DataStore for DatastoreUser {
|
|||
"#,
|
||||
upload_course_record_param.dataid,
|
||||
upload_course_record_param.slot as i16,
|
||||
self.pid,
|
||||
self.pid,
|
||||
self.base.pid,
|
||||
self.base.pid,
|
||||
upload_course_record_param.score,
|
||||
now,
|
||||
now
|
||||
|
|
@ -1641,7 +1651,7 @@ impl DataStore for DatastoreUser {
|
|||
) -> Result<Vec<QResult>, ErrorCode> {
|
||||
let mut results = Vec::new();
|
||||
|
||||
let client_pid = self.pid;
|
||||
let client_pid = self.base.pid;
|
||||
|
||||
for (param, buffer) in bufferparam.iter().zip(buffers.iter()) {
|
||||
if param.slot == 0 {
|
||||
|
|
@ -1713,7 +1723,7 @@ impl DataStore for DatastoreUser {
|
|||
)
|
||||
"#,
|
||||
report_course_param.dataid,
|
||||
self.pid,
|
||||
self.base.pid,
|
||||
report_course_param.report_category as i16,
|
||||
report_course_param.report_reason
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#![cfg(feature = "datastore")]
|
||||
use std::env;
|
||||
|
||||
use rnex_server::{ConnectionInitData, RnexManager, RnexModule};
|
||||
|
|
@ -9,20 +10,21 @@ use crate::{datastore::DatastoreUser, s3presigner::S3Presigner};
|
|||
pub mod datastore;
|
||||
pub(crate) mod s3presigner;
|
||||
|
||||
struct DatastoreManager {
|
||||
#[derive(Debug)]
|
||||
pub struct DatastoreManager {
|
||||
db_pool: PgPool,
|
||||
s3_presigner: S3Presigner,
|
||||
}
|
||||
struct DatastoreModule;
|
||||
pub struct DatastoreModule;
|
||||
impl RnexManager for DatastoreManager {
|
||||
type User = DatastoreUser;
|
||||
type InitData = ConnectionInitData;
|
||||
async fn init_new_user(
|
||||
this: rnex_server::PassthroughInitModule<Self>,
|
||||
mod_holder: &rnex_server::ModuleHolder,
|
||||
remote: &rnex_rmc::RmcConnection,
|
||||
init_data: &Self::InitData,
|
||||
weak_user: rnex_server::WeakPassthroughInitModule<Self::User>,
|
||||
_: &rnex_rmc::RmcConnection,
|
||||
_: &Self::InitData,
|
||||
_: rnex_server::WeakPassthroughInitModule<Self::User>,
|
||||
) -> Self::User {
|
||||
DatastoreUser {
|
||||
dm: this,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use hmac::{Hmac, KeyInit, Mac};
|
|||
use serde_json::json;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct S3Presigner {
|
||||
endpoint: String,
|
||||
bucket: String,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,22 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
bytemuck = { version = "1.25.1", features = ["derive"] }
|
||||
rnex-rmc = { path = "../../rnex-rmc" }
|
||||
rnex-util = { path = "../../rnex-util" }
|
||||
rnex-fpd-protos = { path = "../../rnex-protocols/fpd-protos" }
|
||||
rnex-base = { path = "../rnex-base" }
|
||||
rnex-server = { path = "../../rnex-server" }
|
||||
tokio = { version = "1.52.3", features = ["sync"] }
|
||||
rand = "0.10.2"
|
||||
tracing = "0.1.44"
|
||||
sqlx = { version = "0.9.0", features = ["chrono"] }
|
||||
chrono = "0.4.45"
|
||||
hmac = "0.13.0"
|
||||
md-5 = "0.11.0"
|
||||
nex-account = { version = "0.2.4", registry = "spbr" }
|
||||
hex = "0.4.3"
|
||||
thiserror = "2.0.18"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
|
|
@ -1,92 +1,38 @@
|
|||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, atomic::AtomicU32};
|
||||
use std::sync::{LazyLock, Weak};
|
||||
use std::time::Duration;
|
||||
use std::{env, mem};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
mem,
|
||||
sync::{Arc, Weak},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use crate::rmc::protocols::account_management::{
|
||||
AccountExtraInfo, AccountManagement, RawAccountManagement, RawAccountManagementInfo,
|
||||
RemoteAccountManagement,
|
||||
};
|
||||
use crate::rmc::protocols::friends_3ds::{
|
||||
Friends3DS, RawFriends3DS, RawFriends3DSInfo, RemoteFriends3DS,
|
||||
};
|
||||
use crate::rmc::protocols::friends_wiiu::{
|
||||
FriendsWiiU, RawFriendsWiiU, RawFriendsWiiUInfo, RemoteFriendsWiiU,
|
||||
};
|
||||
use crate::rmc::protocols::nintendo_notification::{
|
||||
NintendoNotification, RawNintendoNotification, RawNintendoNotificationInfo,
|
||||
RemoteNintendoNotification,
|
||||
};
|
||||
use crate::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure};
|
||||
use crate::{
|
||||
define_rmc_proto,
|
||||
kerberos::KerberosDateTime,
|
||||
nex::common::get_station_urls,
|
||||
prudp::{socket_addr::PRUDPSockAddr, station_url::StationUrl},
|
||||
rmc::{
|
||||
protocols::friends_wiiu::{
|
||||
BlacklistedPrincipal, Comment, FriendInfo, FriendRequest, NNAInfo, NintendoPresenceV2,
|
||||
PersistentNotification, PrincipalPreference, PrincipalRequestBlockSetting,
|
||||
},
|
||||
response::ErrorCode,
|
||||
structures::{any::Any, qresult::QResult},
|
||||
},
|
||||
};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use chrono::{TimeZone, Utc};
|
||||
use rnex_rmc::rmc_struct;
|
||||
use sqlx::query;
|
||||
use std::sync::atomic::Ordering::Relaxed;
|
||||
use tokio::spawn;
|
||||
use tokio::sync::RwLock;
|
||||
use tokio::time::sleep;
|
||||
use tracing::warn;
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::rmc::protocols::friends_wiiu::{GameKey, MiiV2, PrincipalBasicInfo};
|
||||
|
||||
use crate::PID;
|
||||
|
||||
use crate::rmc::protocols::account_management::NintendoCreateAccountData;
|
||||
use crate::rmc::protocols::nintendo_notification::NintendoNotificationEvent;
|
||||
|
||||
use crate::rmc::structures::data::Data;
|
||||
|
||||
use crate::executables::common::get_db;
|
||||
|
||||
use crate::rmc::protocols::friends_3ds::{
|
||||
FriendComment, FriendMii, FriendMiiList, FriendPersistentInfo, FriendPicture, FriendPresence,
|
||||
FriendRelationship, Mii, MiiList, MyProfile, NintendoPresence, PlayedGame,
|
||||
use nex_account::{derive_pid_hmac, grpc::ActCreateInfo, grpc_client};
|
||||
use rnex_fpd_protos::{
|
||||
LocalFriendsGuest, LocalFriendsUser, RemoteFriendRemote,
|
||||
account_management::{AccountExtraInfo, AccountManagement, NintendoCreateAccountData},
|
||||
friends_3ds::{
|
||||
self, FriendComment, FriendMii, FriendMiiList, FriendPersistentInfo, FriendPicture,
|
||||
FriendPresence, FriendRelationship, Friends3DS, Mii, MiiList, MyProfile, NintendoPresence,
|
||||
PlayedGame,
|
||||
},
|
||||
friends_wiiu::{
|
||||
self, BlacklistedPrincipal, Comment, FriendRequest, FriendRequestMessage, FriendsWiiU,
|
||||
MiiV2, NNAInfo, NintendoPresenceV2, PersistentNotification, PrincipalBasicInfo,
|
||||
PrincipalPreference, PrincipalRequestBlockSetting,
|
||||
},
|
||||
nintendo_notification::{
|
||||
NintendoNotificationEvent, NintendoNotificationEventGeneral, RemoteNintendoNotification,
|
||||
},
|
||||
};
|
||||
use crate::rmc::protocols::friends_wiiu::FriendRequestMessage;
|
||||
use crate::rmc::protocols::nintendo_notification::NintendoNotificationEventGeneral;
|
||||
use crate::rmc::response::ErrorCode::FPD_InvalidArgument;
|
||||
use crate::rmc::structures::qbuffer::QBuffer;
|
||||
use nex_account::grpc::ActCreateInfo;
|
||||
use nex_account::{derive_pid_hmac, grpc_client};
|
||||
use rnex_rmc::{any::Any, data::Data, qbuffer::QBuffer, response::ErrorCode, rmc_struct};
|
||||
use rnex_server::{PassthroughInitModule, WeakPassthroughInitModule};
|
||||
use rnex_util::{PID, date_time::DateTime};
|
||||
use sqlx::query;
|
||||
use tokio::{spawn, sync::RwLock, time::sleep};
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
define_rmc_proto!(
|
||||
proto FriendsUser{
|
||||
Secure,
|
||||
FriendsWiiU,
|
||||
Friends3DS
|
||||
}
|
||||
);
|
||||
define_rmc_proto!(
|
||||
proto FriendRemote{
|
||||
NintendoNotification
|
||||
}
|
||||
);
|
||||
define_rmc_proto!(
|
||||
proto FriendsGuest{
|
||||
Secure,
|
||||
AccountManagement
|
||||
}
|
||||
);
|
||||
|
||||
static NEX_ACCOUNT_URL: LazyLock<String> =
|
||||
LazyLock::new(|| env::var("NEX_ACCOUNT_ENDPOINT").expect("NEX_ACCOUNT_ENDPOINT not set"));
|
||||
use crate::FriendsManager;
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Pod, Zeroable, Copy, Clone, Debug)]
|
||||
|
|
@ -96,10 +42,11 @@ pub struct NascToken {
|
|||
pub pwd_hash: [u8; 4],
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[rmc_struct(FriendsUser)]
|
||||
pub struct FriendsUser {
|
||||
pub fm: Arc<FriendsManager>,
|
||||
pub addr: PRUDPSockAddr,
|
||||
pub fm: PassthroughInitModule<FriendsManager>,
|
||||
//pub addr: PRUDPSockAddr,
|
||||
pub pid: PID,
|
||||
pub friend_pids: RwLock<Vec<PID>>,
|
||||
pub maybe_remote_friend: RwLock<HashMap<PID, Weak<FriendsUser>>>,
|
||||
|
|
@ -108,27 +55,14 @@ pub struct FriendsUser {
|
|||
pub remote: RemoteFriendRemote,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[rmc_struct(FriendsGuest)]
|
||||
pub struct FriendsGuest {
|
||||
pub fm: Arc<FriendsManager>,
|
||||
pub addr: PRUDPSockAddr,
|
||||
}
|
||||
|
||||
pub struct FriendsManager {
|
||||
pub cid_counter: AtomicU32,
|
||||
pub users: RwLock<HashMap<PID, Weak<FriendsUser>>>,
|
||||
}
|
||||
|
||||
impl FriendsManager {
|
||||
pub fn next_cid(&self) -> u32 {
|
||||
self.cid_counter.fetch_add(1, Relaxed)
|
||||
}
|
||||
}
|
||||
pub struct FriendsGuest;
|
||||
|
||||
impl FriendsManager {
|
||||
async fn denies_friend_requests(&self, pid: PID) -> Result<bool, ErrorCode> {
|
||||
query!("select principal_preference_block_friend_requests from nintendo_network_accounts where pid = $1", pid)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.db)
|
||||
.await
|
||||
.map_err(|_| ErrorCode::FPD_InvalidAccount)
|
||||
.map(|v| v.principal_preference_block_friend_requests)
|
||||
|
|
@ -165,7 +99,7 @@ impl Friends3DS for FriendsUser {
|
|||
|
||||
async fn get_friend_mii(
|
||||
&self,
|
||||
_friends: Vec<crate::rmc::protocols::friends_3ds::FriendInfo>,
|
||||
_friends: Vec<friends_3ds::FriendInfo>,
|
||||
) -> Result<Vec<FriendMii>, ErrorCode> {
|
||||
// sorry for the copying pretendo but i don't have a mii on hand rn
|
||||
let data: Vec<u8> = vec![
|
||||
|
|
@ -196,7 +130,7 @@ impl Friends3DS for FriendsUser {
|
|||
|
||||
async fn get_friend_mii_list(
|
||||
&self,
|
||||
_friends: Vec<crate::rmc::protocols::friends_3ds::FriendInfo>,
|
||||
_friends: Vec<friends_3ds::FriendInfo>,
|
||||
) -> Result<Vec<FriendMiiList>, ErrorCode> {
|
||||
Err(ErrorCode::Core_NotImplemented)
|
||||
}
|
||||
|
|
@ -204,7 +138,7 @@ impl Friends3DS for FriendsUser {
|
|||
async fn is_active_game(
|
||||
&self,
|
||||
_unk: Vec<u32>,
|
||||
_game_key: crate::rmc::protocols::friends_3ds::GameKey,
|
||||
_game_key: friends_3ds::GameKey,
|
||||
) -> Result<Vec<u32>, ErrorCode> {
|
||||
Err(ErrorCode::Core_NotImplemented)
|
||||
}
|
||||
|
|
@ -298,9 +232,9 @@ impl Friends3DS for FriendsUser {
|
|||
|
||||
async fn update_favorite_game_key(
|
||||
&self,
|
||||
game_key: rnex_core::rmc::protocols::friends_3ds::GameKey,
|
||||
game_key: friends_3ds::GameKey,
|
||||
) -> Result<(), ErrorCode> {
|
||||
log::info!("favorite game key: {:?}", game_key);
|
||||
info!("favorite game key: {:?}", game_key);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -314,7 +248,7 @@ impl Friends3DS for FriendsUser {
|
|||
}
|
||||
|
||||
async fn get_friend_presence(&self, unk: Vec<u32>) -> Result<Vec<FriendPresence>, ErrorCode> {
|
||||
log::info!("pids: {:?}", unk);
|
||||
info!("pids: {:?}", unk);
|
||||
|
||||
let presence = FriendPresence {
|
||||
data: Data {},
|
||||
|
|
@ -322,7 +256,7 @@ impl Friends3DS for FriendsUser {
|
|||
presence: NintendoPresence {
|
||||
data: Data {},
|
||||
changed_bit_flag: 0xFFFF_FFFF,
|
||||
game_key: rnex_core::rmc::protocols::friends_3ds::GameKey {
|
||||
game_key: friends_3ds::GameKey {
|
||||
data: Data {},
|
||||
title_id: 1_125_899_907_457_280,
|
||||
version: 2064,
|
||||
|
|
@ -343,7 +277,7 @@ impl Friends3DS for FriendsUser {
|
|||
|
||||
async fn get_friend_comment(
|
||||
&self,
|
||||
_unk: Vec<crate::rmc::protocols::friends_3ds::FriendInfo>,
|
||||
_unk: Vec<friends_3ds::FriendInfo>,
|
||||
) -> Result<Vec<FriendComment>, ErrorCode> {
|
||||
Err(ErrorCode::Core_NotImplemented)
|
||||
}
|
||||
|
|
@ -364,15 +298,15 @@ impl Friends3DS for FriendsUser {
|
|||
area: 0,
|
||||
language: 0,
|
||||
platform: 0,
|
||||
game_key: rnex_core::rmc::protocols::friends_3ds::GameKey {
|
||||
game_key: friends_3ds::GameKey {
|
||||
data: Data {},
|
||||
title_id: 1_125_899_907_457_280,
|
||||
version: 2064,
|
||||
},
|
||||
message: "yo whats up".to_string(),
|
||||
msg_updated_at: KerberosDateTime::now(),
|
||||
friended_at: KerberosDateTime::now(),
|
||||
last_online: KerberosDateTime::now(),
|
||||
msg_updated_at: DateTime::now(),
|
||||
friended_at: DateTime::now(),
|
||||
last_online: DateTime::now(),
|
||||
};
|
||||
|
||||
Ok(vec![dummypersistentinfo])
|
||||
|
|
@ -399,7 +333,7 @@ macro_rules! basic_principal_from_record {
|
|||
nnid: $record.nnid.clone(),
|
||||
mii: MiiV2 {
|
||||
data: Data {},
|
||||
date_time: KerberosDateTime(bytemuck::cast($record.mii_unk_datetime)),
|
||||
date_time: DateTime(bytemuck::cast($record.mii_unk_datetime)),
|
||||
mii_data: $record.mii_ffl_data.clone(),
|
||||
name: QBuffer($record.mii_name.clone()),
|
||||
unk: mii_unk1,
|
||||
|
|
@ -424,7 +358,7 @@ macro_rules! nna_info_from_record {
|
|||
|
||||
macro_rules! game_key_from_record {
|
||||
($record:expr) => {
|
||||
GameKey {
|
||||
friends_wiiu::GameKey {
|
||||
data: Data {},
|
||||
tid: $record.game_key_tid,
|
||||
version: $record.game_key_version,
|
||||
|
|
@ -440,7 +374,7 @@ macro_rules! friend_request_from_record {
|
|||
basic_info: basic_principal_from_record!($record),
|
||||
request_message: FriendRequestMessage {
|
||||
data: Data {},
|
||||
expires_on: KerberosDateTime::from_naive(
|
||||
expires_on: DateTime::from_naive(
|
||||
Utc.timestamp_opt(Utc::now().timestamp() + 2592000, 0)
|
||||
.unwrap()
|
||||
.naive_utc(),
|
||||
|
|
@ -452,9 +386,9 @@ macro_rules! friend_request_from_record {
|
|||
unk,
|
||||
unk2,
|
||||
unk3: $record.unk_2,
|
||||
unk4: KerberosDateTime(bytemuck::cast($record.unk_3)),
|
||||
unk4: DateTime(bytemuck::cast($record.unk_3)),
|
||||
},
|
||||
sent_on: KerberosDateTime::from_naive($record.creation_time),
|
||||
sent_on: DateTime::from_naive($record.creation_time),
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
|
@ -464,12 +398,12 @@ impl FriendsWiiU for FriendsUser {
|
|||
&self,
|
||||
info: NNAInfo,
|
||||
presence: NintendoPresenceV2,
|
||||
birthday: KerberosDateTime,
|
||||
birthday: DateTime,
|
||||
) -> Result<
|
||||
(
|
||||
PrincipalPreference,
|
||||
Comment,
|
||||
Vec<FriendInfo>,
|
||||
Vec<friends_wiiu::FriendInfo>,
|
||||
Vec<FriendRequest>,
|
||||
Vec<FriendRequest>,
|
||||
Vec<BlacklistedPrincipal>,
|
||||
|
|
@ -512,7 +446,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
smoosh_to_i16(info.unk, info.unk2),
|
||||
bytemuck::cast::<_, i64>(birthday)
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await else {
|
||||
println!("psql failed(unable to update user)");
|
||||
return Err(ErrorCode::Core_SystemError)
|
||||
|
|
@ -528,7 +462,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
",
|
||||
self.pid
|
||||
)
|
||||
.fetch_all(get_db())
|
||||
.fetch_all(&self.fm.db)
|
||||
.await
|
||||
.map(|v| {
|
||||
v.into_iter()
|
||||
|
|
@ -549,7 +483,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
",
|
||||
self.pid
|
||||
)
|
||||
.fetch_all(get_db())
|
||||
.fetch_all(&self.fm.db)
|
||||
.await
|
||||
.map(|v| {
|
||||
v.into_iter()
|
||||
|
|
@ -580,7 +514,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
inner join nintendo_network_accounts on friendships.pid = nintendo_network_accounts.pid",
|
||||
self.pid
|
||||
)
|
||||
.fetch_all(get_db())
|
||||
.fetch_all(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
println!("error whilest getting friends");
|
||||
|
|
@ -624,7 +558,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
drop(remo_friends);
|
||||
}
|
||||
|
||||
friends.push(FriendInfo {
|
||||
friends.push(friends_wiiu::FriendInfo {
|
||||
data: Data {},
|
||||
nna_info: nna_info_from_record!(friend),
|
||||
presence,
|
||||
|
|
@ -632,10 +566,10 @@ impl FriendsWiiU for FriendsUser {
|
|||
data: Data {},
|
||||
unk: (bytemuck::cast::<_, u16>(friend.comment_unk) & 0xFF) as u8,
|
||||
message: friend.comment_message,
|
||||
last_changed: KerberosDateTime::from_naive(friend.comment_lastchanged),
|
||||
last_changed: DateTime::from_naive(friend.comment_lastchanged),
|
||||
},
|
||||
became_friends: KerberosDateTime::from_naive(friend_since),
|
||||
last_online: KerberosDateTime::from_naive(friend.last_online),
|
||||
became_friends: DateTime::from_naive(friend_since),
|
||||
last_online: DateTime::from_naive(friend.last_online),
|
||||
unk: 0,
|
||||
});
|
||||
}
|
||||
|
|
@ -650,13 +584,13 @@ impl FriendsWiiU for FriendsUser {
|
|||
",
|
||||
self.pid
|
||||
)
|
||||
.fetch_all(get_db())
|
||||
.fetch_all(&self.fm.db)
|
||||
.await
|
||||
.map(|v| {
|
||||
v.into_iter()
|
||||
.map(|v| BlacklistedPrincipal {
|
||||
basic_info: basic_principal_from_record!(v),
|
||||
since: KerberosDateTime::from_naive(v.since),
|
||||
since: DateTime::from_naive(v.since),
|
||||
..Default::default()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
|
|
@ -681,7 +615,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
},
|
||||
Comment {
|
||||
data: Data {},
|
||||
last_changed: KerberosDateTime::from_naive(query.comment_lastchanged),
|
||||
last_changed: DateTime::from_naive(query.comment_lastchanged),
|
||||
message: query.comment_message,
|
||||
unk: (bytemuck::cast::<_, u16>(query.comment_unk) & 0xFF) as u8,
|
||||
},
|
||||
|
|
@ -697,15 +631,18 @@ impl FriendsWiiU for FriendsUser {
|
|||
)))
|
||||
}
|
||||
|
||||
async fn add_friend(&self, friend: PID) -> Result<(FriendRequest, FriendInfo), ErrorCode> {
|
||||
async fn add_friend(
|
||||
&self,
|
||||
friend: PID,
|
||||
) -> Result<(FriendRequest, friends_wiiu::FriendInfo), ErrorCode> {
|
||||
self.add_friend_request(
|
||||
friend,
|
||||
0,
|
||||
"".into(),
|
||||
0,
|
||||
"".into(),
|
||||
GameKey::default(),
|
||||
KerberosDateTime::now(),
|
||||
friends_wiiu::GameKey::default(),
|
||||
DateTime::now(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
@ -713,12 +650,12 @@ impl FriendsWiiU for FriendsUser {
|
|||
async fn add_friend_by_name(
|
||||
&self,
|
||||
name: String,
|
||||
) -> Result<(FriendRequest, FriendInfo), ErrorCode> {
|
||||
) -> Result<(FriendRequest, friends_wiiu::FriendInfo), ErrorCode> {
|
||||
let Ok(pid) = query!(
|
||||
"select pid from nintendo_network_accounts where nnid = $1",
|
||||
name
|
||||
)
|
||||
.fetch_optional(get_db())
|
||||
.fetch_optional(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
println!("db error when trying to look up nnid");
|
||||
|
|
@ -737,7 +674,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
self.pid,
|
||||
friend
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
return Err(ErrorCode::FPD_InvalidMessageID);
|
||||
|
|
@ -790,9 +727,9 @@ impl FriendsWiiU for FriendsUser {
|
|||
message: String,
|
||||
_unk2: u8,
|
||||
unk3: String,
|
||||
game_key: GameKey,
|
||||
unk4: KerberosDateTime,
|
||||
) -> Result<(FriendRequest, FriendInfo), ErrorCode> {
|
||||
game_key: friends_wiiu::GameKey,
|
||||
unk4: DateTime,
|
||||
) -> Result<(FriendRequest, friends_wiiu::FriendInfo), ErrorCode> {
|
||||
let unk1 = 0;
|
||||
let unk2 = 1;
|
||||
|
||||
|
|
@ -805,12 +742,12 @@ impl FriendsWiiU for FriendsUser {
|
|||
"insert into friendships (pid_a, pid_b) values(99, $1)",
|
||||
self.pid
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
let Ok(v) = query!("select * from nintendo_network_accounts where pid = 99")
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
|
|
@ -829,22 +766,22 @@ impl FriendsWiiU for FriendsUser {
|
|||
drop(friends);
|
||||
|
||||
let Ok(r) = query!("select * from nintendo_network_accounts where pid = 99")
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&this.fm.db)
|
||||
.await
|
||||
else {
|
||||
return;
|
||||
};
|
||||
let data = Any::new(&FriendInfo {
|
||||
let data = Any::new(&friends_wiiu::FriendInfo {
|
||||
data: Data {},
|
||||
nna_info: nna_info_from_record!(r),
|
||||
became_friends: KerberosDateTime::now(),
|
||||
became_friends: DateTime::now(),
|
||||
comment: Comment {
|
||||
data: Data {},
|
||||
last_changed: KerberosDateTime::from_naive(r.comment_lastchanged),
|
||||
last_changed: DateTime::from_naive(r.comment_lastchanged),
|
||||
message: r.comment_message,
|
||||
unk: (bytemuck::cast::<_, u16>(r.comment_unk) & 0xFF) as u8,
|
||||
},
|
||||
last_online: KerberosDateTime::now(),
|
||||
last_online: DateTime::now(),
|
||||
presence: NintendoPresenceV2::default(),
|
||||
unk: 0,
|
||||
})
|
||||
|
|
@ -870,21 +807,21 @@ impl FriendsWiiU for FriendsUser {
|
|||
unk2: 1,
|
||||
unk3: "Dummy".into(),
|
||||
game_key,
|
||||
unk4: KerberosDateTime::now(),
|
||||
expires_on: KerberosDateTime::now(),
|
||||
unk4: DateTime::now(),
|
||||
expires_on: DateTime::now(),
|
||||
},
|
||||
data: Data {},
|
||||
sent_on: KerberosDateTime::now(),
|
||||
sent_on: DateTime::now(),
|
||||
},
|
||||
FriendInfo {
|
||||
became_friends: KerberosDateTime::now(),
|
||||
friends_wiiu::FriendInfo {
|
||||
became_friends: DateTime::now(),
|
||||
comment: Comment {
|
||||
data: Data {},
|
||||
unk: bytemuck::cast::<_, u16>(v.comment_unk & 0xFF) as u8,
|
||||
message: v.comment_message,
|
||||
last_changed: KerberosDateTime::from_naive(v.comment_lastchanged),
|
||||
last_changed: DateTime::from_naive(v.comment_lastchanged),
|
||||
},
|
||||
last_online: KerberosDateTime::now(),
|
||||
last_online: DateTime::now(),
|
||||
nna_info: nna_info_from_record!(v),
|
||||
..Default::default()
|
||||
},
|
||||
|
|
@ -896,7 +833,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
friend,
|
||||
self.pid
|
||||
)
|
||||
.fetch_optional(get_db())
|
||||
.fetch_optional(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
return Err(ErrorCode::Authentication_AccountLibraryError);
|
||||
|
|
@ -911,7 +848,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
"select count(recipient) from friend_requests where sender = $1",
|
||||
self.pid
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
println!("friend request count check failed to execute on database");
|
||||
|
|
@ -924,7 +861,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
"select count(recipient) from friend_requests where recipient = $1",
|
||||
friend
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
println!("friend request count check failed to execute on database");
|
||||
|
|
@ -955,7 +892,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
game_key.tid,
|
||||
game_key.version
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await;
|
||||
|
||||
let query = match query {
|
||||
|
|
@ -993,7 +930,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
"select * from nintendo_network_accounts where pid = $1",
|
||||
self.pid
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
println!("failed to acquire account info after adding friend");
|
||||
|
|
@ -1012,7 +949,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
|
||||
dbg!(Ok((
|
||||
fr,
|
||||
FriendInfo {
|
||||
friends_wiiu::FriendInfo {
|
||||
presence: NintendoPresenceV2 {
|
||||
game_key,
|
||||
app_data: vec![0x00],
|
||||
|
|
@ -1029,7 +966,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
bytemuck::cast::<_, i64>(id),
|
||||
self.pid
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
return Err(ErrorCode::FPD_InvalidMessageID);
|
||||
|
|
@ -1055,8 +992,8 @@ impl FriendsWiiU for FriendsUser {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn accept_friend_request(&self, id: u64) -> Result<FriendInfo, ErrorCode> {
|
||||
let Ok(mut tx) = get_db().begin().await else {
|
||||
async fn accept_friend_request(&self, id: u64) -> Result<friends_wiiu::FriendInfo, ErrorCode> {
|
||||
let Ok(mut tx) = self.fm.db.begin().await else {
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
let Ok(query) = query!(
|
||||
|
|
@ -1120,17 +1057,17 @@ impl FriendsWiiU for FriendsUser {
|
|||
println!("internal server error whilest getting nna info");
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
let data = Any::new(&FriendInfo {
|
||||
let data = Any::new(&friends_wiiu::FriendInfo {
|
||||
data: Data {},
|
||||
nna_info: nna_info_from_record!(r),
|
||||
became_friends: KerberosDateTime::now(),
|
||||
became_friends: DateTime::now(),
|
||||
comment: Comment {
|
||||
data: Data {},
|
||||
last_changed: KerberosDateTime::from_naive(r.comment_lastchanged),
|
||||
last_changed: DateTime::from_naive(r.comment_lastchanged),
|
||||
message: r.comment_message,
|
||||
unk: (bytemuck::cast::<_, u16>(r.comment_unk) & 0xFF) as u8,
|
||||
},
|
||||
last_online: KerberosDateTime::now(),
|
||||
last_online: DateTime::now(),
|
||||
presence: self.presence.read().await.clone().unwrap_or_default(),
|
||||
unk: 0,
|
||||
})
|
||||
|
|
@ -1155,18 +1092,18 @@ impl FriendsWiiU for FriendsUser {
|
|||
|
||||
tx.commit().await.ok();
|
||||
|
||||
Ok(FriendInfo {
|
||||
Ok(friends_wiiu::FriendInfo {
|
||||
data: Data {},
|
||||
nna_info: nna_info_from_record!(query),
|
||||
presence,
|
||||
comment: Comment {
|
||||
data: Data {},
|
||||
last_changed: KerberosDateTime::from_naive(query.comment_lastchanged),
|
||||
last_changed: DateTime::from_naive(query.comment_lastchanged),
|
||||
message: query.comment_message,
|
||||
unk: (bytemuck::cast::<_, u16>(query.comment_unk) & 0xFF) as u8,
|
||||
},
|
||||
became_friends: KerberosDateTime::now(),
|
||||
last_online: KerberosDateTime::from_naive(query.last_online),
|
||||
became_friends: DateTime::now(),
|
||||
last_online: DateTime::from_naive(query.last_online),
|
||||
unk: 0,
|
||||
})
|
||||
}
|
||||
|
|
@ -1176,7 +1113,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
"delete from friend_requests where id = $1 returning sender, recipient",
|
||||
bytemuck::cast::<_, i64>(id),
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
return Err(ErrorCode::FPD_InvalidMessageID);
|
||||
|
|
@ -1216,7 +1153,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
bytemuck::cast::<_, i64>(id),
|
||||
self.pid
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
return Err(ErrorCode::FPD_InvalidMessageID);
|
||||
|
|
@ -1235,7 +1172,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
self.pid,
|
||||
query.sender
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
{
|
||||
println!("{}", e);
|
||||
|
|
@ -1264,18 +1201,18 @@ impl FriendsWiiU for FriendsUser {
|
|||
"select * from nintendo_network_accounts where pid = $1",
|
||||
query.sender
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
println!("attempt to get invalid user which is in friend request");
|
||||
return Err(FPD_InvalidArgument);
|
||||
return Err(ErrorCode::FPD_InvalidArgument);
|
||||
};
|
||||
|
||||
Ok(BlacklistedPrincipal {
|
||||
data: Data {},
|
||||
basic_info: basic_principal_from_record!(user),
|
||||
game_key: GameKey::default(),
|
||||
since: KerberosDateTime::now(),
|
||||
game_key: friends_wiiu::GameKey::default(),
|
||||
since: DateTime::now(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -1285,7 +1222,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
"update friend_requests set is_recieved = true where id = $1",
|
||||
bytemuck::cast::<_, i64>(id)
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
.ok();
|
||||
}
|
||||
|
|
@ -1301,7 +1238,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
self.pid,
|
||||
principal.basic_info.pid
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
{
|
||||
println!("{}", e);
|
||||
|
|
@ -1312,18 +1249,18 @@ impl FriendsWiiU for FriendsUser {
|
|||
"select * from nintendo_network_accounts where pid = $1",
|
||||
principal.basic_info.pid
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
println!("attempt to get invalid user which is in friend request");
|
||||
return Err(FPD_InvalidArgument);
|
||||
return Err(ErrorCode::FPD_InvalidArgument);
|
||||
};
|
||||
|
||||
Ok(BlacklistedPrincipal {
|
||||
data: Data {},
|
||||
basic_info: basic_principal_from_record!(user),
|
||||
game_key: GameKey::default(),
|
||||
since: KerberosDateTime::now(),
|
||||
game_key: friends_wiiu::GameKey::default(),
|
||||
since: DateTime::now(),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -1333,7 +1270,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
self.pid,
|
||||
id
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
{
|
||||
println!("{}", e);
|
||||
|
|
@ -1343,16 +1280,16 @@ impl FriendsWiiU for FriendsUser {
|
|||
}
|
||||
|
||||
async fn update_presence(&self, mut presence: NintendoPresenceV2) -> Result<(), ErrorCode> {
|
||||
if !query!("select principal_preference_show_currently_playing_title from nintendo_network_accounts where pid = $1", self.pid).fetch_one(get_db()).await.map_err(|_| ErrorCode::FPD_InvalidAccount)?.principal_preference_show_currently_playing_title{
|
||||
if !query!("select principal_preference_show_currently_playing_title from nintendo_network_accounts where pid = $1", self.pid).fetch_one(&self.fm.db).await.map_err(|_| ErrorCode::FPD_InvalidAccount)?.principal_preference_show_currently_playing_title{
|
||||
presence.game_server_id = 0;
|
||||
presence.game_key = GameKey::default();
|
||||
presence.game_key = friends_wiiu::GameKey::default();
|
||||
presence.app_data = vec![];
|
||||
}
|
||||
if !query!(
|
||||
"select principal_preference_show_online from nintendo_network_accounts where pid = $1",
|
||||
self.pid
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
.map_err(|_| ErrorCode::FPD_InvalidAccount)?
|
||||
.principal_preference_show_online
|
||||
|
|
@ -1380,7 +1317,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn update_mii(&self, mii: MiiV2) -> Result<KerberosDateTime, ErrorCode> {
|
||||
async fn update_mii(&self, mii: MiiV2) -> Result<DateTime, ErrorCode> {
|
||||
if let Err(e) = query!(
|
||||
"
|
||||
update nintendo_network_accounts
|
||||
|
|
@ -1392,7 +1329,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
bytemuck::cast::<_, i64>(mii.date_time.0),
|
||||
self.pid
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
{
|
||||
println!("internal server error whilest updating mii: {}", e);
|
||||
|
|
@ -1403,7 +1340,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
"select * from nintendo_network_accounts where pid = $1",
|
||||
self.pid
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
println!("internal server error whilest getting nna info");
|
||||
|
|
@ -1425,10 +1362,10 @@ impl FriendsWiiU for FriendsUser {
|
|||
.await;
|
||||
}
|
||||
|
||||
Ok(KerberosDateTime::now())
|
||||
Ok(DateTime::now())
|
||||
}
|
||||
|
||||
async fn update_comment(&self, comment: Comment) -> Result<KerberosDateTime, ErrorCode> {
|
||||
async fn update_comment(&self, comment: Comment) -> Result<DateTime, ErrorCode> {
|
||||
if let Err(e) = query!(
|
||||
"
|
||||
update nintendo_network_accounts
|
||||
|
|
@ -1438,7 +1375,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
comment.message.clone(),
|
||||
self.pid
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
{
|
||||
println!("internal server error whilest updating mii: {}", e);
|
||||
|
|
@ -1463,7 +1400,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
.await;
|
||||
}
|
||||
|
||||
Ok(KerberosDateTime::now())
|
||||
Ok(DateTime::now())
|
||||
}
|
||||
|
||||
async fn update_preference(&self, preference: PrincipalPreference) -> Result<(), ErrorCode> {
|
||||
|
|
@ -1480,7 +1417,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
preference.block_friend_request,
|
||||
self.pid
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
{
|
||||
println!("internal server error whilest updating mii: {e}");
|
||||
|
|
@ -1494,14 +1431,14 @@ impl FriendsWiiU for FriendsUser {
|
|||
|
||||
if !preference.show_playing_title {
|
||||
presence.game_server_id = 0;
|
||||
presence.game_key = GameKey::default();
|
||||
presence.game_key = friends_wiiu::GameKey::default();
|
||||
presence.app_data = vec![];
|
||||
}
|
||||
query!(
|
||||
"update nintendo_network_accounts set last_online = now() where pid = $1",
|
||||
self.pid
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&self.fm.db)
|
||||
.await
|
||||
.ok();
|
||||
let friends = self.maybe_remote_friend.read().await;
|
||||
|
|
@ -1530,7 +1467,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
event_type: 10,
|
||||
sender: self.pid,
|
||||
data: Any::new(&NintendoNotificationEventGeneral {
|
||||
param3: KerberosDateTime::now().0,
|
||||
param3: DateTime::now().0,
|
||||
..Default::default()
|
||||
})
|
||||
.expect("type error"),
|
||||
|
|
@ -1551,7 +1488,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
"select * from nintendo_network_accounts where pid = $1",
|
||||
pid
|
||||
)
|
||||
.fetch_one(get_db())
|
||||
.fetch_one(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
return Err(ErrorCode::FPD_NotFriend);
|
||||
|
|
@ -1591,7 +1528,7 @@ impl FriendsWiiU for FriendsUser {
|
|||
pid,
|
||||
self.pid
|
||||
)
|
||||
.fetch_optional(get_db())
|
||||
.fetch_optional(&self.fm.db)
|
||||
.await
|
||||
else {
|
||||
warn!("user requested request setting of invalid user");
|
||||
|
|
@ -1619,61 +1556,12 @@ impl FriendsWiiU for FriendsUser {
|
|||
|
||||
type HMacMd5 = hmac::Hmac<md5::Md5>;
|
||||
|
||||
impl Secure for FriendsUser {
|
||||
async fn register(
|
||||
&self,
|
||||
station_urls: Vec<StationUrl>,
|
||||
) -> Result<(QResult, u32, StationUrl), ErrorCode> {
|
||||
let cid = self.fm.next_cid();
|
||||
Ok((
|
||||
QResult::success(ErrorCode::Core_Unknown),
|
||||
cid,
|
||||
get_station_urls(&station_urls, self.addr, self.pid, cid).await?[0].clone(),
|
||||
))
|
||||
}
|
||||
async fn register_ex(
|
||||
&self,
|
||||
station_urls: Vec<StationUrl>,
|
||||
_data: Any,
|
||||
) -> Result<(QResult, u32, StationUrl), ErrorCode> {
|
||||
info!("register");
|
||||
self.register(station_urls).await
|
||||
}
|
||||
async fn replace_url(&self, _target: StationUrl, _dest: StationUrl) -> Result<(), ErrorCode> {
|
||||
Err(ErrorCode::Core_NotImplemented)
|
||||
}
|
||||
}
|
||||
|
||||
impl Secure for FriendsGuest {
|
||||
async fn register(
|
||||
&self,
|
||||
station_urls: Vec<StationUrl>,
|
||||
) -> Result<(QResult, u32, StationUrl), ErrorCode> {
|
||||
let cid = self.fm.next_cid();
|
||||
Ok((
|
||||
QResult::success(ErrorCode::Core_Unknown),
|
||||
cid,
|
||||
get_station_urls(&station_urls, self.addr, 100, cid).await?[0].clone(),
|
||||
))
|
||||
}
|
||||
async fn register_ex(
|
||||
&self,
|
||||
station_urls: Vec<StationUrl>,
|
||||
_data: Any,
|
||||
) -> Result<(QResult, u32, StationUrl), ErrorCode> {
|
||||
info!("register");
|
||||
self.register(station_urls).await
|
||||
}
|
||||
async fn replace_url(&self, _target: StationUrl, _dest: StationUrl) -> Result<(), ErrorCode> {
|
||||
Err(ErrorCode::Core_NotImplemented)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for FriendsUser {
|
||||
fn drop(&mut self) {
|
||||
let friends = mem::take(&mut self.maybe_remote_friend);
|
||||
let users = friends.into_inner();
|
||||
let pid = self.pid;
|
||||
let fm = self.fm.clone();
|
||||
tokio::spawn(async move {
|
||||
for user in users {
|
||||
let Some(user) = user.1.upgrade() else {
|
||||
|
|
@ -1685,7 +1573,7 @@ impl Drop for FriendsUser {
|
|||
event_type: 10,
|
||||
sender: pid,
|
||||
data: Any::new(&NintendoNotificationEventGeneral {
|
||||
param3: KerberosDateTime::now().0,
|
||||
param3: DateTime::now().0,
|
||||
..Default::default()
|
||||
})
|
||||
.expect("type error"),
|
||||
|
|
@ -1696,7 +1584,7 @@ impl Drop for FriendsUser {
|
|||
"update nintendo_network_accounts set last_online = now() where pid = $1",
|
||||
pid
|
||||
)
|
||||
.execute(get_db())
|
||||
.execute(&fm.db)
|
||||
.await
|
||||
.ok();
|
||||
});
|
||||
102
rnex-server-nex-modules/rnex-fpd/src/lib.rs
Normal file
102
rnex-server-nex-modules/rnex-fpd/src/lib.rs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
use crate::friends_handler::{FriendsGuest, FriendsUser};
|
||||
use nex_account::GUEST_PID;
|
||||
use rnex_fpd_protos::RemoteFriendRemote;
|
||||
use rnex_rmc::{RmcCallable, RmcPureRemoteObject};
|
||||
use rnex_server::{ConnectionInitData, RnexManager, RnexModule, WeakPassthroughInitModule};
|
||||
use rnex_util::PID;
|
||||
use sqlx::PgPool;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
env,
|
||||
sync::{Arc, Weak, atomic::AtomicU32},
|
||||
};
|
||||
use thiserror::Error;
|
||||
use tokio::sync::RwLock;
|
||||
pub mod friends_handler;
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum ModuleInitError {
|
||||
#[error(transparent)]
|
||||
Sqlx(#[from] sqlx::Error),
|
||||
#[error(transparent)]
|
||||
Env(#[from] env::VarError),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum FriendsMaybeGuest {
|
||||
Guest(FriendsGuest),
|
||||
User(Arc<FriendsUser>),
|
||||
}
|
||||
|
||||
impl RmcCallable for FriendsMaybeGuest {
|
||||
async fn rmc_call(
|
||||
&self,
|
||||
responder: &rnex_util::SendingBufferConnection,
|
||||
protocol_id: u16,
|
||||
method_id: u32,
|
||||
call_id: u32,
|
||||
rest: &[u8],
|
||||
) -> bool {
|
||||
match self {
|
||||
FriendsMaybeGuest::Guest(friends_guest) => {
|
||||
friends_guest
|
||||
.rmc_call(responder, protocol_id, method_id, call_id, rest)
|
||||
.await
|
||||
}
|
||||
FriendsMaybeGuest::User(friends_user) => {
|
||||
friends_user
|
||||
.rmc_call(responder, protocol_id, method_id, call_id, rest)
|
||||
.await
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FriendsManager {
|
||||
pub users: RwLock<HashMap<PID, Weak<FriendsUser>>>,
|
||||
pub db: PgPool,
|
||||
}
|
||||
|
||||
pub struct FriendsModule;
|
||||
|
||||
impl RnexManager for FriendsManager {
|
||||
type InitData = ConnectionInitData;
|
||||
type User = FriendsMaybeGuest;
|
||||
|
||||
async fn init_new_user(
|
||||
mgr: rnex_server::PassthroughInitModule<Self>,
|
||||
mod_holder: &rnex_server::ModuleHolder,
|
||||
remote: &rnex_rmc::RmcConnection,
|
||||
init_data: &Self::InitData,
|
||||
weak_user: WeakPassthroughInitModule<Self::User>,
|
||||
) -> Self::User {
|
||||
if init_data.pid == GUEST_PID {
|
||||
return FriendsMaybeGuest::Guest(FriendsGuest);
|
||||
}
|
||||
FriendsMaybeGuest::User(Arc::new_cyclic(|this| FriendsUser {
|
||||
fm: mgr,
|
||||
pid: init_data.pid,
|
||||
friend_pids: Default::default(),
|
||||
maybe_remote_friend: Default::default(),
|
||||
presence: Default::default(),
|
||||
this: this.clone(),
|
||||
remote: RemoteFriendRemote::new(remote.clone()),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl RnexModule for FriendsModule {
|
||||
type Manager = FriendsManager;
|
||||
|
||||
type InitError = ModuleInitError;
|
||||
|
||||
async fn create_manager(
|
||||
mod_holder: &rnex_server::ModuleHolder,
|
||||
) -> Result<Self::Manager, Self::InitError> {
|
||||
Ok(FriendsManager {
|
||||
users: Default::default(),
|
||||
db: PgPool::connect(&env::var("RNEX_DATASTORE_DATABASE")?).await?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
rnex-rmc = { path = "../../rnex-rmc" }
|
||||
rnex-msg-protos = { path = "../../rnex-protocols/msg-protos" }
|
||||
rnex-server = { path = "../../rnex-server" }
|
||||
tokio = { version = "1.52.3", features = ["sync"] }
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
40
rnex-server-nex-modules/rnex-msg/src/lib.rs
Normal file
40
rnex-server-nex-modules/rnex-msg/src/lib.rs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use rnex_msg_protos::RemoteMessagingClient;
|
||||
use rnex_rmc::{RmcPureRemoteObject, util::PID};
|
||||
use rnex_server::{ConnectionInitData, RnexManager, WeakPassthroughInitModule};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use crate::user::MessagingUser;
|
||||
|
||||
pub mod user;
|
||||
|
||||
pub struct MessagingManager {
|
||||
users_by_pid: RwLock<HashMap<PID, WeakPassthroughInitModule<MessagingUser>>>,
|
||||
}
|
||||
|
||||
pub struct MessagingModule;
|
||||
|
||||
impl RnexManager for MessagingManager {
|
||||
type User = MessagingUser;
|
||||
|
||||
type InitData = ConnectionInitData;
|
||||
|
||||
async fn init_new_user(
|
||||
this: rnex_server::PassthroughInitModule<Self>,
|
||||
mod_holder: &rnex_server::ModuleHolder,
|
||||
remote: &rnex_rmc::RmcConnection,
|
||||
init_data: &Self::InitData,
|
||||
weak_user: rnex_server::WeakPassthroughInitModule<Self::User>,
|
||||
) -> Self::User {
|
||||
this.users_by_pid
|
||||
.write()
|
||||
.await
|
||||
.insert(init_data.pid, weak_user);
|
||||
MessagingUser {
|
||||
msgm: this,
|
||||
pid: init_data.pid,
|
||||
remote: RemoteMessagingClient::new(remote.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
|
@ -1,16 +1,32 @@
|
|||
impl MessageDelivery for User {
|
||||
use crate::MessagingManager;
|
||||
use rnex_msg_protos::message_delivery::RemoteMessageDeliveryNoResponse;
|
||||
use rnex_msg_protos::{
|
||||
LocalMessagingProtocol, RemoteMessagingClient, message_delivery::MessageDelivery,
|
||||
messaging::UserMessage,
|
||||
};
|
||||
use rnex_rmc::{any::Any, response::ErrorCode, rmc_struct, util::PID};
|
||||
use rnex_server::{PassthroughInitModule, WeakPassthroughInitModule};
|
||||
|
||||
#[rmc_struct(MessagingProtocol)]
|
||||
pub struct MessagingUser {
|
||||
pub msgm: PassthroughInitModule<MessagingManager>,
|
||||
pub pid: PID,
|
||||
pub remote: RemoteMessagingClient,
|
||||
}
|
||||
|
||||
impl MessageDelivery for MessagingUser {
|
||||
async fn deliver_message(&self, mut message: Any<UserMessage>) -> Result<(), ErrorCode> {
|
||||
let mut msg = message.get()?;
|
||||
|
||||
let _users = match msg.recipient_type {
|
||||
1 => {
|
||||
let Some(user) = self
|
||||
.matchmake_manager
|
||||
.msgm
|
||||
.users_by_pid
|
||||
.read()
|
||||
.await
|
||||
.get(&msg.recipient_id)
|
||||
.map(Weak::upgrade)
|
||||
.map(WeakPassthroughInitModule::upgrade)
|
||||
.flatten()
|
||||
else {
|
||||
return Err(ErrorCode::Core_InvalidArgument);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,15 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
rnex-rmc = { path = "../../rnex-rmc" }
|
||||
rnex-util = { path = "../../rnex-util" }
|
||||
rnex-rk-protos = { path = "../../rnex-protocols/rk-protos" }
|
||||
rnex-server = { path = "../../rnex-server" }
|
||||
serde = { version = "1.0.228", features = ["derive"] }
|
||||
tracing = "0.1.44"
|
||||
ureq = { version = "3.3.0", features = ["json"] }
|
||||
tokio = { version = "1.52.3", features = ["rt"] }
|
||||
serde_json = "1.0.150"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
|||
86
rnex-server-nex-modules/rnex-rk/src/lib.rs
Normal file
86
rnex-server-nex-modules/rnex-rk/src/lib.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
use std::env::{self, VarError};
|
||||
|
||||
use rnex_rmc::response::ErrorCode;
|
||||
use rnex_server::{ConnectionInitData, RnexManager, RnexModule};
|
||||
use std::str::FromStr;
|
||||
use tracing::error;
|
||||
|
||||
use crate::user::RankingUser;
|
||||
|
||||
pub mod user;
|
||||
|
||||
pub struct RankingManager {
|
||||
rnex_result_get: String,
|
||||
rnex_result_votes_get: String,
|
||||
rnex_result_post: String,
|
||||
}
|
||||
|
||||
pub struct RankingModule;
|
||||
|
||||
impl RankingManager {
|
||||
// Seperate function because I cannot give a fuck right now
|
||||
async fn fetch_team_votes(&self, fest_id: u32) -> Result<Vec<u32>, ErrorCode> {
|
||||
let url_votes = format!("{}?splatfest_id={}", self.rnex_result_votes_get, fest_id);
|
||||
let Ok(response) = tokio::task::spawn_blocking(move || {
|
||||
ureq::get(&url_votes).call().map_err(|e| {
|
||||
error!("GET for votes failed: {:?}", e);
|
||||
ErrorCode::RendezVous_InvalidConfiguration
|
||||
})
|
||||
})
|
||||
.await
|
||||
else {
|
||||
error!("failed to make request");
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
|
||||
let mut response = response?;
|
||||
|
||||
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 RnexManager for RankingManager {
|
||||
type User = RankingUser;
|
||||
|
||||
type InitData = ConnectionInitData;
|
||||
|
||||
async fn init_new_user(
|
||||
this: rnex_server::PassthroughInitModule<Self>,
|
||||
mod_holder: &rnex_server::ModuleHolder,
|
||||
remote: &rnex_rmc::RmcConnection,
|
||||
init_data: &Self::InitData,
|
||||
weak_user: rnex_server::WeakPassthroughInitModule<Self::User>,
|
||||
) -> Self::User {
|
||||
RankingUser {
|
||||
rm: this,
|
||||
pid: init_data.pid,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RnexModule for RankingModule {
|
||||
type Manager = RankingManager;
|
||||
|
||||
type InitError = VarError;
|
||||
|
||||
async fn create_manager(
|
||||
_: &rnex_server::ModuleHolder,
|
||||
) -> Result<Self::Manager, Self::InitError> {
|
||||
Ok(RankingManager {
|
||||
rnex_result_votes_get: env::var("RNEX_SPLATOON_RESULTS_VOTES_GET")?,
|
||||
rnex_result_post: env::var("RNEX_SPLATOON_RESULTS_POST")?,
|
||||
rnex_result_get: env::var("RNEX_SPLATOON_RESULTS_GET")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
|
@ -1,3 +1,25 @@
|
|||
use rnex_rk_protos::{
|
||||
LocalRankingProtocol,
|
||||
ranking::{
|
||||
CompetitionRankingGetParam, CompetitionRankingScoreData, CompetitionRankingScoreInfo,
|
||||
Ranking, UploadCompetitionData,
|
||||
},
|
||||
};
|
||||
use rnex_rmc::{qbuffer::QBuffer, response::ErrorCode, rmc_struct};
|
||||
use rnex_server::PassthroughInitModule;
|
||||
use rnex_util::{PID, date_time::DateTime};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{env, str::FromStr};
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::RankingManager;
|
||||
|
||||
#[rmc_struct(RankingProtocol)]
|
||||
pub struct RankingUser {
|
||||
pub rm: PassthroughInitModule<RankingManager>,
|
||||
pub pid: PID,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct CompetitionPostResults {
|
||||
pub splatfest_id: u32,
|
||||
|
|
@ -7,50 +29,20 @@ pub struct CompetitionPostResults {
|
|||
pub user: PID,
|
||||
}
|
||||
|
||||
// Seperate function because I cannot give a fuck right now
|
||||
async 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 = tokio::task::spawn_blocking(|| {
|
||||
ureq::get(&url_votes).call().map_err(|e| {
|
||||
error!("GET for votes failed: {:?}", e);
|
||||
ErrorCode::RendezVous_InvalidConfiguration
|
||||
})
|
||||
})
|
||||
.await?;
|
||||
|
||||
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 {
|
||||
impl Ranking for RankingUser {
|
||||
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 url_results = format!("{}?splatfest_id={}", self.rm.rnex_result_get, fest_id);
|
||||
let Ok(response_results) =
|
||||
tokio::task::spawn_blocking(move || ureq::get(&url_results).call()).await
|
||||
else {
|
||||
error!("failed to join task");
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
|
||||
let results: Vec<CompetitionPostResults> = match response_results {
|
||||
Ok(mut res) => res.body_mut().read_json().map_err(|e| {
|
||||
|
|
@ -69,7 +61,7 @@ impl Ranking for User {
|
|||
let start = offset.min(results.len());
|
||||
let end = (start + size).min(results.len());
|
||||
|
||||
let team_votes = fetch_team_votes(fest_id)?;
|
||||
let team_votes = self.rm.fetch_team_votes(fest_id).await?;
|
||||
let mut wins = vec![0u32, 0u32];
|
||||
for r in &results {
|
||||
let won_team = (r.team_id ^ (!r.team_win)) & 1;
|
||||
|
|
@ -84,7 +76,7 @@ impl Ranking for User {
|
|||
unk: 1,
|
||||
pid: r.user,
|
||||
score: r.score,
|
||||
modified: KerberosDateTime::now(),
|
||||
modified: DateTime::now(),
|
||||
unk2: 1,
|
||||
appdata: QBuffer(vec![]),
|
||||
})
|
||||
|
|
@ -113,14 +105,6 @@ impl Ranking for User {
|
|||
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,
|
||||
|
|
@ -137,9 +121,18 @@ impl Ranking for User {
|
|||
}
|
||||
};
|
||||
|
||||
let response = ureq::post(&endpoint)
|
||||
.header("Content-Type", "application/json")
|
||||
.send(json_body);
|
||||
let rm = self.rm.clone();
|
||||
|
||||
let Ok(response) = tokio::task::spawn_blocking(move || {
|
||||
ureq::post(&rm.rnex_result_post)
|
||||
.header("Content-Type", "application/json")
|
||||
.send(json_body)
|
||||
})
|
||||
.await
|
||||
else {
|
||||
error!("unable to spawn blocking");
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
|
||||
match response {
|
||||
Ok(res) => {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ chrono = "0.4.39"
|
|||
bytemuck = { version = "1.25.0", features = ["derive"] }
|
||||
md-5 = "0.11.0"
|
||||
thiserror = "2.0.18"
|
||||
nex-account = { version = "0.2.4", registry = "spbr" }
|
||||
|
||||
[features]
|
||||
nx = []
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use md5::{Digest, Md5};
|
||||
use nex_account::{grpc::Pid, grpc_client};
|
||||
|
||||
use crate::PID;
|
||||
|
||||
|
|
@ -44,4 +45,17 @@ impl Account {
|
|||
pub fn get_login_data(&self) -> (PID, [u8; 16]) {
|
||||
(self.pid, self.nex_key)
|
||||
}
|
||||
pub async fn from_nexact(pid: PID, username: &str) -> Option<Self> {
|
||||
let key: [u8; 16] = grpc_client()
|
||||
.await
|
||||
.ok()?
|
||||
.get_nex_key_by_pid(Pid { pid })
|
||||
.await
|
||||
.ok()?
|
||||
.into_inner()
|
||||
.key
|
||||
.try_into()
|
||||
.ok()?;
|
||||
Some(Self::new_raw_key(pid, username, key))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue