lots of changes
This commit is contained in:
parent
8af4ca525a
commit
3b6de6968d
24 changed files with 879 additions and 258 deletions
|
|
@ -1,6 +1,7 @@
|
|||
use crate::grpc::account;
|
||||
use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement};
|
||||
use crate::{define_rmc_proto, kerberos};
|
||||
use cfg_if::cfg_if;
|
||||
use log::{info, warn};
|
||||
use macros::rmc_struct;
|
||||
use rnex_core::kerberos::{KerberosDateTime, Ticket, derive_key};
|
||||
|
|
@ -11,6 +12,7 @@ use rnex_core::rmc::response::ErrorCode;
|
|||
use rnex_core::rmc::response::ErrorCode::Core_Unknown;
|
||||
use rnex_core::rmc::structures::any::Any;
|
||||
use rnex_core::rmc::structures::connection_data::ConnectionData;
|
||||
use rnex_core::rmc::structures::connection_data::ConnectionDataOld;
|
||||
use rnex_core::rmc::structures::qresult::QResult;
|
||||
use std::hash::{DefaultHasher, Hasher};
|
||||
use std::net::SocketAddrV4;
|
||||
|
|
@ -49,7 +51,13 @@ pub fn generate_ticket(
|
|||
encrypted_session_ticket
|
||||
}
|
||||
|
||||
async fn get_login_data_by_pid(pid: u32) -> Option<(u32, [u8; 16])> {
|
||||
async fn get_login_data_by_pid(pid: u32) -> Option<(u32, Box<[u8]>)> {
|
||||
if pid == GUEST_ACCOUNT.pid {
|
||||
let source_login_data = GUEST_ACCOUNT.get_login_data();
|
||||
|
||||
return Some((source_login_data.0, source_login_data.1.into()));
|
||||
}
|
||||
|
||||
let Ok(mut client) = account::Client::new().await else {
|
||||
return None;
|
||||
};
|
||||
|
|
@ -58,7 +66,7 @@ async fn get_login_data_by_pid(pid: u32) -> Option<(u32, [u8; 16])> {
|
|||
return None;
|
||||
};
|
||||
|
||||
Some((pid, passwd))
|
||||
Some((pid, passwd.into()))
|
||||
}
|
||||
|
||||
fn station_url_from_sock_addr(sock_addr: SocketAddrV4) -> String {
|
||||
|
|
@ -118,6 +126,42 @@ impl Auth for AuthHandler {
|
|||
async fn login(
|
||||
&self,
|
||||
name: String,
|
||||
) -> Result<(QResult, u32, Vec<u8>, ConnectionDataOld, String), ErrorCode> {
|
||||
let (pid, ticket) = self.generate_ticket_from_name(&name).await?;
|
||||
|
||||
let result = QResult::success(Core_Unknown);
|
||||
|
||||
let mut hasher = DefaultHasher::new();
|
||||
|
||||
hasher.write(name.as_bytes());
|
||||
|
||||
let Ok(addr) = self.control_server.get_url(hasher.finish()).await else {
|
||||
warn!("no secure proxies");
|
||||
return Err(ErrorCode::Core_Exception);
|
||||
};
|
||||
|
||||
let connection_data = ConnectionDataOld {
|
||||
station_url: station_url_from_sock_addr(addr),
|
||||
special_station_url: "".to_string(),
|
||||
special_protocols: Vec::new(),
|
||||
};
|
||||
|
||||
let ret = (
|
||||
result,
|
||||
pid,
|
||||
ticket.into(),
|
||||
connection_data,
|
||||
self.build_name.to_string(),
|
||||
);
|
||||
|
||||
info!("data: {:?}", ret);
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
async fn login_ex(
|
||||
&self,
|
||||
name: String,
|
||||
_extra_data: Any,
|
||||
) -> Result<(QResult, u32, Vec<u8>, ConnectionData, String), ErrorCode> {
|
||||
let (pid, ticket) = self.generate_ticket_from_name(&name).await?;
|
||||
|
||||
|
|
@ -152,14 +196,6 @@ impl Auth for AuthHandler {
|
|||
Ok(ret)
|
||||
}
|
||||
|
||||
async fn login_ex(
|
||||
&self,
|
||||
name: String,
|
||||
_extra_data: Any,
|
||||
) -> Result<(QResult, u32, Vec<u8>, ConnectionData, String), ErrorCode> {
|
||||
self.login(name).await
|
||||
}
|
||||
|
||||
async fn request_ticket(
|
||||
&self,
|
||||
source_pid: u32,
|
||||
|
|
|
|||
93
rnex-core/src/nex/common.rs
Normal file
93
rnex-core/src/nex/common.rs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
use rnex_core::prudp::station_url::StationUrl;
|
||||
use rnex_core::prudp::station_url::UrlOptions::{
|
||||
Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID,
|
||||
};
|
||||
use rnex_core::prudp::station_url::nat_types::PUBLIC;
|
||||
use rnex_core::rmc::response::ErrorCode::Core_Exception;
|
||||
|
||||
use rnex_core::prudp::socket_addr::PRUDPSockAddr;
|
||||
use rnex_core::rmc::response::ErrorCode;
|
||||
|
||||
pub async fn get_station_urls(
|
||||
station_urls: &[StationUrl],
|
||||
addr: PRUDPSockAddr,
|
||||
pid: u32,
|
||||
cid: u32,
|
||||
) -> Result<Vec<StationUrl>, ErrorCode> {
|
||||
let mut public_station: Option<StationUrl> = None;
|
||||
let mut private_station: Option<StationUrl> = None;
|
||||
|
||||
for station in station_urls {
|
||||
let is_public = station.options.iter().any(|v| {
|
||||
if let NatType(v) = v {
|
||||
if *v & PUBLIC != 0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
});
|
||||
|
||||
let Some(nat_filtering) = station.options.iter().find_map(|v| match v {
|
||||
NatFiltering(v) => Some(v),
|
||||
_ => None,
|
||||
}) else {
|
||||
return Err(Core_Exception);
|
||||
};
|
||||
|
||||
let Some(nat_mapping) = station.options.iter().find_map(|v| match v {
|
||||
NatMapping(v) => Some(v),
|
||||
_ => None,
|
||||
}) else {
|
||||
return Err(Core_Exception);
|
||||
};
|
||||
|
||||
if !is_public || (*nat_filtering == 0 && *nat_mapping == 0) {
|
||||
private_station = Some(station.clone());
|
||||
}
|
||||
|
||||
if is_public {
|
||||
public_station = Some(station.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let Some(mut private_station) = private_station else {
|
||||
return Err(Core_Exception);
|
||||
};
|
||||
|
||||
let mut public_station = if let Some(public_station) = public_station {
|
||||
public_station
|
||||
} else {
|
||||
let mut public_station = private_station.clone();
|
||||
|
||||
public_station.options.retain(|v| match v {
|
||||
Address(_) | Port(_) | NatFiltering(_) | NatMapping(_) | NatType(_) => false,
|
||||
_ => true,
|
||||
});
|
||||
|
||||
public_station
|
||||
.options
|
||||
.push(Address(*addr.regular_socket_addr.ip()));
|
||||
public_station
|
||||
.options
|
||||
.push(Port(addr.regular_socket_addr.port()));
|
||||
public_station.options.push(NatFiltering(0));
|
||||
public_station.options.push(NatMapping(0));
|
||||
public_station.options.push(NatType(3));
|
||||
|
||||
public_station
|
||||
};
|
||||
|
||||
let both = [&mut public_station, &mut private_station];
|
||||
|
||||
for station in both {
|
||||
station.options.retain(|v| match v {
|
||||
PrincipalID(_) | RVConnectionID(_) => false,
|
||||
_ => true,
|
||||
});
|
||||
|
||||
station.options.push(PrincipalID(pid));
|
||||
station.options.push(RVConnectionID(cid));
|
||||
}
|
||||
|
||||
Ok(vec![public_station])
|
||||
}
|
||||
160
rnex-core/src/nex/friends_handler.rs
Normal file
160
rnex-core/src/nex/friends_handler.rs
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
use std::sync::{Arc, atomic::AtomicU32};
|
||||
use std::time::Duration;
|
||||
|
||||
use log::info;
|
||||
use macros::rmc_struct;
|
||||
use rnex_core::rmc::protocols::friends::{Friends, RawFriends, RawFriendsInfo, RemoteFriends};
|
||||
use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure};
|
||||
use rnex_core::{
|
||||
define_rmc_proto,
|
||||
kerberos::KerberosDateTime,
|
||||
nex::common::get_station_urls,
|
||||
prudp::{socket_addr::PRUDPSockAddr, station_url::StationUrl},
|
||||
rmc::{
|
||||
protocols::friends::{
|
||||
BlacklistedPrincipal, Comment, FriendInfo, FriendRequest, NNAInfo, NintendoPresenceV2,
|
||||
PersistentNotification, PrincipalPreference,
|
||||
},
|
||||
response::ErrorCode,
|
||||
structures::{any::Any, qresult::QResult},
|
||||
},
|
||||
};
|
||||
use std::sync::atomic::Ordering::Relaxed;
|
||||
use tokio::time::sleep;
|
||||
|
||||
use rnex_core::rmc::protocols::friends::{GameKey, MiiV2, PrincipalBasicInfo};
|
||||
|
||||
define_rmc_proto!(
|
||||
proto FriendsUser{
|
||||
Secure,
|
||||
Friends
|
||||
}
|
||||
);
|
||||
#[rmc_struct(FriendsUser)]
|
||||
pub struct FriendsUser {
|
||||
pub fm: Arc<FriendsManager>,
|
||||
pub addr: PRUDPSockAddr,
|
||||
pub pid: u32,
|
||||
}
|
||||
|
||||
pub struct FriendsManager {
|
||||
pub cid_counter: AtomicU32,
|
||||
}
|
||||
|
||||
impl FriendsManager {
|
||||
pub fn next_cid(&self) -> u32 {
|
||||
self.cid_counter.fetch_add(1, Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
impl Friends for FriendsUser {
|
||||
async fn update_and_get_all_information(
|
||||
&self,
|
||||
info: NNAInfo,
|
||||
presence: NintendoPresenceV2,
|
||||
date_time: KerberosDateTime,
|
||||
) -> Result<
|
||||
(
|
||||
PrincipalPreference,
|
||||
Comment,
|
||||
Vec<FriendInfo>,
|
||||
Vec<FriendRequest>,
|
||||
Vec<FriendRequest>,
|
||||
Vec<BlacklistedPrincipal>,
|
||||
bool,
|
||||
Vec<PersistentNotification>,
|
||||
bool,
|
||||
),
|
||||
ErrorCode,
|
||||
> {
|
||||
Ok((
|
||||
PrincipalPreference {
|
||||
block_friend_request: false,
|
||||
show_online: false,
|
||||
show_playing_title: false,
|
||||
},
|
||||
Comment {
|
||||
last_changed: KerberosDateTime::now(),
|
||||
message: "".to_string(),
|
||||
unk: 0,
|
||||
},
|
||||
vec![FriendInfo {
|
||||
became_friends: KerberosDateTime::now(),
|
||||
comment: Comment {
|
||||
last_changed: KerberosDateTime::now(),
|
||||
message: "I'm just a dummy account :3".to_string(),
|
||||
unk: 0,
|
||||
},
|
||||
last_online: KerberosDateTime::now(),
|
||||
nna_info: NNAInfo {
|
||||
principal_basic_info: PrincipalBasicInfo {
|
||||
pid: 101,
|
||||
nnid: "dummyaccount".to_string(),
|
||||
mii: MiiV2{
|
||||
date_time: KerberosDateTime::now(),
|
||||
name: "Dummy Account".to_string(),
|
||||
mii_data: hex::decode("030000402bd7c32986a771f2dc6b35e31da15e37ff7c0000391e6f006f006d0069000000000000000000000000004040001065033568641e2013661a611821640f0000290052485000000000000000000000000000000000000000000000e838").unwrap(),
|
||||
unk: 0,
|
||||
unk2: 0,
|
||||
},
|
||||
unk: 0
|
||||
},
|
||||
unk: 0,
|
||||
unk2: 0
|
||||
},
|
||||
presence: NintendoPresenceV2{
|
||||
changed_flags: 0,
|
||||
message: "".to_string(),
|
||||
app_data: vec![],
|
||||
game_key: GameKey{
|
||||
tid: 0x00050002101ce400,
|
||||
version: 0x0
|
||||
},
|
||||
game_server_id: 0,
|
||||
is_online: true,
|
||||
gid: 0,
|
||||
pid: 101,
|
||||
unk: 0,
|
||||
unk2: 0,
|
||||
unk3: 0,
|
||||
unk4: 0,
|
||||
unk5: 0,
|
||||
unk6: 0,
|
||||
unk7: 0
|
||||
},
|
||||
unk: 0
|
||||
}],
|
||||
vec![],
|
||||
vec![],
|
||||
vec![],
|
||||
false,
|
||||
vec![],
|
||||
false,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
pub mod account;
|
||||
pub mod auth_handler;
|
||||
pub mod user;
|
||||
pub mod common;
|
||||
pub mod friends_handler;
|
||||
pub mod matchmake;
|
||||
pub mod remote_console;
|
||||
pub mod matchmake;
|
||||
pub mod user;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::define_rmc_proto;
|
||||
use crate::nex::common::get_station_urls;
|
||||
use crate::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager};
|
||||
use crate::nex::remote_console::RemoteConsole;
|
||||
use crate::rmc::protocols::matchmake::{
|
||||
|
|
@ -21,6 +22,7 @@ use rnex_core::rmc::protocols::matchmake_extension::{
|
|||
use rnex_core::rmc::protocols::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking};
|
||||
use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure};
|
||||
use rnex_core::rmc::response::ErrorCode;
|
||||
use rnex_core::rmc::structures::any::Any;
|
||||
use rnex_core::rmc::structures::matchmake::{
|
||||
AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession,
|
||||
};
|
||||
|
|
@ -71,97 +73,27 @@ impl Secure for User {
|
|||
users.insert(cid, self.this.clone());
|
||||
drop(users);
|
||||
|
||||
let mut public_station: Option<StationUrl> = None;
|
||||
let mut private_station: Option<StationUrl> = None;
|
||||
let stations = get_station_urls(&station_urls, self.ip, self.pid, cid).await?;
|
||||
|
||||
for station in station_urls {
|
||||
let is_public = station.options.iter().any(|v| {
|
||||
if let NatType(v) = v {
|
||||
if *v & PUBLIC != 0 {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
});
|
||||
|
||||
let Some(nat_filtering) = station.options.iter().find_map(|v| match v {
|
||||
NatFiltering(v) => Some(v),
|
||||
_ => None,
|
||||
}) else {
|
||||
return Err(Core_Exception);
|
||||
};
|
||||
|
||||
let Some(nat_mapping) = station.options.iter().find_map(|v| match v {
|
||||
NatMapping(v) => Some(v),
|
||||
_ => None,
|
||||
}) else {
|
||||
return Err(Core_Exception);
|
||||
};
|
||||
|
||||
if !is_public || (*nat_filtering == 0 && *nat_mapping == 0) {
|
||||
private_station = Some(station.clone());
|
||||
}
|
||||
|
||||
if is_public {
|
||||
public_station = Some(station);
|
||||
}
|
||||
}
|
||||
|
||||
let Some(mut private_station) = private_station else {
|
||||
return Err(Core_Exception);
|
||||
};
|
||||
|
||||
let mut public_station = if let Some(public_station) = public_station {
|
||||
public_station
|
||||
} else {
|
||||
let mut public_station = private_station.clone();
|
||||
|
||||
public_station.options.retain(|v| match v {
|
||||
Address(_) | Port(_) | NatFiltering(_) | NatMapping(_) | NatType(_) => false,
|
||||
_ => true,
|
||||
});
|
||||
|
||||
public_station
|
||||
.options
|
||||
.push(Address(*self.ip.regular_socket_addr.ip()));
|
||||
public_station
|
||||
.options
|
||||
.push(Port(self.ip.regular_socket_addr.port()));
|
||||
public_station.options.push(NatFiltering(0));
|
||||
public_station.options.push(NatMapping(0));
|
||||
public_station.options.push(NatType(3));
|
||||
|
||||
public_station
|
||||
};
|
||||
|
||||
let both = [&mut public_station, &mut private_station];
|
||||
|
||||
for station in both {
|
||||
station.options.retain(|v| match v {
|
||||
PrincipalID(_) | RVConnectionID(_) => false,
|
||||
_ => true,
|
||||
});
|
||||
|
||||
station.options.push(PrincipalID(self.pid));
|
||||
station.options.push(RVConnectionID(cid));
|
||||
}
|
||||
let first = stations.first().unwrap().clone();
|
||||
|
||||
let mut lock = self.station_url.write().await;
|
||||
|
||||
*lock = vec![
|
||||
public_station.clone(),
|
||||
// private_station.clone()
|
||||
];
|
||||
*lock = stations;
|
||||
|
||||
drop(lock);
|
||||
|
||||
let result = QResult::success(ErrorCode::Core_Unknown);
|
||||
|
||||
let out = public_station.to_string();
|
||||
Ok((result, cid, first))
|
||||
}
|
||||
|
||||
println!("out: {}", out);
|
||||
|
||||
Ok((result, cid, public_station))
|
||||
async fn register_ex(
|
||||
&self,
|
||||
station_urls: Vec<StationUrl>,
|
||||
_data: Any,
|
||||
) -> Result<(QResult, u32, StationUrl), ErrorCode> {
|
||||
self.register(station_urls).await
|
||||
}
|
||||
|
||||
async fn replace_url(&self, target_url: StationUrl, dest: StationUrl) -> Result<(), ErrorCode> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue