V0 #2
24 changed files with 879 additions and 258 deletions
lots of changes
commit
3b6de6968d
|
|
@ -14,7 +14,7 @@ simplelog = "0.12.2"
|
||||||
chrono = "0.4.39"
|
chrono = "0.4.39"
|
||||||
log = "0.4.25"
|
log = "0.4.25"
|
||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
|
cfg-if = "1.0.4"
|
||||||
hmac = "0.12.1"
|
hmac = "0.12.1"
|
||||||
md-5 = "^0.10.6"
|
md-5 = "^0.10.6"
|
||||||
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] }
|
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread", "net", "sync", "fs"] }
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
use cfg_if::cfg_if;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use rnex_core::common::setup;
|
use rnex_core::common::setup;
|
||||||
use rnex_core::executables::common::{SECURE_SERVER_ACCOUNT, new_simple_backend};
|
use rnex_core::executables::common::{SECURE_SERVER_ACCOUNT, new_simple_backend};
|
||||||
|
use rnex_core::executables::regular_backend;
|
||||||
use rnex_core::nex::auth_handler::AuthHandler;
|
use rnex_core::nex::auth_handler::AuthHandler;
|
||||||
use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister;
|
use rnex_core::reggie::EdgeNodeHolderConnectOption::DontRegister;
|
||||||
use rnex_core::reggie::RemoteEdgeNodeHolder;
|
use rnex_core::reggie::RemoteEdgeNodeHolder;
|
||||||
|
|
@ -23,25 +25,11 @@ pub static FORWARD_EDGE_NODE_HOLDER: Lazy<SocketAddrV4> = Lazy::new(|| {
|
||||||
async fn main() {
|
async fn main() {
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
let conn = TcpStream::connect(&*FORWARD_EDGE_NODE_HOLDER)
|
cfg_if! {
|
||||||
.await
|
if #[cfg(features = "friends")]{
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let conn: SplittableBufferConnection = conn.into();
|
} else {
|
||||||
|
regular_backend::start_regular_backend().await
|
||||||
conn.send(DontRegister.to_data().unwrap()).await;
|
}
|
||||||
|
}
|
||||||
let conn = new_rmc_gateway_connection(conn, |r| {
|
|
||||||
Arc::new(OnlyRemote::<RemoteEdgeNodeHolder>::new(r))
|
|
||||||
});
|
|
||||||
|
|
||||||
new_simple_backend(move |_, _| {
|
|
||||||
let controller = conn.clone();
|
|
||||||
Arc::new(AuthHandler {
|
|
||||||
destination_server_acct: &SECURE_SERVER_ACCOUNT,
|
|
||||||
build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0",
|
|
||||||
control_server: controller,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
|
use cfg_if::cfg_if;
|
||||||
use rnex_core::common::setup;
|
use rnex_core::common::setup;
|
||||||
use rnex_core::executables::common::new_simple_backend;
|
use rnex_core::executables::common::new_simple_backend;
|
||||||
|
use rnex_core::executables::friends_backend::start_friends_backend;
|
||||||
use rnex_core::nex::matchmake::MatchmakeManager;
|
use rnex_core::nex::matchmake::MatchmakeManager;
|
||||||
use rnex_core::nex::remote_console::RemoteConsole;
|
use rnex_core::nex::remote_console::RemoteConsole;
|
||||||
use rnex_core::nex::user::User;
|
use rnex_core::nex::user::User;
|
||||||
|
|
@ -11,27 +13,11 @@ use std::sync::atomic::AtomicU32;
|
||||||
async fn main() {
|
async fn main() {
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
let mmm = Arc::new(MatchmakeManager {
|
cfg_if! {
|
||||||
//gid_counter: AtomicU32::new(1),
|
if #[cfg(feature = "friends")]{
|
||||||
sessions: Default::default(),
|
start_friends_backend().await;
|
||||||
users: Default::default(),
|
} else {
|
||||||
rv_cid_counter: AtomicU32::new(1),
|
regular_backend::start_regular_backend().await
|
||||||
});
|
}
|
||||||
|
}
|
||||||
let weak_mmm = Arc::downgrade(&mmm);
|
|
||||||
|
|
||||||
MatchmakeManager::initialize_garbage_collect_thread(weak_mmm).await;
|
|
||||||
|
|
||||||
new_simple_backend(move |c, r| {
|
|
||||||
let mmm = mmm.clone();
|
|
||||||
Arc::new_cyclic(move |this| User {
|
|
||||||
this: this.clone(),
|
|
||||||
ip: c.prudpsock_addr,
|
|
||||||
pid: c.pid,
|
|
||||||
remote: RemoteConsole::new(r),
|
|
||||||
matchmake_manager: mmm,
|
|
||||||
station_url: Default::default(),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
rnex-core/src/executables/friends_backend.rs
Normal file
22
rnex-core/src/executables/friends_backend.rs
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
use std::sync::{Arc, atomic::AtomicU32};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
executables::common::new_simple_backend,
|
||||||
|
nex::friends_handler::{FriendsManager, FriendsUser},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub async fn start_friends_backend() {
|
||||||
|
let fm = Arc::new(FriendsManager {
|
||||||
|
cid_counter: AtomicU32::new(1),
|
||||||
|
});
|
||||||
|
|
||||||
|
new_simple_backend(move |c, r| {
|
||||||
|
let fm = fm.clone();
|
||||||
|
Arc::new_cyclic(move |this| FriendsUser {
|
||||||
|
fm,
|
||||||
|
addr: c.prudpsock_addr,
|
||||||
|
pid: c.pid,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
@ -1 +1,3 @@
|
||||||
pub mod common;
|
pub mod common;
|
||||||
|
pub mod friends_backend;
|
||||||
|
pub mod regular_backend;
|
||||||
|
|
|
||||||
33
rnex-core/src/executables/regular_backend.rs
Normal file
33
rnex-core/src/executables/regular_backend.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
use std::sync::{Arc, atomic::AtomicU32};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
executables::common::new_simple_backend,
|
||||||
|
nex::{matchmake::MatchmakeManager, remote_console::RemoteConsole, user::User},
|
||||||
|
rmc::protocols::RmcPureRemoteObject,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub async fn start_regular_backend() {
|
||||||
|
let mmm = Arc::new(MatchmakeManager {
|
||||||
|
//gid_counter: AtomicU32::new(1),
|
||||||
|
sessions: Default::default(),
|
||||||
|
users: Default::default(),
|
||||||
|
rv_cid_counter: AtomicU32::new(1),
|
||||||
|
});
|
||||||
|
|
||||||
|
let weak_mmm = Arc::downgrade(&mmm);
|
||||||
|
|
||||||
|
MatchmakeManager::initialize_garbage_collect_thread(weak_mmm).await;
|
||||||
|
|
||||||
|
new_simple_backend(move |c, r| {
|
||||||
|
let mmm = mmm.clone();
|
||||||
|
Arc::new_cyclic(move |this| User {
|
||||||
|
this: this.clone(),
|
||||||
|
ip: c.prudpsock_addr,
|
||||||
|
pid: c.pid,
|
||||||
|
remote: RemoteConsole::new(r),
|
||||||
|
matchmake_manager: mmm,
|
||||||
|
station_url: Default::default(),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::rmc::structures::RmcSerialize;
|
|
||||||
use bytemuck::{Pod, Zeroable, bytes_of};
|
use bytemuck::{Pod, Zeroable, bytes_of};
|
||||||
|
use cfg_if::cfg_if;
|
||||||
use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Utc};
|
use chrono::{Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike, Utc};
|
||||||
use hmac::Hmac;
|
use hmac::Hmac;
|
||||||
use hmac::Mac;
|
use hmac::Mac;
|
||||||
|
|
@ -8,7 +8,20 @@ use rc4::KeyInit;
|
||||||
use rc4::cipher::StreamCipherCoreWrapper;
|
use rc4::cipher::StreamCipherCoreWrapper;
|
||||||
use rc4::consts::U16;
|
use rc4::consts::U16;
|
||||||
use rc4::{Rc4, Rc4Core, StreamCipher};
|
use rc4::{Rc4, Rc4Core, StreamCipher};
|
||||||
|
use rnex_core::rmc::structures::RmcSerialize;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
|
use typenum::Unsigned;
|
||||||
|
|
||||||
|
use rnex_core::rmc::structures::Result;
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature = "friends")]{
|
||||||
|
pub type SESSION_KEY_LENGTH_TY = U16;
|
||||||
|
} else {
|
||||||
|
pub type SESSION_KEY_LENGTH_TY = U32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub const SESSION_KEY_LENGTH: usize = SESSION_KEY_LENGTH_TY::USIZE;
|
||||||
|
|
||||||
type Md5Hmac = Hmac<md5::Md5>;
|
type Md5Hmac = Hmac<md5::Md5>;
|
||||||
|
|
||||||
|
|
@ -99,11 +112,11 @@ impl KerberosDateTime {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for KerberosDateTime {
|
impl RmcSerialize for KerberosDateTime {
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||||
Ok(self.0.serialize(writer)?)
|
Ok(self.0.serialize(writer)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
fn deserialize(reader: &mut impl Read) -> Result<Self> {
|
||||||
Ok(Self(u64::deserialize(reader)?))
|
Ok(Self(u64::deserialize(reader)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -113,7 +126,7 @@ impl RmcSerialize for KerberosDateTime {
|
||||||
pub struct TicketInternalData {
|
pub struct TicketInternalData {
|
||||||
pub issued_time: KerberosDateTime,
|
pub issued_time: KerberosDateTime,
|
||||||
pub pid: u32,
|
pub pid: u32,
|
||||||
pub session_key: [u8; 32],
|
pub session_key: [u8; SESSION_KEY_LENGTH],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TicketInternalData {
|
impl TicketInternalData {
|
||||||
|
|
@ -148,7 +161,7 @@ impl TicketInternalData {
|
||||||
#[derive(Pod, Zeroable, Copy, Clone)]
|
#[derive(Pod, Zeroable, Copy, Clone)]
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
pub struct Ticket {
|
pub struct Ticket {
|
||||||
pub session_key: [u8; 32],
|
pub session_key: [u8; SESSION_KEY_LENGTH],
|
||||||
pub pid: u32,
|
pub pid: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::grpc::account;
|
use crate::grpc::account;
|
||||||
use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement};
|
use crate::reggie::{RemoteEdgeNodeHolder, RemoteEdgeNodeManagement};
|
||||||
use crate::{define_rmc_proto, kerberos};
|
use crate::{define_rmc_proto, kerberos};
|
||||||
|
use cfg_if::cfg_if;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
use macros::rmc_struct;
|
use macros::rmc_struct;
|
||||||
use rnex_core::kerberos::{KerberosDateTime, Ticket, derive_key};
|
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::response::ErrorCode::Core_Unknown;
|
||||||
use rnex_core::rmc::structures::any::Any;
|
use rnex_core::rmc::structures::any::Any;
|
||||||
use rnex_core::rmc::structures::connection_data::ConnectionData;
|
use rnex_core::rmc::structures::connection_data::ConnectionData;
|
||||||
|
use rnex_core::rmc::structures::connection_data::ConnectionDataOld;
|
||||||
use rnex_core::rmc::structures::qresult::QResult;
|
use rnex_core::rmc::structures::qresult::QResult;
|
||||||
use std::hash::{DefaultHasher, Hasher};
|
use std::hash::{DefaultHasher, Hasher};
|
||||||
use std::net::SocketAddrV4;
|
use std::net::SocketAddrV4;
|
||||||
|
|
@ -49,7 +51,13 @@ pub fn generate_ticket(
|
||||||
encrypted_session_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 {
|
let Ok(mut client) = account::Client::new().await else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
@ -58,7 +66,7 @@ async fn get_login_data_by_pid(pid: u32) -> Option<(u32, [u8; 16])> {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
Some((pid, passwd))
|
Some((pid, passwd.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn station_url_from_sock_addr(sock_addr: SocketAddrV4) -> String {
|
fn station_url_from_sock_addr(sock_addr: SocketAddrV4) -> String {
|
||||||
|
|
@ -118,6 +126,42 @@ impl Auth for AuthHandler {
|
||||||
async fn login(
|
async fn login(
|
||||||
&self,
|
&self,
|
||||||
name: String,
|
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> {
|
) -> Result<(QResult, u32, Vec<u8>, ConnectionData, String), ErrorCode> {
|
||||||
let (pid, ticket) = self.generate_ticket_from_name(&name).await?;
|
let (pid, ticket) = self.generate_ticket_from_name(&name).await?;
|
||||||
|
|
||||||
|
|
@ -152,14 +196,6 @@ impl Auth for AuthHandler {
|
||||||
Ok(ret)
|
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(
|
async fn request_ticket(
|
||||||
&self,
|
&self,
|
||||||
source_pid: u32,
|
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 account;
|
||||||
pub mod auth_handler;
|
pub mod auth_handler;
|
||||||
pub mod user;
|
pub mod common;
|
||||||
pub mod remote_console;
|
pub mod friends_handler;
|
||||||
pub mod matchmake;
|
pub mod matchmake;
|
||||||
|
pub mod remote_console;
|
||||||
|
pub mod user;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::define_rmc_proto;
|
use crate::define_rmc_proto;
|
||||||
|
use crate::nex::common::get_station_urls;
|
||||||
use crate::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager};
|
use crate::nex::matchmake::{ExtendedMatchmakeSession, MatchmakeManager};
|
||||||
use crate::nex::remote_console::RemoteConsole;
|
use crate::nex::remote_console::RemoteConsole;
|
||||||
use crate::rmc::protocols::matchmake::{
|
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::ranking::{Ranking, RawRanking, RawRankingInfo, RemoteRanking};
|
||||||
use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure};
|
use rnex_core::rmc::protocols::secure::{RawSecure, RawSecureInfo, RemoteSecure, Secure};
|
||||||
use rnex_core::rmc::response::ErrorCode;
|
use rnex_core::rmc::response::ErrorCode;
|
||||||
|
use rnex_core::rmc::structures::any::Any;
|
||||||
use rnex_core::rmc::structures::matchmake::{
|
use rnex_core::rmc::structures::matchmake::{
|
||||||
AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession,
|
AutoMatchmakeParam, CreateMatchmakeSessionParam, JoinMatchmakeSessionParam, MatchmakeSession,
|
||||||
};
|
};
|
||||||
|
|
@ -71,97 +73,27 @@ impl Secure for User {
|
||||||
users.insert(cid, self.this.clone());
|
users.insert(cid, self.this.clone());
|
||||||
drop(users);
|
drop(users);
|
||||||
|
|
||||||
let mut public_station: Option<StationUrl> = None;
|
let stations = get_station_urls(&station_urls, self.ip, self.pid, cid).await?;
|
||||||
let mut private_station: Option<StationUrl> = None;
|
|
||||||
|
|
||||||
for station in station_urls {
|
let first = stations.first().unwrap().clone();
|
||||||
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 mut lock = self.station_url.write().await;
|
let mut lock = self.station_url.write().await;
|
||||||
|
|
||||||
*lock = vec![
|
*lock = stations;
|
||||||
public_station.clone(),
|
|
||||||
// private_station.clone()
|
|
||||||
];
|
|
||||||
|
|
||||||
drop(lock);
|
drop(lock);
|
||||||
|
|
||||||
let result = QResult::success(ErrorCode::Core_Unknown);
|
let result = QResult::success(ErrorCode::Core_Unknown);
|
||||||
|
|
||||||
let out = public_station.to_string();
|
Ok((result, cid, first))
|
||||||
|
}
|
||||||
|
|
||||||
println!("out: {}", out);
|
async fn register_ex(
|
||||||
|
&self,
|
||||||
Ok((result, cid, public_station))
|
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> {
|
async fn replace_url(&self, target_url: StationUrl, dest: StationUrl) -> Result<(), ErrorCode> {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
pub mod encryption;
|
pub mod encryption;
|
||||||
pub mod socket_addr;
|
pub mod socket_addr;
|
||||||
pub mod station_url;
|
pub mod station_url;
|
||||||
|
pub mod ticket;
|
||||||
pub mod types_flags;
|
pub mod types_flags;
|
||||||
pub mod virtual_port;
|
pub mod virtual_port;
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,24 @@
|
||||||
|
use hmac::Hmac;
|
||||||
|
use macros::RmcSerialize;
|
||||||
|
use md5::digest::Mac;
|
||||||
|
use rnex_core::prudp::virtual_port::VirtualPort;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::net::SocketAddrV4;
|
use std::net::SocketAddrV4;
|
||||||
use hmac::{Hmac};
|
|
||||||
use md5::digest::Mac;
|
|
||||||
use macros::RmcSerialize;
|
|
||||||
use rnex_core::prudp::virtual_port::VirtualPort;
|
|
||||||
|
|
||||||
type Md5Hmac = Hmac<md5::Md5>;
|
type Md5Hmac = Hmac<md5::Md5>;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Hash, Debug, Copy, Clone, Ord, PartialOrd, RmcSerialize)]
|
#[derive(Eq, PartialEq, Hash, Debug, Copy, Clone, Ord, PartialOrd, RmcSerialize)]
|
||||||
#[rmc_struct(0)]
|
#[rmc_struct(0)]
|
||||||
pub struct PRUDPSockAddr{
|
pub struct PRUDPSockAddr {
|
||||||
pub regular_socket_addr: SocketAddrV4,
|
pub regular_socket_addr: SocketAddrV4,
|
||||||
pub virtual_port: VirtualPort
|
pub virtual_port: VirtualPort,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PRUDPSockAddr {
|
||||||
|
pub fn new(regular_socket_addr: SocketAddrV4, virtual_port: VirtualPort) -> Self {
|
||||||
impl PRUDPSockAddr{
|
Self {
|
||||||
pub fn new(regular_socket_addr: SocketAddrV4, virtual_port: VirtualPort) -> Self{
|
|
||||||
Self{
|
|
||||||
regular_socket_addr,
|
regular_socket_addr,
|
||||||
virtual_port
|
virtual_port,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,8 +28,11 @@ impl PRUDPSockAddr{
|
||||||
let data = self.regular_socket_addr.ip().octets().to_vec();
|
let data = self.regular_socket_addr.ip().octets().to_vec();
|
||||||
//data.extend_from_slice(&self.regular_socket_addr.port().to_be_bytes());
|
//data.extend_from_slice(&self.regular_socket_addr.port().to_be_bytes());
|
||||||
|
|
||||||
hmac.write_all(&data).expect("figuring this out was complete ass");
|
hmac.write_all(&data)
|
||||||
let result: [u8; 16] = hmac.finalize().into_bytes()[0..16].try_into().expect("fuck");
|
.expect("figuring this out was complete ass");
|
||||||
|
let result: [u8; 16] = hmac.finalize().into_bytes()[0..16]
|
||||||
|
.try_into()
|
||||||
|
.expect("fuck");
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
81
rnex-core/src/prudp/ticket.rs
Normal file
81
rnex-core/src/prudp/ticket.rs
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
use log::{error, info};
|
||||||
|
use rc4::{KeyInit, Rc4, Rc4Core, StreamCipher, cipher::StreamCipherCoreWrapper};
|
||||||
|
use typenum::{U16, U32};
|
||||||
|
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
kerberos::{SESSION_KEY_LENGTH, SESSION_KEY_LENGTH_TY, TicketInternalData, derive_key},
|
||||||
|
nex::account::Account,
|
||||||
|
rmc::structures::RmcSerialize,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn read_secure_connection_data(
|
||||||
|
data: &[u8],
|
||||||
|
act: &Account,
|
||||||
|
) -> Option<([u8; SESSION_KEY_LENGTH], u32, u32)> {
|
||||||
|
let mut cursor = Cursor::new(data);
|
||||||
|
|
||||||
|
let mut ticket_data: Vec<u8> = Vec::deserialize(&mut cursor).ok()?;
|
||||||
|
let mut request_data: Vec<u8> = Vec::deserialize(&mut cursor).ok()?;
|
||||||
|
info!(
|
||||||
|
"done
|
||||||
|
request data"
|
||||||
|
);
|
||||||
|
|
||||||
|
let ticket_data_size = ticket_data.len();
|
||||||
|
|
||||||
|
let ticket_data = &mut ticket_data[0..ticket_data_size - 0x10];
|
||||||
|
|
||||||
|
let server_key = derive_key(act.pid, &act.kerbros_password[..]);
|
||||||
|
|
||||||
|
let mut rc4: StreamCipherCoreWrapper<Rc4Core<U16>> =
|
||||||
|
Rc4::new_from_slice(&server_key).expect("unable to init rc4 keystream");
|
||||||
|
|
||||||
|
rc4.apply_keystream(ticket_data);
|
||||||
|
|
||||||
|
let ticket_data: &TicketInternalData = match bytemuck::try_from_bytes(ticket_data) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
error!("unable to read internal ticket data: {}", e);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// todo: add ticket expiration
|
||||||
|
|
||||||
|
let TicketInternalData {
|
||||||
|
session_key,
|
||||||
|
pid: ticket_source_pid,
|
||||||
|
issued_time,
|
||||||
|
} = *ticket_data;
|
||||||
|
|
||||||
|
// todo: add checking if tickets are signed with a valid md5-hmac
|
||||||
|
let request_data_length = request_data.len();
|
||||||
|
let request_data = &mut request_data[0..request_data_length - 0x10];
|
||||||
|
|
||||||
|
let mut rc4: StreamCipherCoreWrapper<Rc4Core<SESSION_KEY_LENGTH_TY>> =
|
||||||
|
Rc4::new_from_slice(&session_key).expect("unable to init rc4 keystream");
|
||||||
|
|
||||||
|
rc4.apply_keystream(request_data);
|
||||||
|
|
||||||
|
let mut reqest_data_cursor = Cursor::new(request_data);
|
||||||
|
|
||||||
|
let pid: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?;
|
||||||
|
|
||||||
|
if pid != ticket_source_pid {
|
||||||
|
let ticket_created_on = issued_time.to_regular_time();
|
||||||
|
|
||||||
|
error!(
|
||||||
|
"someone tried to spoof their pid, ticket was created on: {}",
|
||||||
|
ticket_created_on.to_rfc2822()
|
||||||
|
);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _cid: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?;
|
||||||
|
let response_check: u32 = reqest_data_cursor.read_struct(IS_BIG_ENDIAN).ok()?;
|
||||||
|
|
||||||
|
Some((session_key, pid, response_check))
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::rmc::structures::connection_data::ConnectionData;
|
use crate::rmc::structures::connection_data::{ConnectionData, ConnectionDataOld};
|
||||||
use macros::{method_id, rmc_proto};
|
use macros::{method_id, rmc_proto};
|
||||||
use rnex_core::rmc::response::ErrorCode;
|
use rnex_core::rmc::response::ErrorCode;
|
||||||
use rnex_core::rmc::structures::any::Any;
|
use rnex_core::rmc::structures::any::Any;
|
||||||
|
|
@ -14,7 +14,7 @@ pub trait Auth {
|
||||||
async fn login(
|
async fn login(
|
||||||
&self,
|
&self,
|
||||||
name: String,
|
name: String,
|
||||||
) -> Result<(QResult, u32, Vec<u8>, ConnectionData, String), ErrorCode>;
|
) -> Result<(QResult, u32, Vec<u8>, ConnectionDataOld, String), ErrorCode>;
|
||||||
|
|
||||||
/// representation of the `LoginEx` method(for details see the
|
/// representation of the `LoginEx` method(for details see the
|
||||||
/// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol))
|
/// [kinnay wiki entry](https://github.com/kinnay/NintendoClients/wiki/Authentication-Protocol))
|
||||||
|
|
|
||||||
146
rnex-core/src/rmc/protocols/friends.rs
Normal file
146
rnex-core/src/rmc/protocols/friends.rs
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
use macros::{RmcSerialize, method_id, rmc_proto};
|
||||||
|
|
||||||
|
use rnex_core::{kerberos::KerberosDateTime, rmc::response::ErrorCode};
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct MiiV2 {
|
||||||
|
pub name: String,
|
||||||
|
pub unk: u8,
|
||||||
|
pub unk2: u8,
|
||||||
|
pub mii_data: Vec<u8>,
|
||||||
|
pub date_time: KerberosDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct PrincipalBasicInfo {
|
||||||
|
pub pid: u32,
|
||||||
|
pub nnid: String,
|
||||||
|
pub mii: MiiV2,
|
||||||
|
pub unk: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct NNAInfo {
|
||||||
|
pub principal_basic_info: PrincipalBasicInfo,
|
||||||
|
pub unk: u8,
|
||||||
|
pub unk2: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct GameKey {
|
||||||
|
pub tid: u64,
|
||||||
|
pub version: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct NintendoPresenceV2 {
|
||||||
|
pub changed_flags: u32,
|
||||||
|
pub is_online: bool,
|
||||||
|
pub game_key: GameKey,
|
||||||
|
pub unk: u8,
|
||||||
|
pub message: String,
|
||||||
|
pub unk2: u32,
|
||||||
|
pub unk3: u8,
|
||||||
|
pub game_server_id: u32,
|
||||||
|
pub unk4: u32,
|
||||||
|
pub pid: u32,
|
||||||
|
pub gid: u32,
|
||||||
|
pub app_data: Vec<u8>,
|
||||||
|
pub unk5: u8,
|
||||||
|
pub unk6: u8,
|
||||||
|
pub unk7: u8,
|
||||||
|
}
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct PrincipalPreference {
|
||||||
|
pub show_online: bool,
|
||||||
|
pub show_playing_title: bool,
|
||||||
|
pub block_friend_request: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct Comment {
|
||||||
|
pub unk: u8,
|
||||||
|
pub message: String,
|
||||||
|
pub last_changed: KerberosDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct FriendInfo {
|
||||||
|
pub nna_info: NNAInfo,
|
||||||
|
pub presence: NintendoPresenceV2,
|
||||||
|
pub comment: Comment,
|
||||||
|
pub became_friends: KerberosDateTime,
|
||||||
|
pub last_online: KerberosDateTime,
|
||||||
|
pub unk: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct FriendRequestMessage {
|
||||||
|
pub friend_request_id: u64,
|
||||||
|
pub is_recieved: u8,
|
||||||
|
pub unk: u8,
|
||||||
|
pub message: String,
|
||||||
|
pub unk2: u8,
|
||||||
|
pub unk3: String,
|
||||||
|
pub game_key: GameKey,
|
||||||
|
pub unk4: KerberosDateTime,
|
||||||
|
pub expires_on: KerberosDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct FriendRequest {
|
||||||
|
pub basic_info: PrincipalBasicInfo,
|
||||||
|
pub request_message: FriendRequestMessage,
|
||||||
|
pub sent_on: KerberosDateTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct BlacklistedPrincipal {
|
||||||
|
pub basic_info: PrincipalBasicInfo,
|
||||||
|
pub game_key: GameKey,
|
||||||
|
pub since: KerberosDateTime,
|
||||||
|
}
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
pub struct PersistentNotification {
|
||||||
|
pub unk1: u64,
|
||||||
|
pub unk2: u32,
|
||||||
|
pub unk3: u32,
|
||||||
|
pub unk4: u32,
|
||||||
|
pub unk5: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rmc_proto(102)]
|
||||||
|
pub trait Friends {
|
||||||
|
#[method_id(1)]
|
||||||
|
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,
|
||||||
|
>;
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#![allow(async_fn_in_trait)]
|
#![allow(async_fn_in_trait)]
|
||||||
|
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
|
pub mod friends;
|
||||||
pub mod matchmake;
|
pub mod matchmake;
|
||||||
pub mod matchmake_ext;
|
pub mod matchmake_ext;
|
||||||
pub mod matchmake_extension;
|
pub mod matchmake_extension;
|
||||||
|
|
@ -294,8 +295,8 @@ async fn handle_incoming<T: RmcCallable + Send + Sync + 'static>(
|
||||||
} = message;
|
} = message;
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"RMC REQUEST: Proto: {}; Method: {};",
|
"RMC REQUEST: Proto: {}; Method: {}; cid: {}",
|
||||||
protocol_id, method_id
|
protocol_id, method_id, call_id
|
||||||
);
|
);
|
||||||
|
|
||||||
remote
|
remote
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,21 @@ use rnex_core::prudp::station_url::StationUrl;
|
||||||
use rnex_core::rmc::response::ErrorCode;
|
use rnex_core::rmc::response::ErrorCode;
|
||||||
use rnex_core::rmc::structures::qresult::QResult;
|
use rnex_core::rmc::structures::qresult::QResult;
|
||||||
|
|
||||||
|
use crate::rmc::structures::any::Any;
|
||||||
|
|
||||||
#[rmc_proto(11)]
|
#[rmc_proto(11)]
|
||||||
pub trait Secure {
|
pub trait Secure {
|
||||||
#[method_id(1)]
|
#[method_id(1)]
|
||||||
async fn register(&self, station_urls: Vec<StationUrl>) -> Result<(QResult, u32, StationUrl), ErrorCode>;
|
async fn register(
|
||||||
|
&self,
|
||||||
|
station_urls: Vec<StationUrl>,
|
||||||
|
) -> Result<(QResult, u32, StationUrl), ErrorCode>;
|
||||||
|
#[method_id(4)]
|
||||||
|
async fn register_ex(
|
||||||
|
&self,
|
||||||
|
station_urls: Vec<StationUrl>,
|
||||||
|
data: Any,
|
||||||
|
) -> Result<(QResult, u32, StationUrl), ErrorCode>;
|
||||||
#[method_id(7)]
|
#[method_id(7)]
|
||||||
async fn replace_url(&self, target: StationUrl, dest: StationUrl) -> Result<(), ErrorCode>;
|
async fn replace_url(&self, target: StationUrl, dest: StationUrl) -> Result<(), ErrorCode>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
|
use rnex_core::rmc::structures::{Result, RmcSerialize};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||||
use super::{Result, RmcSerialize};
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Any{
|
pub struct Any {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub data: Vec<u8>
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for Any{
|
impl RmcSerialize for Any {
|
||||||
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||||
self.name.serialize(writer)?;
|
self.name.serialize(writer)?;
|
||||||
|
|
||||||
|
|
@ -32,11 +32,6 @@ impl RmcSerialize for Any{
|
||||||
|
|
||||||
reader.read_exact(&mut data)?;
|
reader.read_exact(&mut data)?;
|
||||||
|
|
||||||
Ok(
|
Ok(Any { name, data })
|
||||||
Any{
|
|
||||||
name,
|
|
||||||
data
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
use std::io::{Read, Write};
|
use crate::rmc::structures::Result;
|
||||||
use crate::rmc::structures::RmcSerialize;
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
impl<'a> RmcSerialize for &'a [u8] {
|
||||||
|
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||||
impl<'a> RmcSerialize for &'a [u8]{
|
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
|
||||||
let u32_size = self.len() as u32;
|
let u32_size = self.len() as u32;
|
||||||
writer.write(bytemuck::bytes_of(&u32_size))?;
|
writer.write(bytemuck::bytes_of(&u32_size))?;
|
||||||
writer.write(self)?;
|
writer.write(self)?;
|
||||||
|
|
@ -13,25 +12,25 @@ impl<'a> RmcSerialize for &'a [u8]{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// DO NOT USE (also maybe split off the serialize and deserialize functions at some point)
|
/// DO NOT USE (also maybe split off the serialize and deserialize functions at some point)
|
||||||
fn deserialize(_reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
fn deserialize(_reader: &mut impl Read) -> Result<Self> {
|
||||||
panic!("cannot deserialize to a u8 slice reference (use this ONLY for writing)")
|
panic!("cannot deserialize to a u8 slice reference (use this ONLY for writing)")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
fn serialize_write_size(&self) -> Result<u32> {
|
||||||
Ok(4 + self.len() as u32)
|
Ok(4 + self.len() as u32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for Box<[u8]>{
|
impl RmcSerialize for Box<[u8]> {
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||||
(&self[..]).serialize(writer)
|
(&self[..]).serialize(writer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
fn deserialize(reader: &mut impl Read) -> Result<Self> {
|
||||||
Vec::deserialize(reader).map(|v| v.into_boxed_slice())
|
Vec::deserialize(reader).map(|v| v.into_boxed_slice())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
fn serialize_write_size(&self) -> Result<u32> {
|
||||||
(&self[..]).serialize_write_size()
|
(&self[..]).serialize_write_size()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,19 @@
|
||||||
|
|
||||||
use macros::RmcSerialize;
|
use macros::RmcSerialize;
|
||||||
use rnex_core::kerberos::KerberosDateTime;
|
use rnex_core::kerberos::KerberosDateTime;
|
||||||
|
|
||||||
#[derive(Debug, RmcSerialize)]
|
#[derive(Debug, RmcSerialize)]
|
||||||
#[rmc_struct(1)]
|
#[rmc_struct(1)]
|
||||||
pub struct ConnectionData{
|
pub struct ConnectionData {
|
||||||
pub station_url: String,
|
pub station_url: String,
|
||||||
pub special_protocols: Vec<u8>,
|
pub special_protocols: Vec<u8>,
|
||||||
pub special_station_url: String,
|
pub special_station_url: String,
|
||||||
pub date_time: KerberosDateTime
|
pub date_time: KerberosDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, RmcSerialize)]
|
||||||
|
#[rmc_struct(1)]
|
||||||
|
pub struct ConnectionDataOld {
|
||||||
|
pub station_url: String,
|
||||||
|
pub special_protocols: Vec<u8>,
|
||||||
|
pub special_station_url: String,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
use std::io::{Read, Write};
|
|
||||||
use bytemuck::bytes_of;
|
|
||||||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
|
||||||
use crate::rmc::structures::RmcSerialize;
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
use bytemuck::bytes_of;
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||||
|
|
||||||
impl RmcSerialize for u8{
|
impl RmcSerialize for u8 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(writer.write_all(bytes_of(self))?)
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
|
@ -19,7 +19,7 @@ impl RmcSerialize for u8{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for i8{
|
impl RmcSerialize for i8 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(writer.write_all(bytes_of(self))?)
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
|
@ -35,7 +35,7 @@ impl RmcSerialize for i8{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for u16{
|
impl RmcSerialize for u16 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(writer.write_all(bytes_of(self))?)
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
|
@ -50,7 +50,7 @@ impl RmcSerialize for u16{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for i16{
|
impl RmcSerialize for i16 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(writer.write_all(bytes_of(self))?)
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
|
@ -65,7 +65,7 @@ impl RmcSerialize for i16{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for u32{
|
impl RmcSerialize for u32 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(writer.write_all(bytes_of(self))?)
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
|
@ -80,7 +80,7 @@ impl RmcSerialize for u32{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for i32{
|
impl RmcSerialize for i32 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(writer.write_all(bytes_of(self))?)
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
|
@ -95,7 +95,7 @@ impl RmcSerialize for i32{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for u64{
|
impl RmcSerialize for u64 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(writer.write_all(bytes_of(self))?)
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
|
@ -110,7 +110,7 @@ impl RmcSerialize for u64{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for i64{
|
impl RmcSerialize for i64 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(writer.write_all(bytes_of(self))?)
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
|
@ -125,7 +125,7 @@ impl RmcSerialize for i64{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for f64{
|
impl RmcSerialize for f64 {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
Ok(writer.write_all(bytes_of(self))?)
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
|
@ -141,10 +141,10 @@ impl RmcSerialize for f64{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for bool{
|
impl RmcSerialize for bool {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
match self{
|
match self {
|
||||||
true => writer.write_all(&[1])?,
|
true => writer.write_all(&[1])?,
|
||||||
false => writer.write_all(&[0])?,
|
false => writer.write_all(&[0])?,
|
||||||
}
|
}
|
||||||
|
|
@ -161,8 +161,7 @@ impl RmcSerialize for bool{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: RmcSerialize, U: RmcSerialize> RmcSerialize for (T, U) {
|
||||||
impl<T: RmcSerialize, U: RmcSerialize> RmcSerialize for (T, U){
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
self.0.serialize(writer)?;
|
self.0.serialize(writer)?;
|
||||||
|
|
@ -178,14 +177,11 @@ impl<T: RmcSerialize, U: RmcSerialize> RmcSerialize for (T, U){
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||||
Ok(
|
Ok(self.0.serialize_write_size()? + self.1.serialize_write_size()?)
|
||||||
self.0.serialize_write_size()? +
|
|
||||||
self.1.serialize_write_size()?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize> RmcSerialize for (T, U, V){
|
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize> RmcSerialize for (T, U, V) {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
self.0.serialize(writer)?;
|
self.0.serialize(writer)?;
|
||||||
|
|
@ -203,15 +199,15 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize> RmcSerialize for (T, U,
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||||
Ok(
|
Ok(self.0.serialize_write_size()?
|
||||||
self.0.serialize_write_size()? +
|
+ self.1.serialize_write_size()?
|
||||||
self.1.serialize_write_size()? +
|
+ self.2.serialize_write_size()?)
|
||||||
self.2.serialize_write_size()?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize> RmcSerialize for (T, U, V, W){
|
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize> RmcSerialize
|
||||||
|
for (T, U, V, W)
|
||||||
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
self.0.serialize(writer)?;
|
self.0.serialize(writer)?;
|
||||||
|
|
@ -231,16 +227,16 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize> RmcSeri
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||||
Ok(
|
Ok(self.0.serialize_write_size()?
|
||||||
self.0.serialize_write_size()? +
|
+ self.1.serialize_write_size()?
|
||||||
self.1.serialize_write_size()? +
|
+ self.2.serialize_write_size()?
|
||||||
self.2.serialize_write_size()? +
|
+ self.3.serialize_write_size()?)
|
||||||
self.3.serialize_write_size()?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcSerialize> RmcSerialize for (T, U, V, W, X){
|
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcSerialize>
|
||||||
|
RmcSerialize for (T, U, V, W, X)
|
||||||
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
self.0.serialize(writer)?;
|
self.0.serialize(writer)?;
|
||||||
|
|
@ -264,17 +260,23 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||||
Ok(
|
Ok(self.0.serialize_write_size()?
|
||||||
self.0.serialize_write_size()? +
|
+ self.1.serialize_write_size()?
|
||||||
self.1.serialize_write_size()? +
|
+ self.2.serialize_write_size()?
|
||||||
self.2.serialize_write_size()? +
|
+ self.2.serialize_write_size()?
|
||||||
self.2.serialize_write_size()? +
|
+ self.3.serialize_write_size()?)
|
||||||
self.3.serialize_write_size()?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcSerialize, Y: RmcSerialize> RmcSerialize for (T, U, V, W, X, Y){
|
impl<
|
||||||
|
T: RmcSerialize,
|
||||||
|
U: RmcSerialize,
|
||||||
|
V: RmcSerialize,
|
||||||
|
W: RmcSerialize,
|
||||||
|
X: RmcSerialize,
|
||||||
|
Y: RmcSerialize,
|
||||||
|
> RmcSerialize for (T, U, V, W, X, Y)
|
||||||
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
self.0.serialize(writer)?;
|
self.0.serialize(writer)?;
|
||||||
|
|
@ -300,18 +302,25 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||||
Ok(
|
Ok(self.0.serialize_write_size()?
|
||||||
self.0.serialize_write_size()? +
|
+ self.1.serialize_write_size()?
|
||||||
self.1.serialize_write_size()? +
|
+ self.2.serialize_write_size()?
|
||||||
self.2.serialize_write_size()? +
|
+ self.3.serialize_write_size()?
|
||||||
self.3.serialize_write_size()? +
|
+ self.4.serialize_write_size()?
|
||||||
self.4.serialize_write_size()? +
|
+ self.5.serialize_write_size()?)
|
||||||
self.5.serialize_write_size()?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcSerialize, Y: RmcSerialize, Z: RmcSerialize> RmcSerialize for (T, U, V, W, X, Y, Z){
|
impl<
|
||||||
|
T: RmcSerialize,
|
||||||
|
U: RmcSerialize,
|
||||||
|
V: RmcSerialize,
|
||||||
|
W: RmcSerialize,
|
||||||
|
X: RmcSerialize,
|
||||||
|
Y: RmcSerialize,
|
||||||
|
Z: RmcSerialize,
|
||||||
|
> RmcSerialize for (T, U, V, W, X, Y, Z)
|
||||||
|
{
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
self.0.serialize(writer)?;
|
self.0.serialize(writer)?;
|
||||||
|
|
@ -338,19 +347,123 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||||
Ok(
|
Ok(self.0.serialize_write_size()?
|
||||||
self.0.serialize_write_size()? +
|
+ self.1.serialize_write_size()?
|
||||||
self.1.serialize_write_size()? +
|
+ self.2.serialize_write_size()?
|
||||||
self.2.serialize_write_size()? +
|
+ self.3.serialize_write_size()?
|
||||||
self.3.serialize_write_size()? +
|
+ self.4.serialize_write_size()?
|
||||||
self.4.serialize_write_size()? +
|
+ self.5.serialize_write_size()?
|
||||||
self.5.serialize_write_size()? +
|
+ self.6.serialize_write_size()?)
|
||||||
self.6.serialize_write_size()?
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: RmcSerialize> RmcSerialize for Box<T>{
|
impl<
|
||||||
|
T: RmcSerialize,
|
||||||
|
U: RmcSerialize,
|
||||||
|
V: RmcSerialize,
|
||||||
|
W: RmcSerialize,
|
||||||
|
X: RmcSerialize,
|
||||||
|
Y: RmcSerialize,
|
||||||
|
Z: RmcSerialize,
|
||||||
|
A: RmcSerialize,
|
||||||
|
> RmcSerialize for (T, U, V, W, X, Y, Z, A)
|
||||||
|
{
|
||||||
|
#[inline(always)]
|
||||||
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
self.0.serialize(writer)?;
|
||||||
|
self.1.serialize(writer)?;
|
||||||
|
self.2.serialize(writer)?;
|
||||||
|
self.3.serialize(writer)?;
|
||||||
|
self.4.serialize(writer)?;
|
||||||
|
self.5.serialize(writer)?;
|
||||||
|
self.6.serialize(writer)?;
|
||||||
|
self.7.serialize(writer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
let first = T::deserialize(reader)?;
|
||||||
|
let second = U::deserialize(reader)?;
|
||||||
|
let third = V::deserialize(reader)?;
|
||||||
|
let fourth = W::deserialize(reader)?;
|
||||||
|
let fifth = X::deserialize(reader)?;
|
||||||
|
let sixth = Y::deserialize(reader)?;
|
||||||
|
let seventh = Z::deserialize(reader)?;
|
||||||
|
let eighth = A::deserialize(reader)?;
|
||||||
|
|
||||||
|
Ok((first, second, third, fourth, fifth, sixth, seventh, eighth))
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||||
|
Ok(self.0.serialize_write_size()?
|
||||||
|
+ self.1.serialize_write_size()?
|
||||||
|
+ self.2.serialize_write_size()?
|
||||||
|
+ self.3.serialize_write_size()?
|
||||||
|
+ self.4.serialize_write_size()?
|
||||||
|
+ self.5.serialize_write_size()?
|
||||||
|
+ self.6.serialize_write_size()?
|
||||||
|
+ self.7.serialize_write_size()?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<
|
||||||
|
T: RmcSerialize,
|
||||||
|
U: RmcSerialize,
|
||||||
|
V: RmcSerialize,
|
||||||
|
W: RmcSerialize,
|
||||||
|
X: RmcSerialize,
|
||||||
|
Y: RmcSerialize,
|
||||||
|
Z: RmcSerialize,
|
||||||
|
A: RmcSerialize,
|
||||||
|
B: RmcSerialize,
|
||||||
|
> RmcSerialize for (T, U, V, W, X, Y, Z, A, B)
|
||||||
|
{
|
||||||
|
#[inline(always)]
|
||||||
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
self.0.serialize(writer)?;
|
||||||
|
self.1.serialize(writer)?;
|
||||||
|
self.2.serialize(writer)?;
|
||||||
|
self.3.serialize(writer)?;
|
||||||
|
self.4.serialize(writer)?;
|
||||||
|
self.5.serialize(writer)?;
|
||||||
|
self.6.serialize(writer)?;
|
||||||
|
self.7.serialize(writer)?;
|
||||||
|
self.8.serialize(writer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
let first = T::deserialize(reader)?;
|
||||||
|
let second = U::deserialize(reader)?;
|
||||||
|
let third = V::deserialize(reader)?;
|
||||||
|
let fourth = W::deserialize(reader)?;
|
||||||
|
let fifth = X::deserialize(reader)?;
|
||||||
|
let sixth = Y::deserialize(reader)?;
|
||||||
|
let seventh = Z::deserialize(reader)?;
|
||||||
|
let eighth = A::deserialize(reader)?;
|
||||||
|
let nineth = B::deserialize(reader)?;
|
||||||
|
|
||||||
|
Ok((
|
||||||
|
first, second, third, fourth, fifth, sixth, seventh, eighth, nineth,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
#[inline(always)]
|
||||||
|
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||||
|
Ok(self.0.serialize_write_size()?
|
||||||
|
+ self.1.serialize_write_size()?
|
||||||
|
+ self.2.serialize_write_size()?
|
||||||
|
+ self.3.serialize_write_size()?
|
||||||
|
+ self.4.serialize_write_size()?
|
||||||
|
+ self.5.serialize_write_size()?
|
||||||
|
+ self.6.serialize_write_size()?
|
||||||
|
+ self.7.serialize_write_size()?
|
||||||
|
+ self.8.serialize_write_size()?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: RmcSerialize> RmcSerialize for Box<T> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||||
self.as_ref().serialize(writer)
|
self.as_ref().serialize(writer)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
|
use rnex_core::kerberos::KerberosDateTime;
|
||||||
|
use rnex_core::rmc::structures;
|
||||||
|
use rnex_core::rmc::structures::{Result, RmcSerialize};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use crate::kerberos::KerberosDateTime;
|
|
||||||
use crate::rmc::structures;
|
|
||||||
use crate::rmc::structures::RmcSerialize;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub enum Variant{
|
pub enum Variant {
|
||||||
#[default]
|
#[default]
|
||||||
None,
|
None,
|
||||||
SInt64(i64),
|
SInt64(i64),
|
||||||
|
|
@ -15,9 +15,9 @@ pub enum Variant{
|
||||||
UInt64(u64),
|
UInt64(u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RmcSerialize for Variant{
|
impl RmcSerialize for Variant {
|
||||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||||
match self{
|
match self {
|
||||||
Variant::None => {
|
Variant::None => {
|
||||||
writer.write_all(&[0])?;
|
writer.write_all(&[0])?;
|
||||||
}
|
}
|
||||||
|
|
@ -50,8 +50,8 @@ impl RmcSerialize for Variant{
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
fn deserialize(reader: &mut impl Read) -> Result<Self> {
|
||||||
match u8::deserialize(reader)?{
|
match u8::deserialize(reader)? {
|
||||||
0 => Ok(Variant::None),
|
0 => Ok(Variant::None),
|
||||||
1 => Ok(Variant::SInt64(i64::deserialize(reader)?)),
|
1 => Ok(Variant::SInt64(i64::deserialize(reader)?)),
|
||||||
2 => Ok(Variant::Double(f64::deserialize(reader)?)),
|
2 => Ok(Variant::Double(f64::deserialize(reader)?)),
|
||||||
|
|
@ -59,7 +59,7 @@ impl RmcSerialize for Variant{
|
||||||
4 => Ok(Variant::String(String::deserialize(reader)?)),
|
4 => Ok(Variant::String(String::deserialize(reader)?)),
|
||||||
5 => Ok(Variant::DateTime(KerberosDateTime::deserialize(reader)?)),
|
5 => Ok(Variant::DateTime(KerberosDateTime::deserialize(reader)?)),
|
||||||
6 => Ok(Variant::UInt64(u64::deserialize(reader)?)),
|
6 => Ok(Variant::UInt64(u64::deserialize(reader)?)),
|
||||||
v => Err(structures::Error::UnexpectedValue(v as u64))
|
v => Err(structures::Error::UnexpectedValue(v as u64)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue