Merge pull request 'Update Rust crate anyhow to v1.0.103' (#40) from renovate/anyhow-1.x-lockfile into v0
Some checks failed
Build and Test / splatoon (push) Has been cancelled
Build and Test / super-mario-maker (push) Has been cancelled
Build and Test / mario-tennis (push) Has been cancelled
Build and Test / wii-u-chat (push) Has been cancelled
Build and Test / wii-sports-club (push) Has been cancelled
Build and Test / friends (push) Has been cancelled
Build and Test / sonic-transformed (push) Has been cancelled
Build and Test / fast-racing-neo (push) Has been cancelled
Build and Test / puyopuyo (push) Has been cancelled
Build and Test / splatoon-testfire (push) Has been cancelled
Build and Test / minecraft-wiiu (push) Has been cancelled

Reviewed-on: #40
This commit is contained in:
redbinder0526 2026-07-06 18:26:15 +02:00 committed by Maple Nebel
commit 8b9f8e02eb
6 changed files with 628 additions and 124 deletions

86
Cargo.lock generated
View file

@ -45,9 +45,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.102"
version = "1.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3"
[[package]]
name = "async-trait"
@ -3909,22 +3909,13 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets 0.48.5",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets 0.52.6",
"windows-targets",
]
[[package]]
@ -3936,67 +3927,34 @@ dependencies = [
"windows-link",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm 0.48.5",
"windows_aarch64_msvc 0.48.5",
"windows_i686_gnu 0.48.5",
"windows_i686_msvc 0.48.5",
"windows_x86_64_gnu 0.48.5",
"windows_x86_64_gnullvm 0.48.5",
"windows_x86_64_msvc 0.48.5",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm 0.52.6",
"windows_aarch64_msvc 0.52.6",
"windows_i686_gnu 0.52.6",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc 0.52.6",
"windows_x86_64_gnu 0.52.6",
"windows_x86_64_gnullvm 0.52.6",
"windows_x86_64_msvc 0.52.6",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
@ -4009,48 +3967,24 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"

View file

@ -10,7 +10,7 @@ sonic-transformed:
RNEX_DEFAULT_PORT: 10000
RNEX_ACCESS_KEY: "b26a3421"
ac-new-leaf:
include-in-checkall: true
include-in-checkall: false
features:
- prudpv1
- datastore

View file

@ -1,11 +1,14 @@
use std::collections::{HashMap, HashSet};
use std::env;
use std::io::{Cursor, Write};
use std::ops::Deref;
use std::process::id;
use std::sync::{Arc, atomic::AtomicU32};
use std::sync::{LazyLock, Weak};
use base64::{Engine as _, engine::general_purpose};
use bytemuck::{Pod, Zeroable, bytes_of};
use futures::StreamExt;
use hex::decode;
use hmac::Mac;
use log::info;
@ -56,10 +59,13 @@ use rnex_core::rmc::structures::data::Data;
use crate::executables::common::get_db;
use crate::kerberos;
use crate::rmc::protocols::friends_3ds::{
FriendComment, FriendMii, FriendMiiList, FriendPersistentInfo, FriendPicture, FriendPresence,
FriendRelationship, Mii, MiiList, MyProfile, NintendoPresence, PlayedGame,
};
use crate::rmc::protocols::friends_wiiu::FriendRequestMessage;
use crate::rmc::protocols::nintendo_notification::NintendoNotificationEventGeneral;
use nex_account::grpc::ActCreateInfo;
use nex_account::grpc::nex_account_service_client::NexAccountServiceClient;
use nex_account::{derive_pid_hmac, grpc_client};
@ -86,11 +92,6 @@ define_rmc_proto!(
static NEX_ACCOUNT_URL: LazyLock<String> =
LazyLock::new(|| env::var("NEX_ACCOUNT_ENDPOINT").expect("NEX_ACCOUNT_ENDPOINT not set"));
pub struct UserData {
info: NNAInfo,
presence: NintendoPresenceV2,
}
#[repr(C, packed)]
#[derive(Pod, Zeroable, Copy, Clone, Debug)]
pub struct NascToken {
@ -104,8 +105,9 @@ pub struct FriendsUser {
pub fm: Arc<FriendsManager>,
pub addr: PRUDPSockAddr,
pub pid: PID,
pub data: RwLock<Option<UserData>>,
pub current_friends: RwLock<Vec<PID>>,
pub friend_pids: RwLock<Vec<PID>>,
pub maybe_remote_friend: RwLock<HashMap<PID, Weak<FriendsUser>>>,
pub presence: RwLock<Option<NintendoPresenceV2>>,
pub this: Weak<FriendsUser>,
pub remote: RemoteFriendRemote,
}
@ -118,7 +120,7 @@ pub struct FriendsGuest {
pub struct FriendsManager {
pub cid_counter: AtomicU32,
pub users: RwLock<Vec<Weak<FriendsUser>>>,
pub users: RwLock<HashMap<PID, Weak<FriendsUser>>>,
}
impl FriendsManager {
@ -371,12 +373,78 @@ impl Friends3DS for FriendsUser {
}
}
fn smoosh_to_i16(val1: u8, val2: u8) -> i16 {
bytemuck::cast(((val1 as u16) << 8) | val2 as u16)
}
fn unsmoosh_from_i16(val: i16) -> (u8, u8) {
let val: u16 = bytemuck::cast(val);
((val & 0xFF00 >> 8) as u8, (val & 0xFF) as u8)
}
macro_rules! basic_principal_from_record {
($record:expr) => {{
let (mii_unk1, mii_unk2) = unsmoosh_from_i16($record.mii_unks);
PrincipalBasicInfo {
data: Data {},
pid: $record.pid,
nnid: $record.nnid,
mii: MiiV2 {
data: Data {},
date_time: KerberosDateTime::from_naive($record.mii_unk_datetime),
mii_data: $record.mii_ffl_data,
name: $record.mii_name,
unk: mii_unk1,
unk2: mii_unk2,
},
unk: (bytemuck::cast::<_, u16>($record.principal_info_unk) & 0xFF) as u8,
}
}};
}
macro_rules! nna_info_from_record {
($record:expr) => {{
let (nna_unk1, nna_unk2) = unsmoosh_from_i16($record.nna_info_unks_2);
NNAInfo {
data: Data {},
principal_basic_info: basic_principal_from_record!($record),
unk: nna_unk1,
unk2: nna_unk2,
}
}};
}
macro_rules! friend_request_from_record {
($record:expr) => {{
let (unk, unk2) = unsmoosh_from_i16($record.unks_1);
FriendRequest {
data: Data {},
basic_info: basic_principal_from_record!($record),
request_message: FriendRequestMessage {
data: Data {},
expires_on: KerberosDateTime::PRACTICALLY_NEVER,
friend_request_id: $record.id,
game_key: GameKey {
data: Data {},
tid: $record.game_key_tid,
version: $record.game_key_version,
},
is_recieved: $record.is_recieved,
message: $record.message,
unk,
unk2,
unk3: $record.unk_2,
unk4: KerberosDateTime::from_naive($record.unk_3),
},
sent_on: KerberosDateTime::from_naive($record.creation_time),
}
}};
}
impl FriendsWiiU for FriendsUser {
async fn update_and_get_all_information(
&self,
info: NNAInfo,
presence: NintendoPresenceV2,
date_time: KerberosDateTime,
birthday: KerberosDateTime,
) -> Result<
(
PrincipalPreference,
@ -391,39 +459,231 @@ impl FriendsWiiU for FriendsUser {
),
ErrorCode,
> {
// let query = query!("select ", self.pid).fetch_all(get_db()).await;
if info.principal_basic_info.pid == self.pid {
return Err(ErrorCode::FPD_InvalidArgument);
}
*self.presence.write().await = Some(presence.clone());
let Ok(query) = query!("
insert into nintendo_network_accounts (
pid, nnid, mii_name, mii_unks, mii_ffl_data, mii_unk_datetime, principal_info_unk, nna_info_unks_2, birthday
) values (
$1, $2, $3, $4, $5, $6 , $7, $8, $9
)
on conflict (pid)
do update set
mii_name = excluded.mii_name,
mii_unks = excluded.mii_unks,
mii_ffl_data = excluded.mii_ffl_data,
mii_unk_datetime = excluded.mii_unk_datetime,
principal_info_unk = excluded.principal_info_unk,
nna_info_unks_2 = excluded.nna_info_unks_2,
birthday = excluded.birthday
returning comment_unk, comment_message, comment_lastchanged, principal_preference_show_online, principal_preference_show_currently_playing_title, principal_preference_block_friend_requests
",
self.pid,
info.principal_basic_info.nnid,
info.principal_basic_info.mii.name,
smoosh_to_i16(info.principal_basic_info.mii.unk, info.principal_basic_info.mii.unk2),
info.principal_basic_info.mii.mii_data,
info.principal_basic_info.mii.date_time.to_regular_time().naive_utc(),
info.principal_basic_info.unk as i16,
smoosh_to_i16(info.unk, info.unk2),
birthday.to_regular_time().naive_utc()
)
.fetch_one(get_db())
.await else {
println!("psql failed(unable to update user)");
return Err(ErrorCode::Core_SystemError)
};
let Ok(outgoing_friend_requests) = query!(
"
select
*
from friend_requests
inner join nintendo_network_accounts on recipient = nintendo_network_accounts.pid
where sender = $1
",
self.pid
)
.fetch_all(get_db())
.await
.map(|v| {
v.into_iter()
.map(|v| friend_request_from_record!(v))
.collect::<Vec<_>>()
}) else {
println!("error whilest getting friend requests");
return Err(ErrorCode::Core_SystemError);
};
let Ok(incoming_friend_requests) = query!(
"
select
*
from friend_requests
inner join nintendo_network_accounts on sender = nintendo_network_accounts.pid
where recipient = $1
",
self.pid
)
.fetch_all(get_db())
.await
.map(|v| {
v.into_iter()
.map(|v| friend_request_from_record!(v))
.collect::<Vec<_>>()
}) else {
println!("error whilest getting friend requests");
return Err(ErrorCode::Core_SystemError);
};
let Ok(friends_raw) = query!(
"
select
nintendo_network_accounts.pid,
since,
nnid,
comment_message,
comment_unk,
comment_lastchanged,
nna_info_unks_2,
principal_info_unk,
mii_name,
mii_unks,
mii_ffl_data,
mii_unk_datetime,
last_online
from friendships_of_pid($1) as friendships
inner join nintendo_network_accounts on friendships.pid = nintendo_network_accounts.pid",
self.pid
)
.fetch_all(get_db())
.await
else {
println!("error whilest getting friends");
return Err(ErrorCode::Core_SystemError);
};
let mut friends = Vec::with_capacity(friends_raw.len());
for mut friend in friends_raw {
let Some(friend_since) = friend.since else {
println!("this should absolutely never happen(psql messed up somehow)");
return Err(ErrorCode::Core_SystemError);
};
let mut presence = NintendoPresenceV2::default();
let mut current_friends = self.friend_pids.write().await;
current_friends.push(friend.pid);
drop(current_friends);
let mut users = self.fm.users.read().await;
let user = users.get(&friend.pid).cloned();
drop(users);
if let Some(user) = user {
if let Some(user) = user.upgrade() {
let online_presence = user.presence.read().await;
if let Some(online_presence) = online_presence.as_ref() {
presence = online_presence.clone();
} else {
println!(
"internal server error, user is somehow online and in the friends manager yet has not set their presence yet..."
);
}
drop(online_presence);
let mut other_friend_remotes = user.maybe_remote_friend.write().await;
other_friend_remotes.insert(self.pid, self.this.clone());
drop(other_friend_remotes);
let mut remo_friends = self.maybe_remote_friend.write().await;
remo_friends.insert(friend.pid, Arc::downgrade(&user));
drop(remo_friends);
}
}
friends.push(FriendInfo {
data: Data {},
nna_info: nna_info_from_record!(friend),
presence,
comment: Comment {
data: Data {},
unk: (bytemuck::cast::<_, u16>(friend.comment_unk) & 0xFF) as u8,
message: friend.comment_message,
last_changed: KerberosDateTime::from_naive(friend.comment_lastchanged),
},
became_friends: KerberosDateTime::from_naive(friend_since),
last_online: KerberosDateTime::from_naive(friend.last_online),
unk: 0,
});
}
self.fm
.users
.write()
.await
.insert(self.pid, self.this.clone());
<Self as FriendsWiiU>::update_presence(self, presence).await?;
Ok((
PrincipalPreference {
data: Data {},
block_friend_request: false,
show_online: true,
show_playing_title: false,
block_friend_request: query.principal_preference_block_friend_requests,
show_online: query.principal_preference_show_online,
show_playing_title: query.principal_preference_show_currently_playing_title,
},
Comment {
data: Data {},
last_changed: KerberosDateTime::now(),
message: "stub(will be impl'd later)".into(),
unk: 0,
last_changed: KerberosDateTime::from_naive(query.comment_lastchanged),
message: query.comment_message,
unk: (bytemuck::cast::<_, u16>(query.comment_unk) & 0xFF) as u8,
},
vec![],
vec![],
vec![],
friends,
outgoing_friend_requests,
incoming_friend_requests,
// todo: blacklisted principals
vec![],
false,
// todo: persistent notifications
vec![],
false,
))
}
async fn add_friend(&self, friend: PID) -> Result<(FriendRequest, FriendInfo), ErrorCode> {
Err(ErrorCode::Core_NotImplemented)
self.add_friend_request(
friend,
0,
"".into(),
0,
"".into(),
GameKey::default(),
KerberosDateTime::now(),
)
.await
}
async fn add_friend_by_name(
&self,
name: String,
) -> Result<(FriendRequest, FriendInfo), ErrorCode> {
Err(ErrorCode::Core_NotImplemented)
let Ok(pid) = query!(
"select pid from nintendo_network_accounts where nnid = $1",
name
)
.fetch_optional(get_db())
.await
else {
println!("db error when trying to look up nnid");
return Err(ErrorCode::Core_Exception);
};
match pid {
Some(pid) => self.add_friend(pid.pid).await,
None => Err(ErrorCode::FPD_InvalidAccount),
}
}
async fn remove_friend(&self, friend: PID) -> Result<(), ErrorCode> {
@ -440,7 +700,98 @@ impl FriendsWiiU for FriendsUser {
game_key: GameKey,
unk4: KerberosDateTime,
) -> Result<(FriendRequest, FriendInfo), ErrorCode> {
Err(ErrorCode::Core_NotImplemented)
// check for too many friend requests both ways
let Ok(query) = query!(
"select count(recipient) from friend_requests where sender = $1",
self.pid
)
.fetch_one(get_db())
.await
else {
println!("friend request count check failed to execute on database");
return Err(ErrorCode::Core_Exception);
};
if query.count.is_none_or(|v| v >= 100) {
return Err(ErrorCode::FPD_RequestLimitExceed);
}
let Ok(query) = query!(
"select count(recipient) from friend_requests where recipient = $1",
friend
)
.fetch_one(get_db())
.await
else {
println!("friend request count check failed to execute on database");
return Err(ErrorCode::Core_Exception);
};
if query.count.is_none_or(|v| v >= 100) {
return Err(ErrorCode::FPD_RequestLimitExceed);
}
let unks_1 = smoosh_to_i16(unk1, unk2);
let query = query!(
"with fr_base as (insert into friend_requests
(sender, recipient, message, unks_1, unk_2, unk_3, game_key_tid, game_key_version)
values ($1, $2, $3, $4, $5, $6, $7, $8)
returning *)
select *
from fr_base
inner join nintendo_network_accounts
on recipient = pid
",
//inner join on recipient = pid
self.pid,
friend,
message,
unks_1,
unk3,
unk4.to_regular_time().naive_utc(),
game_key.tid,
game_key.version
)
.fetch_one(get_db())
.await;
let query = match query {
Ok(q) => q,
Err(e) => {
if let Some(e) = e.into_database_error() {
match e.kind() {
sqlx::error::ErrorKind::UniqueViolation => {
return Err(ErrorCode::FPD_AddFriendProhibited);
}
sqlx::error::ErrorKind::ForeignKeyViolation => {
return Err(ErrorCode::FPD_NotNetworkAccount);
}
sqlx::error::ErrorKind::CheckViolation => {
return Err(ErrorCode::FPD_FriendRequestNotAllowed);
}
_ => {
println!("unknown db error occurred");
return Err(ErrorCode::Core_Exception);
}
}
} else {
println!("unknown db error occurred");
return Err(ErrorCode::Core_Exception);
}
}
};
let fr = friend_request_from_record!(query);
let users = self.fm.users.read().await;
if let Some(user) = users.get(&friend).and_then(|v| v.upgrade()) {
user.remote
.process_nintendo_notification_event_2(NintendoNotificationEvent {
event_type: 25,
sender: self.pid,
data: Any::new(&fr).expect("type check failed"),
})
.await;
}
Ok((fr, Default::default()))
}
async fn cancel_friend_request(&self, id: u64) -> Result<(), ErrorCode> {
@ -448,7 +799,75 @@ impl FriendsWiiU for FriendsUser {
}
async fn accept_friend_request(&self, id: u64) -> Result<FriendInfo, ErrorCode> {
Err(ErrorCode::Core_NotImplemented)
let Ok(query) = query!(
"delete from friend_requests where id = $1 and recipient = $2 returning recipient, sender",
bytemuck::cast::<_, i64>(id),
self.pid
)
.fetch_one(get_db())
.await
else {
return Err(ErrorCode::FPD_InvalidMessageID);
};
let sender = query.sender;
match query!(
"insert into friendships (pid_a, pid_b) values ($1, $2)",
query.recipient,
query.sender
)
.execute(get_db())
.await
{
Ok(_) => {}
Err(e) => return Err(ErrorCode::FPD_FriendAlreadyAdded),
};
let Ok(query) = query!(
"select * from nintendo_network_accounts where pid = $1",
query.sender
)
.fetch_one(get_db())
.await
else {
println!("failed to acquire account info after adding friend");
return Err(ErrorCode::FPD_InvalidMessageID);
};
let mut presence = NintendoPresenceV2::default();
let users = self.fm.users.read().await;
let user = users.get(&sender).cloned();
drop(users);
if let Some(user) = user {
if let Some(user) = user.upgrade() {
let online_presence = user.presence.read().await;
if let Some(online_presence) = online_presence.as_ref() {
presence = online_presence.clone();
} else {
println!(
"internal server error, user is somehow online and in the friends manager yet has not set their presence yet..."
);
}
drop(online_presence);
}
}
Ok(FriendInfo {
data: Data {},
nna_info: nna_info_from_record!(query),
presence,
comment: Comment {
data: Data {},
last_changed: KerberosDateTime::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),
unk: 0,
})
}
async fn delete_friend_request(&self, id: u64) -> Result<(), ErrorCode> {
@ -460,6 +879,14 @@ impl FriendsWiiU for FriendsUser {
}
async fn mark_friend_requests_as_received(&self, ids: Vec<u64>) -> Result<(), ErrorCode> {
for id in ids {
query!(
"update friend_requests set is_recieved = true where id = $1",
bytemuck::cast::<_, i64>(id)
)
.execute(get_db())
.await;
}
Err(ErrorCode::Core_NotImplemented)
}
@ -475,23 +902,164 @@ impl FriendsWiiU for FriendsUser {
}
async fn update_presence(&self, presence: NintendoPresenceV2) -> Result<(), ErrorCode> {
Err(ErrorCode::Core_NotImplemented)
let data = Any::new(&presence).expect("type error");
let mut user_presence = self.presence.write().await;
*user_presence = Some(presence);
drop(user_presence);
let friends = self.maybe_remote_friend.read().await;
for friend in friends.iter().filter_map(|f| f.1.upgrade()) {
friend
.remote
.process_nintendo_notification_event_2(NintendoNotificationEvent {
event_type: 24,
sender: self.pid,
data: data.clone(),
})
.await;
}
Ok(())
}
async fn update_mii(&self, presence: MiiV2) -> Result<KerberosDateTime, ErrorCode> {
Err(ErrorCode::Core_NotImplemented)
async fn update_mii(&self, mii: MiiV2) -> Result<KerberosDateTime, ErrorCode> {
if let Err(e) = query!(
"
update nintendo_network_accounts
set mii_name = $1, mii_unks = $2, mii_ffl_data = $3, mii_unk_datetime = $4
where pid = $5",
mii.name,
smoosh_to_i16(mii.unk, mii.unk2),
mii.mii_data,
mii.date_time.to_regular_time().naive_utc(),
self.pid
)
.execute(get_db())
.await
{
println!("internal server error whilest updating mii: {}", e);
return Err(ErrorCode::Core_Exception);
}
let Ok(r) = query!(
"select * from nintendo_network_accounts where pid = $1",
self.pid
)
.fetch_one(get_db())
.await
else {
println!("internal server error whilest getting nna info");
return Err(ErrorCode::Core_Exception);
};
let nna_info = nna_info_from_record!(r);
let data = Any::new(&nna_info).expect("type error");
let friends = self.maybe_remote_friend.read().await;
for friend in friends.iter().filter_map(|f| f.1.upgrade()) {
friend
.remote
.process_nintendo_notification_event_2(NintendoNotificationEvent {
event_type: 21,
sender: self.pid,
data: data.clone(),
})
.await;
}
Ok(KerberosDateTime::now())
}
async fn update_comment(&self, presence: Comment) -> Result<KerberosDateTime, ErrorCode> {
Err(ErrorCode::Core_NotImplemented)
async fn update_comment(&self, comment: Comment) -> Result<KerberosDateTime, ErrorCode> {
if let Err(e) = query!(
"
update nintendo_network_accounts
set comment_unk = $1, comment_message = $2, comment_lastchanged = now()
where pid = $3",
comment.unk as i16,
comment.message.clone(),
self.pid
)
.execute(get_db())
.await
{
println!("internal server error whilest updating mii: {}", e);
return Err(ErrorCode::Core_Exception);
}
let data = Any::new(&NintendoNotificationEventGeneral {
param1: bytemuck::cast(self.pid),
str_param: comment.message,
..Default::default()
})
.expect("type error");
let friends = self.maybe_remote_friend.read().await;
for friend in friends.iter().filter_map(|f| f.1.upgrade()) {
friend
.remote
.process_nintendo_notification_event_2(NintendoNotificationEvent {
event_type: 21,
sender: self.pid,
data: data.clone(),
})
.await;
}
Ok(KerberosDateTime::now())
}
async fn update_preference(&self, preference: PrincipalPreference) -> Result<(), ErrorCode> {
Err(ErrorCode::Core_NotImplemented)
let data = Any::new(&preference).expect("type error");
if let Err(e) = query!(
"
update nintendo_network_accounts
set
principal_preference_show_online = $1, principal_preference_show_currently_playing_title = $2, principal_preference_block_friend_requests = $3
where pid = $4",
preference.show_online,
preference.show_playing_title,
preference.block_friend_request,
self.pid
)
.execute(get_db())
.await
{
println!("internal server error whilest updating mii: {}", e);
return Err(ErrorCode::Core_Exception);
}
let friends = self.maybe_remote_friend.read().await;
for friend in friends.iter().filter_map(|f| f.1.upgrade()) {
friend
.remote
.process_nintendo_notification_event_2(NintendoNotificationEvent {
event_type: 23,
sender: self.pid,
data: data.clone(),
})
.await;
}
Ok(())
}
async fn get_basic_info(&self, pids: Vec<PID>) -> Result<Vec<PrincipalBasicInfo>, ErrorCode> {
Err(ErrorCode::Core_NotImplemented)
let mut principal_infos = Vec::with_capacity(pids.len());
for pid in pids {
let Ok(user) = query!(
"select * from nintendo_network_accounts where pid = $1",
pid
)
.fetch_one(get_db())
.await
else {
return Err(ErrorCode::FPD_InvalidPrincipalID);
};
principal_infos.push(basic_principal_from_record!(user));
}
Ok(principal_infos)
}
async fn delete_persistent_notification(
@ -521,10 +1089,6 @@ impl Secure for FriendsUser {
station_urls: Vec<StationUrl>,
) -> Result<(QResult, u32, StationUrl), ErrorCode> {
let cid = self.fm.next_cid();
let users = self.fm.users.read().await;
if users.iter().filter(|u| u.upgrade().is_some()).count() >= 100 {
return Err(ErrorCode::RendezVous_ConnectionFailure);
}
Ok((
QResult::success(ErrorCode::Core_Unknown),
cid,

View file

@ -6,7 +6,7 @@ use rnex_core::rmc::structures::data::Data;
use rnex_core::PID;
#[derive(RmcSerialize, Debug, Clone)]
#[derive(RmcSerialize, Debug, Clone, Default)]
#[rmc_struct(0)]
pub struct MiiV2 {
#[extends]
@ -18,7 +18,7 @@ pub struct MiiV2 {
pub date_time: KerberosDateTime,
}
#[derive(RmcSerialize, Debug, Clone)]
#[derive(RmcSerialize, Debug, Clone, Default)]
#[rmc_struct(0)]
pub struct PrincipalBasicInfo {
#[extends]
@ -29,7 +29,7 @@ pub struct PrincipalBasicInfo {
pub unk: u8,
}
#[derive(RmcSerialize, Debug, Clone)]
#[derive(RmcSerialize, Debug, Clone, Default)]
#[rmc_struct(0)]
pub struct NNAInfo {
#[extends]
@ -39,16 +39,16 @@ pub struct NNAInfo {
pub unk2: u8,
}
#[derive(RmcSerialize, Clone, Copy, Debug)]
#[derive(RmcSerialize, Clone, Copy, Debug, Default)]
#[rmc_struct(0)]
pub struct GameKey {
#[extends]
pub data: Data,
pub tid: u64,
pub version: u16,
pub tid: i64,
pub version: i16,
}
#[derive(RmcSerialize, Clone, Debug)]
#[derive(RmcSerialize, Clone, Debug, Default)]
#[rmc_struct(0)]
pub struct NintendoPresenceV2 {
#[extends]
@ -79,7 +79,7 @@ pub struct PrincipalPreference {
pub block_friend_request: bool,
}
#[derive(RmcSerialize)]
#[derive(RmcSerialize, Default)]
#[rmc_struct(0)]
pub struct Comment {
#[extends]
@ -89,7 +89,7 @@ pub struct Comment {
pub last_changed: KerberosDateTime,
}
#[derive(RmcSerialize)]
#[derive(RmcSerialize, Default)]
#[rmc_struct(0)]
pub struct FriendInfo {
#[extends]
@ -107,8 +107,8 @@ pub struct FriendInfo {
pub struct FriendRequestMessage {
#[extends]
pub data: Data,
pub friend_request_id: u64,
pub is_recieved: u8,
pub friend_request_id: i64,
pub is_recieved: bool,
pub unk: u8,
pub message: String,
pub unk2: u8,

View file

@ -3,6 +3,8 @@ use macros::{RmcSerialize, method_id, rmc_proto};
use rnex_core::PID;
use rnex_core::rmc::structures::any::Any;
use crate::rmc::structures::data::Data;
#[derive(RmcSerialize)]
#[rmc_struct(0)]
pub struct NintendoNotificationEvent {
@ -11,9 +13,11 @@ pub struct NintendoNotificationEvent {
pub data: Any,
}
#[derive(RmcSerialize)]
#[derive(RmcSerialize, Default)]
#[rmc_struct(0)]
pub struct NintendoNotificationEventGeneral {
#[extends]
pub data: Data,
pub param1: u32,
pub param2: u64,
pub param3: u64,
@ -23,6 +27,8 @@ pub struct NintendoNotificationEventGeneral {
#[derive(RmcSerialize)]
#[rmc_struct(0)]
pub struct NintendoNotificationEventProfile {
#[extends]
pub data: Data,
pub region: u8,
pub country: u8,
pub area: u8,

View file

@ -1,5 +1,5 @@
use macros::RmcSerialize;
#[derive(RmcSerialize, Debug, Clone, Copy)]
#[derive(RmcSerialize, Debug, Clone, Copy, Default)]
#[rmc_struct(0)]
pub struct Data {}