optimize
This commit is contained in:
parent
6625dab9c1
commit
5782951e68
25 changed files with 956 additions and 501 deletions
|
|
@ -29,9 +29,15 @@ typenum = "1.18.0"
|
|||
reqwest = { version= "0.12.18", features = ["blocking"]}
|
||||
json = "0.12.4"
|
||||
ctrlc = "3.4.7"
|
||||
criterion = "0.7.0"
|
||||
anyhow = "1.0.100"
|
||||
|
||||
[features]
|
||||
rmc_struct_header = []
|
||||
|
||||
|
||||
[[bench]]
|
||||
name = "rmc_serialization"
|
||||
harness = false
|
||||
|
||||
[[bin]]
|
||||
name = "backend_server_insecure"
|
||||
|
|
|
|||
99
rnex-core/benches/rmc_serialization.rs
Normal file
99
rnex-core/benches/rmc_serialization.rs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
use std::hint::black_box;
|
||||
use std::io::Cursor;
|
||||
use std::ops::Deref;
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
use once_cell::sync::Lazy;
|
||||
use rnex_core::kerberos::KerberosDateTime;
|
||||
use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria};
|
||||
use rnex_core::rmc::structures::RmcSerialize;
|
||||
use rnex_core::rmc::structures::variant::Variant;
|
||||
|
||||
static DUMMY: Lazy<AutoMatchmakeParam> = Lazy::new(|| AutoMatchmakeParam{
|
||||
additional_participants: vec![1,2,3,4],
|
||||
auto_matchmake_option: 10,
|
||||
gid_for_participation_check: 9,
|
||||
join_message: "hi".to_string(),
|
||||
participation_count: 32,
|
||||
target_gids: vec![45,2,51,1,1,1,1],
|
||||
search_criteria: vec![MatchmakeSessionSearchCriteria{
|
||||
attribs: vec!["hi".to_string(), "ig".to_string(), "gotta put data here".to_string()],
|
||||
exclude_locked: true,
|
||||
exclude_non_host_pid: false,
|
||||
exclude_system_password_set: true,
|
||||
exclude_user_password_set: false,
|
||||
game_mode: "some gamemode".to_string(),
|
||||
matchmake_param: MatchmakeParam{
|
||||
params: vec![
|
||||
("SR".to_string(), Variant::Bool(true)),
|
||||
("SR2".to_string(), Variant::Double(1.0)),
|
||||
("SR3".to_string(), Variant::SInt64(42)),
|
||||
("SR4".to_string(), Variant::String("test".to_string()))
|
||||
]
|
||||
},
|
||||
matchmake_system_type: "some type".to_string(),
|
||||
maximum_participants: "???".to_string(),
|
||||
minimum_participants: "-99".to_string(),
|
||||
refer_gid: 123,
|
||||
selection_method: 9999999,
|
||||
vacant_only: true,
|
||||
vacant_participants: 1000
|
||||
}],
|
||||
matchmake_session: MatchmakeSession{
|
||||
refer_gid: 10,
|
||||
matchmake_system_type: 139,
|
||||
matchmake_param: MatchmakeParam{
|
||||
params: vec![
|
||||
("QSR".to_string(), Variant::Bool(false)),
|
||||
("SRQ2".to_string(), Variant::Double(1.1)),
|
||||
("SQR3".to_string(), Variant::SInt64(422)),
|
||||
("SDR4".to_string(), Variant::String("tetst".to_string()))
|
||||
]
|
||||
},
|
||||
participation_count: 99,
|
||||
application_buffer: vec![1,2,3,4,5,6,7,8,9],
|
||||
attributes: vec![10,20,99,100000],
|
||||
datetime: KerberosDateTime::now(),
|
||||
gamemode: 111,
|
||||
open_participation: false,
|
||||
option0: 100,
|
||||
progress_score: 1,
|
||||
system_password_enabled: false,
|
||||
user_password: "aaa".to_string(),
|
||||
session_key: vec![91,123,5,2,1,2,4,124,4],
|
||||
user_password_enabled: false,
|
||||
gathering: Gathering{
|
||||
minimum_participants: 1,
|
||||
maximum_participants: 12,
|
||||
description: "aaargh".to_string(),
|
||||
flags: 100,
|
||||
host_pid: 999999919,
|
||||
owner_pid: 138830,
|
||||
participant_policy: 1,
|
||||
policy_argument: 99837,
|
||||
self_gid: 129,
|
||||
state: 1389488
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
static DUMMY_SER: Lazy<Vec<u8>> = Lazy::new(|| serialize_to_vec(DUMMY.deref()));
|
||||
|
||||
fn serialize_to_vec(r: &impl RmcSerialize) -> Vec<u8>{
|
||||
let mut vec = r.to_data();
|
||||
|
||||
vec.unwrap()
|
||||
}
|
||||
|
||||
fn read_struct<T: RmcSerialize>(r: &[u8]) -> T{
|
||||
T::deserialize(&mut Cursor::new(r)).unwrap()
|
||||
}
|
||||
fn matchmake_with_param(c: &mut Criterion) {
|
||||
let raw = DUMMY.deref();
|
||||
let ser = DUMMY_SER.deref().as_slice();
|
||||
c.bench_function("mmparam: ser", |b| b.iter(move || serialize_to_vec(black_box(raw))));
|
||||
c.bench_function("mmparam: de", |b| b.iter(move || read_struct::<AutoMatchmakeParam>(black_box(ser))));
|
||||
}
|
||||
|
||||
criterion_group!(benches, matchmake_with_param);
|
||||
criterion_main!(benches);
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ async fn main() {
|
|||
|
||||
let conn: SplittableBufferConnection = conn.into();
|
||||
|
||||
conn.send(DontRegister.to_data()).await;
|
||||
conn.send(DontRegister.to_data().unwrap()).await;
|
||||
|
||||
let conn = new_rmc_gateway_connection(conn, |r| Arc::new(OnlyRemote::<RemoteEdgeNodeHolder>::new(r)));
|
||||
|
||||
|
|
|
|||
|
|
@ -83,11 +83,11 @@ impl KerberosDateTime{
|
|||
}
|
||||
|
||||
impl RmcSerialize for KerberosDateTime{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(self.0.serialize(writer)?)
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(Self(u64::deserialize(reader)?))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,3 +24,7 @@ pub mod rnex_proxy_common;
|
|||
pub mod util;
|
||||
pub mod executables;
|
||||
pub use macros::*;
|
||||
|
||||
pub mod config{
|
||||
pub const FEATURE_HAS_STRUCT_HEADER: bool = cfg!(feature = "rmc_struct_header");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ use std::fs::File;
|
|||
use std::net::{Ipv4Addr};
|
||||
use std::sync::Once;
|
||||
use std::{env, fs};
|
||||
use std::hint::black_box;
|
||||
use criterion::{criterion_group, criterion_main, Criterion};
|
||||
|
||||
mod prudp;
|
||||
pub mod rmc;
|
||||
|
|
@ -35,360 +37,111 @@ pub mod reggie;
|
|||
pub mod util;
|
||||
pub mod common;
|
||||
|
||||
|
||||
|
||||
static KERBEROS_SERVER_PASSWORD: Lazy<String> = Lazy::new(|| {
|
||||
env::var("AUTH_SERVER_PASSWORD")
|
||||
.ok()
|
||||
.unwrap_or("password".to_owned())
|
||||
});
|
||||
|
||||
static AUTH_SERVER_ACCOUNT: Lazy<Account> =
|
||||
Lazy::new(|| Account::new(1, "Quazal Authentication", &KERBEROS_SERVER_PASSWORD));
|
||||
static SECURE_SERVER_ACCOUNT: Lazy<Account> =
|
||||
Lazy::new(|| Account::new(2, "Quazal Rendez-Vous", &KERBEROS_SERVER_PASSWORD));
|
||||
|
||||
static AUTH_SERVER_PORT: Lazy<u16> = Lazy::new(|| {
|
||||
env::var("AUTH_SERVER_PORT")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(10000)
|
||||
});
|
||||
static SECURE_SERVER_PORT: Lazy<u16> = Lazy::new(|| {
|
||||
env::var("SECURE_SERVER_PORT")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(10001)
|
||||
});
|
||||
|
||||
static OWN_IP_PRIVATE: Lazy<Ipv4Addr> = Lazy::new(|| {
|
||||
env::var("SERVER_IP")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.expect("no private ip specified")
|
||||
});
|
||||
|
||||
static OWN_IP_PUBLIC: Lazy<String> =
|
||||
Lazy::new(|| env::var("SERVER_IP_PUBLIC").unwrap_or(OWN_IP_PRIVATE.to_string()));
|
||||
|
||||
static SECURE_STATION_URL: Lazy<String> = Lazy::new(|| {
|
||||
format!(
|
||||
"prudps:/PID=2;sid=1;stream=10;type=2;address={};port={};CID=1",
|
||||
*OWN_IP_PUBLIC, *SECURE_SERVER_PORT
|
||||
)
|
||||
});
|
||||
|
||||
static FORCE_EXIT: Once = Once::new();
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
CombinedLogger::init(vec![
|
||||
TermLogger::new(
|
||||
LevelFilter::Info,
|
||||
Config::default(),
|
||||
TerminalMode::Mixed,
|
||||
ColorChoice::Auto,
|
||||
),
|
||||
WriteLogger::new(LevelFilter::max(), Config::default(), {
|
||||
fs::create_dir_all("log").unwrap();
|
||||
let date = Local::now().to_rfc3339_opts(SecondsFormat::Secs, false);
|
||||
// this fixes windows being windows
|
||||
let date = date.replace(":", "-");
|
||||
let filename = format!("{}.log", date);
|
||||
if cfg!(windows) {
|
||||
File::create(format!("log\\{}", filename)).unwrap()
|
||||
} else {
|
||||
File::create(format!("log/{}", filename)).unwrap()
|
||||
}
|
||||
}),
|
||||
])
|
||||
.unwrap();
|
||||
|
||||
ctrlc::set_handler(||{
|
||||
FORCE_EXIT.call_once_force(|_|{
|
||||
println!("attempting exit");
|
||||
});
|
||||
}).unwrap();
|
||||
|
||||
dotenv::dotenv().ok();
|
||||
|
||||
//start_servers().await;
|
||||
}
|
||||
/*
|
||||
|
||||
struct AuthServer{
|
||||
router: Arc<Router>,
|
||||
join_handle: JoinHandle<()>,
|
||||
socket: Socket
|
||||
pub mod config{
|
||||
pub const FEATURE_HAS_STRUCT_HEADER: bool = cfg!(feature = "rmc_struct_header");
|
||||
}
|
||||
|
||||
async fn start_auth_server() -> AuthServer{
|
||||
info!("starting auth server on {}:{}", *OWN_IP_PRIVATE, *AUTH_SERVER_PORT);
|
||||
use std::io::Cursor;
|
||||
use std::ops::Deref;
|
||||
use rnex_core::kerberos::KerberosDateTime;
|
||||
use rnex_core::rmc::structures::matchmake::{AutoMatchmakeParam, Gathering, MatchmakeParam, MatchmakeSession, MatchmakeSessionSearchCriteria};
|
||||
use rnex_core::rmc::structures::RmcSerialize;
|
||||
use rnex_core::rmc::structures::variant::Variant;
|
||||
|
||||
let (router, join_handle) =
|
||||
Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT)).await
|
||||
.expect("unable to startauth server");
|
||||
|
||||
info!("setting up endpoints");
|
||||
|
||||
// dont assign it to the name _ as that will make it drop right here and now
|
||||
|
||||
let auth_protocol_config = AuthProtocolConfig{
|
||||
secure_server_account: &SECURE_SERVER_ACCOUNT,
|
||||
build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0",
|
||||
station_url: &SECURE_STATION_URL
|
||||
};
|
||||
|
||||
let rmcserver = RMCProtocolServer::new(Box::new([
|
||||
Box::new(auth::bound_protocol(auth_protocol_config))
|
||||
]));
|
||||
|
||||
let socket =
|
||||
Socket::new(
|
||||
router.clone(),
|
||||
VirtualPort::new(1,10),
|
||||
"6f599f81",
|
||||
Box::new(|_, count|{
|
||||
Box::pin(
|
||||
async move {
|
||||
|
||||
|
||||
let encryption_pairs = Vec::from_iter((0..=count).map(|_v| {
|
||||
let rc4: Rc4<U5> = Rc4::new_from_slice( "CD&ML".as_bytes()).unwrap();
|
||||
let cypher = Box::new(rc4);
|
||||
let server_cypher: Box<dyn StreamCipher + Send> = cypher;
|
||||
|
||||
let rc4: Rc4<U5> = Rc4::new_from_slice( "CD&ML".as_bytes()).unwrap();
|
||||
let cypher = Box::new(rc4);
|
||||
let client_cypher: Box<dyn StreamCipher + Send> = cypher;
|
||||
|
||||
EncryptionPair{
|
||||
recv: client_cypher,
|
||||
send: server_cypher
|
||||
}
|
||||
}));
|
||||
|
||||
Some((Vec::new(), encryption_pairs, None))
|
||||
}
|
||||
)
|
||||
}),
|
||||
Box::new(move |packet, socket, connection|{
|
||||
let rmcserver = rmcserver.clone();
|
||||
Box::pin(async move { rmcserver.process_message(packet, socket, connection).await; })
|
||||
})
|
||||
).await.expect("unable to create socket");
|
||||
|
||||
AuthServer{
|
||||
join_handle,
|
||||
router,
|
||||
socket,
|
||||
static DUMMY: Lazy<AutoMatchmakeParam> = Lazy::new(|| AutoMatchmakeParam{
|
||||
additional_participants: vec![1,2,3,4],
|
||||
auto_matchmake_option: 10,
|
||||
gid_for_participation_check: 9,
|
||||
join_message: "hi".to_string(),
|
||||
participation_count: 32,
|
||||
target_gids: vec![45,2,51,1,1,1,1],
|
||||
search_criteria: vec![MatchmakeSessionSearchCriteria{
|
||||
attribs: vec!["hi".to_string(), "ig".to_string(), "gotta put data here".to_string()],
|
||||
exclude_locked: true,
|
||||
exclude_non_host_pid: false,
|
||||
exclude_system_password_set: true,
|
||||
exclude_user_password_set: false,
|
||||
game_mode: "some gamemode".to_string(),
|
||||
matchmake_param: MatchmakeParam{
|
||||
params: vec![
|
||||
("SR".to_string(), Variant::Bool(true)),
|
||||
("SR2".to_string(), Variant::Double(1.0)),
|
||||
("SR3".to_string(), Variant::SInt64(42)),
|
||||
("SR4".to_string(), Variant::String("test".to_string()))
|
||||
]
|
||||
},
|
||||
matchmake_system_type: "some type".to_string(),
|
||||
maximum_participants: "???".to_string(),
|
||||
minimum_participants: "-99".to_string(),
|
||||
refer_gid: 123,
|
||||
selection_method: 9999999,
|
||||
vacant_only: true,
|
||||
vacant_participants: 1000
|
||||
}],
|
||||
matchmake_session: MatchmakeSession{
|
||||
refer_gid: 10,
|
||||
matchmake_system_type: 139,
|
||||
matchmake_param: MatchmakeParam{
|
||||
params: vec![
|
||||
("QSR".to_string(), Variant::Bool(false)),
|
||||
("SRQ2".to_string(), Variant::Double(1.1)),
|
||||
("SQR3".to_string(), Variant::SInt64(422)),
|
||||
("SDR4".to_string(), Variant::String("tetst".to_string()))
|
||||
]
|
||||
},
|
||||
participation_count: 99,
|
||||
application_buffer: vec![1,2,3,4,5,6,7,8,9],
|
||||
attributes: vec![10,20,99,100000],
|
||||
datetime: KerberosDateTime::now(),
|
||||
gamemode: 111,
|
||||
open_participation: false,
|
||||
option0: 100,
|
||||
progress_score: 1,
|
||||
system_password_enabled: false,
|
||||
user_password: "aaa".to_string(),
|
||||
session_key: vec![91,123,5,2,1,2,4,124,4],
|
||||
user_password_enabled: false,
|
||||
gathering: Gathering{
|
||||
minimum_participants: 1,
|
||||
maximum_participants: 12,
|
||||
description: "aaargh".to_string(),
|
||||
flags: 100,
|
||||
host_pid: 999999919,
|
||||
owner_pid: 138830,
|
||||
participant_policy: 1,
|
||||
policy_argument: 99837,
|
||||
self_gid: 129,
|
||||
state: 1389488
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
static DUMMY_SER: Lazy<Vec<u8>> = Lazy::new(|| serialize_to_vec(DUMMY.deref()));
|
||||
|
||||
fn serialize_to_vec(r: &impl RmcSerialize) -> Vec<u8>{
|
||||
let mut vec = r.to_data();
|
||||
|
||||
vec.unwrap()
|
||||
}
|
||||
|
||||
struct SecureServer{
|
||||
router: Arc<Router>,
|
||||
join_handle: JoinHandle<()>,
|
||||
socket: Socket
|
||||
fn read_struct<T: RmcSerialize>(r: &[u8]) -> T{
|
||||
T::deserialize(&mut Cursor::new(r)).unwrap()
|
||||
}
|
||||
fn matchmake_with_param(c: &mut Criterion) {
|
||||
let raw = DUMMY.deref();
|
||||
let ser = DUMMY_SER.deref().as_slice();
|
||||
c.bench_function("mmparam: ser", |b| b.iter(move || serialize_to_vec(black_box(raw))));
|
||||
c.bench_function("mmparam: de", |b| b.iter(move || read_struct::<AutoMatchmakeParam>(black_box(ser))));
|
||||
}
|
||||
|
||||
async fn start_secure_server() -> SecureServer{
|
||||
info!("starting secure server on {}:{}", *OWN_IP_PRIVATE, *SECURE_SERVER_PORT);
|
||||
criterion_group!(benches, matchmake_with_param);
|
||||
//criterion_main!(benches);
|
||||
|
||||
let (router, join_handle) =
|
||||
Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT)).await
|
||||
.expect("unable to startauth server");
|
||||
|
||||
info!("setting up endpoints");
|
||||
|
||||
let matchmake_data = Arc::new(RwLock::new(
|
||||
MatchmakeData{
|
||||
matchmake_sessions: BTreeMap::new()
|
||||
}
|
||||
));
|
||||
|
||||
let rmcserver = RMCProtocolServer::new(Box::new([
|
||||
Box::new(block_if_maintenance),
|
||||
Box::new(protocols::secure::bound_protocol()),
|
||||
Box::new(protocols::matchmake::bound_protocol(matchmake_data.clone())),
|
||||
Box::new(protocols::matchmake_extension::bound_protocol(matchmake_data)),
|
||||
Box::new(protocols::nat_traversal::bound_protocol())
|
||||
]));
|
||||
|
||||
let socket =
|
||||
Socket::new(
|
||||
router.clone(),
|
||||
VirtualPort::new(1,10),
|
||||
"6f599f81",
|
||||
Box::new(|p, count|{
|
||||
Box::pin(
|
||||
async move {
|
||||
let (session_key, pid, check_value) = read_secure_connection_data(&p.payload, &SECURE_SERVER_ACCOUNT)?;
|
||||
|
||||
let check_value_response = check_value + 1;
|
||||
|
||||
let data = bytemuck::bytes_of(&check_value_response);
|
||||
|
||||
let mut response = Vec::new();
|
||||
|
||||
data.serialize(&mut response).ok()?;
|
||||
|
||||
let encryption_pairs = generate_secure_encryption_pairs(session_key, count);
|
||||
|
||||
Some((response, encryption_pairs, Some(
|
||||
ActiveSecureConnectionData{
|
||||
pid,
|
||||
session_key
|
||||
}
|
||||
)))
|
||||
}
|
||||
)
|
||||
}),
|
||||
Box::new(move |packet, socket, connection|{
|
||||
let rmcserver = rmcserver.clone();
|
||||
Box::pin(async move { rmcserver.process_message(packet, socket, connection).await; })
|
||||
})
|
||||
).await.expect("unable to create socket");
|
||||
|
||||
SecureServer{
|
||||
join_handle,
|
||||
router,
|
||||
socket,
|
||||
fn main(){
|
||||
for _ in 0..10000000 {
|
||||
let v = serialize_to_vec(black_box(DUMMY.deref()));
|
||||
let u = read_struct::<AutoMatchmakeParam>(black_box(DUMMY_SER.deref().as_slice()));
|
||||
black_box(v);
|
||||
black_box(u);
|
||||
}
|
||||
}*/
|
||||
/*
|
||||
async fn start_auth() -> JoinHandle<()> {
|
||||
tokio::spawn(async {
|
||||
let (router_secure, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT))
|
||||
.await
|
||||
.expect("unable to start router");
|
||||
|
||||
let mut socket_secure = router_secure
|
||||
.add_socket(VirtualPort::new(1, 10), Unsecure(
|
||||
"6f599f81"
|
||||
))
|
||||
.await
|
||||
.expect("unable to add socket");
|
||||
|
||||
// let conn = socket_secure.connect(auth_sockaddr).await.unwrap();
|
||||
|
||||
while !FORCE_EXIT.is_completed() {
|
||||
let Some(conn) = socket_secure.accept().await else {
|
||||
error!("server crashed");
|
||||
return;
|
||||
};
|
||||
|
||||
info!("new connected user!");
|
||||
|
||||
let _ = new_rmc_gateway_connection(conn, |_| {
|
||||
Arc::new(AuthHandler {
|
||||
destination_server_acct: &SECURE_SERVER_ACCOUNT,
|
||||
build_name: "branch:origin/project/wup-agmj build:3_8_15_2004_0",
|
||||
station_url: &SECURE_STATION_URL,
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async fn start_secure() -> JoinHandle<()> {
|
||||
tokio::spawn(async {
|
||||
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;
|
||||
|
||||
let web_server = web::start_web(mmm.clone()).await;
|
||||
|
||||
let (router_secure, _) =
|
||||
Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT))
|
||||
.await
|
||||
.expect("unable to start router");
|
||||
|
||||
let mut socket_secure = router_secure
|
||||
.add_socket(
|
||||
VirtualPort::new(1, 10),
|
||||
Secure(
|
||||
"6f599f81",
|
||||
&SECURE_SERVER_ACCOUNT
|
||||
),
|
||||
)
|
||||
.await
|
||||
.expect("unable to add socket");
|
||||
|
||||
// let conn = socket_secure.connect(auth_sockaddr).await.unwrap();
|
||||
|
||||
while !FORCE_EXIT.is_completed() {
|
||||
let Some(conn) = socket_secure.accept().await else {
|
||||
error!("server crashed");
|
||||
return;
|
||||
};
|
||||
|
||||
info!("new connected user on secure :D!");
|
||||
|
||||
let ip = conn.socket_addr;
|
||||
let pid = conn.user_id;
|
||||
|
||||
let _ = new_rmc_gateway_connection(conn, |r| {
|
||||
Arc::new_cyclic(|w| User {
|
||||
ip,
|
||||
pid,
|
||||
this: w.clone(),
|
||||
remote: RemoteConsole::new(r),
|
||||
station_url: Default::default(),
|
||||
matchmake_manager: mmm.clone()
|
||||
})
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async fn start_test() {
|
||||
let addr = SocketAddrV4::new(*OWN_IP_PRIVATE, *SECURE_SERVER_PORT);
|
||||
|
||||
let virt_addr = VirtualPort::new(1, 10);
|
||||
let prudp_addr = PRUDPSockAddr::new(addr, virt_addr);
|
||||
|
||||
let (router_test, _) = Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, 26969))
|
||||
.await
|
||||
.expect("unable to start router");
|
||||
|
||||
let mut socket_secure = router_test
|
||||
.add_socket(VirtualPort::new(1, 10), Unsecure("6f599f81"))
|
||||
.await
|
||||
.expect("unable to add socket");
|
||||
|
||||
let conn = socket_secure.connect(prudp_addr).await.unwrap();
|
||||
|
||||
let remote = new_rmc_gateway_connection(conn, |r| {
|
||||
Arc::new(OnlyRemote::<RemoteUserProtocol>::new(r))
|
||||
});
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
let urls = vec!["prudp:/address=192.168.178.45;port=60146;Pl=2;natf=0;natm=0;pmp=0;sid=15;upnp=0".to_owned()];
|
||||
}
|
||||
|
||||
async fn start_servers() {
|
||||
#[cfg(feature = "auth")]
|
||||
let auth_server = start_auth().await;
|
||||
#[cfg(feature = "secure")]
|
||||
let secure_server = start_secure().await;
|
||||
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
|
||||
//start_test().await;
|
||||
|
||||
|
||||
|
||||
#[cfg(feature = "auth")]
|
||||
auth_server.await.expect("auth server crashed");
|
||||
#[cfg(feature = "secure")]
|
||||
secure_server.await.expect("auth server crashed");
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
@ -162,6 +162,8 @@ mod test {
|
|||
use rnex_core::rmc::structures::RmcSerialize;
|
||||
use rnex_core::rmc::response::RMCResponse;
|
||||
use std::io::Cursor;
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use std::io::Read;
|
|||
use crate::prudp::station_url::Type::{PRUDP, PRUDPS, UDP};
|
||||
use crate::prudp::station_url::UrlOptions::{Address, ConnectionID, NatFiltering, NatMapping, NatType, Platform, PMP, Port, PrincipalID, RVConnectionID, StreamID, StreamType, UPNP, PID};
|
||||
use crate::rmc::structures::Error::StationUrlInvalid;
|
||||
use crate::rmc::structures::helpers::DummyFormatWriter;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Type{
|
||||
|
|
@ -135,59 +136,66 @@ impl TryFrom<&str> for StationUrl{
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<String> for &'a StationUrl{
|
||||
fn into(self) -> String {
|
||||
let mut url = match self.url_type{
|
||||
impl Display for StationUrl{
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let url_type_str = match self.url_type{
|
||||
UDP => "udp:/",
|
||||
PRUDP => "prudp:/",
|
||||
PRUDPS => "prudps:/"
|
||||
}.to_owned();
|
||||
};
|
||||
write!(f, "{}",url_type_str)?;
|
||||
|
||||
for option in &self.options{
|
||||
match option{
|
||||
Address(v) => write!(url, "address={}", v).expect("failed to write"),
|
||||
Port(v) => write!(url, "port={}", v).expect("failed to write"),
|
||||
StreamType(v) => write!(url, "stream={}", v).expect("failed to write"),
|
||||
StreamID(v) => write!(url, "sid={}", v).expect("failed to write"),
|
||||
ConnectionID(v) => write!(url, "CID={}", v).expect("failed to write"),
|
||||
PrincipalID(v) => write!(url, "PID={}", v).expect("failed to write"),
|
||||
NatType(v) => write!(url, "type={}", v).expect("failed to write"),
|
||||
NatMapping(v) => write!(url, "natm={}", v).expect("failed to write"),
|
||||
NatFiltering(v) => write!(url, "natf={}", v).expect("failed to write"),
|
||||
UPNP(v) => write!(url, "upnp={}", v).expect("failed to write"),
|
||||
RVConnectionID(v) => write!(url, "RVCID={}", v).expect("failed to write"),
|
||||
Platform(v) => write!(url, "pl={}", v).expect("failed to write"),
|
||||
PMP(v) => write!(url, "pmp={}", v).expect("failed to write"),
|
||||
PID(v) => write!(url, "PID={}", v).expect("failed to write"),
|
||||
Address(v) => write!(f, "address={}", v)?,
|
||||
Port(v) => write!(f, "port={}", v)?,
|
||||
StreamType(v) => write!(f, "stream={}", v)?,
|
||||
StreamID(v) => write!(f, "sid={}", v)?,
|
||||
ConnectionID(v) => write!(f, "CID={}", v)?,
|
||||
PrincipalID(v) => write!(f, "PID={}", v)?,
|
||||
NatType(v) => write!(f, "type={}", v)?,
|
||||
NatMapping(v) => write!(f, "natm={}", v)?,
|
||||
NatFiltering(v) => write!(f, "natf={}", v)?,
|
||||
UPNP(v) => write!(f, "upnp={}", v)?,
|
||||
RVConnectionID(v) => write!(f, "RVCID={}", v)?,
|
||||
Platform(v) => write!(f, "pl={}", v)?,
|
||||
PMP(v) => write!(f, "pmp={}", v)?,
|
||||
PID(v) => write!(f, "PID={}", v)?,
|
||||
}
|
||||
write!(url, ";").expect("failed to write");
|
||||
write!(f, ";")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Into<String> for &'a StationUrl{
|
||||
fn into(self) -> String {
|
||||
let mut url = self.to_string();
|
||||
|
||||
|
||||
url[0..url.len()-1].into()
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for StationUrl{
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let str: String = self.into();
|
||||
|
||||
write!(f, "{}", str)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
impl RmcSerialize for StationUrl{
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
let str = String::deserialize(reader)?;
|
||||
|
||||
Self::try_from(str.as_str()).map_err(|_| StationUrlInvalid)
|
||||
}
|
||||
fn serialize(&self, writer: &mut dyn std::io::Write) -> crate::rmc::structures::Result<()> {
|
||||
fn serialize(&self, writer: &mut impl std::io::Write) -> crate::rmc::structures::Result<()> {
|
||||
let str: String = self.into();
|
||||
|
||||
str.serialize(writer)
|
||||
}
|
||||
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
let mut dummy = DummyFormatWriter::new();
|
||||
|
||||
write!(&mut dummy, "{}", self)?;
|
||||
|
||||
Ok(dummy.serialize_str_len())
|
||||
}
|
||||
}
|
||||
|
||||
impl Debug for StationUrl{
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ pub struct Any{
|
|||
}
|
||||
|
||||
impl RmcSerialize for Any{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||
self.name.serialize(writer)?;
|
||||
|
||||
let u32_len = self.data.len() as u32;
|
||||
|
|
@ -21,7 +21,7 @@ impl RmcSerialize for Any{
|
|||
|
||||
Ok(())
|
||||
}
|
||||
fn deserialize(mut reader: &mut dyn Read) -> Result<Self> {
|
||||
fn deserialize(mut reader: &mut impl Read) -> Result<Self> {
|
||||
let name = String::deserialize(reader)?;
|
||||
|
||||
// also length ?
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use crate::rmc::structures::RmcSerialize;
|
|||
|
||||
|
||||
impl<'a> RmcSerialize for &'a [u8]{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
let u32_size = self.len() as u32;
|
||||
writer.write(bytemuck::bytes_of(&u32_size))?;
|
||||
writer.write(self)?;
|
||||
|
|
@ -13,17 +13,25 @@ impl<'a> RmcSerialize for &'a [u8]{
|
|||
}
|
||||
|
||||
/// DO NOT USE (also maybe split off the serialize and deserialize functions at some point)
|
||||
fn deserialize(_reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
fn deserialize(_reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
panic!("cannot deserialize to a u8 slice reference (use this ONLY for writing)")
|
||||
}
|
||||
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(4 + self.len() as u32)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for Box<[u8]>{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
(&self[..]).serialize(writer)
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Vec::deserialize(reader).map(|v| v.into_boxed_slice())
|
||||
}
|
||||
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
(&self[..]).serialize_write_size()
|
||||
}
|
||||
}
|
||||
48
rnex-core/src/rmc/structures/helpers.rs
Normal file
48
rnex-core/src/rmc/structures/helpers.rs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
use std::{fmt, io};
|
||||
|
||||
pub struct DummyFormatWriter(u32);
|
||||
|
||||
impl fmt::Write for DummyFormatWriter{
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
self.0 += s.as_bytes().len() as u32;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyFormatWriter{
|
||||
pub const fn new() -> Self{ Self(0) }
|
||||
pub const fn serialize_str_len(&self) -> u32 {
|
||||
2 + self.0 + 1
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DummyWriter(u32);
|
||||
|
||||
impl io::Write for DummyWriter{
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0 += buf.len() as u32;
|
||||
Ok(buf.len())
|
||||
}
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
self.0 += buf.len() as u32;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl DummyWriter{
|
||||
pub const fn new() -> Self{ Self(0) }
|
||||
pub const fn get_total_len(&self) -> u32{
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn len_of_write(f: impl FnOnce(&mut DummyWriter) -> anyhow::Result<()>) -> u32{
|
||||
let mut dummy = DummyWriter::new();
|
||||
f(&mut dummy).ok();
|
||||
dummy.get_total_len()
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ use crate::rmc::structures::RmcSerialize;
|
|||
// this is also for implementing `Buffer` this is tecnically not the same as its handled internaly
|
||||
// probably but as it has the same mapping it doesn't matter and simplifies things
|
||||
impl<T: RmcSerialize> RmcSerialize for Vec<T>{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
let u32_len = self.len() as u32;
|
||||
|
||||
writer.write_all(bytes_of(&u32_len))?;
|
||||
|
|
@ -20,21 +20,27 @@ impl<T: RmcSerialize> RmcSerialize for Vec<T>{
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
let len: u32 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
let mut vec = Vec::with_capacity(len as usize);
|
||||
//let mut vec = Vec::with_capacity(len as usize);
|
||||
|
||||
for _ in 0..len{
|
||||
vec.push(T::deserialize(reader)?);
|
||||
}
|
||||
let vec = (0..len).map(|_| T::deserialize(reader)).collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
Ok(vec)
|
||||
}
|
||||
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
let mut val = 0u32;
|
||||
for i in self{
|
||||
val += i.serialize_write_size()?;
|
||||
}
|
||||
Ok(4 + val)
|
||||
}
|
||||
}
|
||||
|
||||
impl<const LEN: usize, T: RmcSerialize> RmcSerialize for [T; LEN]{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
for i in 0..LEN{
|
||||
self[i].serialize(writer)?;
|
||||
}
|
||||
|
|
@ -42,7 +48,7 @@ impl<const LEN: usize, T: RmcSerialize> RmcSerialize for [T; LEN]{
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
let mut arr = [const { MaybeUninit::<T>::uninit() }; LEN];
|
||||
|
||||
for i in 0..LEN{
|
||||
|
|
@ -55,4 +61,12 @@ impl<const LEN: usize, T: RmcSerialize> RmcSerialize for [T; LEN]{
|
|||
|
||||
Ok(arr)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
let mut val = 0u32;
|
||||
for i in self{
|
||||
val += i.serialize_write_size()?;
|
||||
}
|
||||
Ok(val)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use std::io;
|
||||
use std::{fmt, io};
|
||||
use std::io::{Read, Write};
|
||||
use std::string::FromUtf8Error;
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::rmc::structures::helpers::DummyWriter;
|
||||
//ideas for the future: make a proc macro library which allows generation of struct reads
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
|
@ -16,7 +16,9 @@ pub enum Error{
|
|||
#[error("version mismatch: {0}")]
|
||||
VersionMismatch(u8),
|
||||
#[error("an error occurred reading the station url")]
|
||||
StationUrlInvalid
|
||||
StationUrlInvalid,
|
||||
#[error("error formatting text: {0}")]
|
||||
FormatError(#[from] fmt::Error)
|
||||
}
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
|
@ -33,28 +35,43 @@ pub mod primitives;
|
|||
pub mod matchmake;
|
||||
pub mod variant;
|
||||
pub mod ranking;
|
||||
mod networking;
|
||||
pub mod networking;
|
||||
pub mod helpers;
|
||||
|
||||
pub trait RmcSerialize{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()>;
|
||||
fn deserialize(reader: &mut dyn Read) -> Result<Self> where Self: Sized;
|
||||
fn serialize(&self, writer: &mut impl Write) -> Result<()>;
|
||||
fn serialize_write_size(&self) -> Result<u32>{
|
||||
let mut dummy = DummyWriter::new();
|
||||
|
||||
fn to_data(&self) -> Vec<u8>{
|
||||
let mut data = Vec::new();
|
||||
self.serialize(&mut dummy)?;
|
||||
|
||||
self.serialize(&mut data).expect("out of memory or something");
|
||||
Ok(dummy.get_total_len())
|
||||
}
|
||||
fn deserialize(reader: &mut impl Read) -> Result<Self> where Self: Sized;
|
||||
|
||||
data
|
||||
fn to_data(&self) -> Result<Vec<u8>>{
|
||||
let mut data = Vec::with_capacity(
|
||||
self.serialize_write_size()? as usize
|
||||
);
|
||||
|
||||
self.serialize(&mut data)?;
|
||||
|
||||
debug_assert_eq!(self.serialize_write_size().unwrap(), data.len() as u32);
|
||||
|
||||
Ok(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for (){
|
||||
fn serialize(&self, _writer: &mut dyn Write) -> Result<()> {
|
||||
fn serialize(&self, _writer: &mut impl Write) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
fn deserialize(_reader: &mut dyn Read) -> Result<Self> {
|
||||
fn deserialize(_reader: &mut impl Read) -> Result<Self> {
|
||||
Ok(())
|
||||
}
|
||||
fn serialize_write_size(&self) -> Result<u32> {
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -4,30 +4,36 @@ use rnex_core::prudp::virtual_port::VirtualPort;
|
|||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
impl RmcSerialize for SocketAddrV4{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
self.ip().to_bits().serialize(writer)?;
|
||||
self.port().serialize(writer)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
let ip = u32::deserialize(reader)?;
|
||||
let port = u16::deserialize(reader)?;
|
||||
|
||||
Ok(SocketAddrV4::new(Ipv4Addr::from_bits(ip), port))
|
||||
}
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(6)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl RmcSerialize for VirtualPort{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
self.0.serialize(writer)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(Self(u8::deserialize(reader)?))
|
||||
}
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(1)
|
||||
}
|
||||
}
|
||||
|
|
@ -4,97 +4,146 @@ use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
|||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
impl RmcSerialize for u8{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(writer.write_all(bytes_of(self))?)
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(1)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for i8{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(writer.write_all(bytes_of(self))?)
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(1)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for u16{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(writer.write_all(bytes_of(self))?)
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(2)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for i16{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(writer.write_all(bytes_of(self))?)
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(2)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for u32{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(writer.write_all(bytes_of(self))?)
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(4)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for i32{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(writer.write_all(bytes_of(self))?)
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(4)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for u64{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(writer.write_all(bytes_of(self))?)
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(8)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for i64{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(writer.write_all(bytes_of(self))?)
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(8)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for f64{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
Ok(writer.write_all(bytes_of(self))?)
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(mut reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(8)
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for bool{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
match self{
|
||||
true => writer.write_all(&[1])?,
|
||||
false => writer.write_all(&[0])?,
|
||||
|
|
@ -102,54 +151,77 @@ impl RmcSerialize for bool{
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
Ok(u8::deserialize(reader)? != 0)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<T: RmcSerialize, U: RmcSerialize> RmcSerialize for (T, U){
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
self.0.serialize(writer)?;
|
||||
self.1.serialize(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
let first = T::deserialize(reader)?;
|
||||
let second = U::deserialize(reader)?;
|
||||
|
||||
Ok((first, second))
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
Ok(
|
||||
self.0.serialize_write_size()? +
|
||||
self.1.serialize_write_size()?
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize> RmcSerialize for (T, U, V){
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[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)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[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)?;
|
||||
|
||||
Ok((first, second, third))
|
||||
}
|
||||
#[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()?
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize> RmcSerialize for (T, U, V, W){
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[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)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[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)?;
|
||||
|
|
@ -157,10 +229,20 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize> RmcSeri
|
|||
|
||||
Ok((first, second, third, fourth))
|
||||
}
|
||||
#[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()?
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcSerialize> RmcSerialize for (T, U, V, W, X){
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[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)?;
|
||||
|
|
@ -170,7 +252,8 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[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)?;
|
||||
|
|
@ -179,10 +262,21 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
|||
|
||||
Ok((first, second, third, fourth, fifth))
|
||||
}
|
||||
#[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.2.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){
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[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)?;
|
||||
|
|
@ -193,7 +287,8 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[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)?;
|
||||
|
|
@ -203,10 +298,22 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
|||
|
||||
Ok((first, second, third, fourth, fifth, sixth))
|
||||
}
|
||||
#[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()?
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcSerialize, Y: RmcSerialize, Z: RmcSerialize> RmcSerialize for (T, U, V, W, X, Y, Z){
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[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)?;
|
||||
|
|
@ -217,8 +324,8 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[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)?;
|
||||
|
|
@ -229,13 +336,31 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
|
|||
|
||||
Ok((first, second, third, fourth, fifth, sixth, seventh))
|
||||
}
|
||||
#[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()?
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: RmcSerialize> RmcSerialize for Box<T>{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
#[inline(always)]
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
self.as_ref().serialize(writer)
|
||||
}
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
#[inline(always)]
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
T::deserialize(reader).map(Box::new)
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
|
||||
T::serialize_write_size(self.as_ref())
|
||||
}
|
||||
}
|
||||
|
|
@ -8,7 +8,7 @@ use crate::rmc::structures::{Result, RmcSerialize};
|
|||
pub struct QBuffer(pub Vec<u8>);
|
||||
|
||||
impl RmcSerialize for QBuffer{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||
let len_u16 = self.0.len() as u16;
|
||||
|
||||
writer.write(bytes_of(&len_u16))?;
|
||||
|
|
@ -17,7 +17,7 @@ impl RmcSerialize for QBuffer{
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> Result<Self> {
|
||||
fn deserialize(mut reader: &mut impl Read) -> Result<Self> {
|
||||
let size: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
let mut vec = vec![0; size as usize];
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ impl QResult{
|
|||
}
|
||||
|
||||
impl RmcSerialize for QResult{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||
writer.write(bytes_of(self))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(mut reader: &mut dyn Read) -> Result<Self> {
|
||||
fn deserialize(mut reader: &mut impl Read) -> Result<Self> {
|
||||
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,12 @@
|
|||
use std::io::{Cursor, Read, Write};
|
||||
use std::any::Any;
|
||||
use std::cmp::max;
|
||||
use std::fmt::Arguments;
|
||||
use std::io;
|
||||
use std::io::{Cursor, ErrorKind, IoSlice, Read, Write};
|
||||
use std::ops::Sub;
|
||||
use bytemuck::bytes_of;
|
||||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::rmc::structures;
|
||||
use crate::rmc::structures::Error::VersionMismatch;
|
||||
use crate::rmc::structures::Result;
|
||||
|
||||
|
|
@ -10,35 +16,97 @@ struct StructureHeader{
|
|||
length: u32
|
||||
}
|
||||
|
||||
pub fn write_struct(writer: &mut dyn Write, version: u8, pred: impl FnOnce(&mut Vec<u8>) -> Result<()> ) -> Result<()> {
|
||||
#[cfg(feature = "rmc_struct_header")]
|
||||
pub const HEADER_SIZE: u32 = 0;
|
||||
#[cfg(not(feature = "rmc_struct_header"))]
|
||||
pub const HEADER_SIZE: u32 = 5;
|
||||
|
||||
pub struct OnlyWriteVec<'a>(&'a mut Vec<u8>);
|
||||
|
||||
impl Write for OnlyWriteVec<'_> {
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
self.0.flush()
|
||||
}
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
||||
self.0.write_all(buf)
|
||||
}
|
||||
fn write_fmt(&mut self, args: Arguments<'_>) -> io::Result<()> {
|
||||
self.0.write_fmt(args)
|
||||
}
|
||||
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
|
||||
self.0.write_vectored(bufs)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rmc_struct_header")]
|
||||
pub fn write_struct<T: Write>(writer: &mut T, version: u8, inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> {
|
||||
writer.write_all(&[version])?;
|
||||
|
||||
let mut scratch_space: Vec<u8> = Vec::new();
|
||||
writer.write_all(bytes_of(&inner_size))?;
|
||||
|
||||
(pred)(&mut scratch_space)?;
|
||||
|
||||
let u32_size = scratch_space.len() as u32;
|
||||
|
||||
writer.write_all(bytes_of(&u32_size))?;
|
||||
writer.write_all(&scratch_space)?;
|
||||
(pred)(writer)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn read_struct<T: Sized>(mut reader: &mut dyn Read, version: u8, pred: impl FnOnce(&mut Cursor<Vec<u8>>) -> Result<T>) -> Result<T> {
|
||||
|
||||
|
||||
#[cfg(not(feature = "rmc_struct_header"))]
|
||||
pub fn write_struct<T: Write>(writer: &mut T, version: u8, _inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> {
|
||||
pred(writer)
|
||||
}
|
||||
|
||||
|
||||
pub struct SubRead<'a, T: Read>{
|
||||
left_to_read: usize,
|
||||
origin: &'a mut T
|
||||
}
|
||||
|
||||
impl<'a, T: Read> SubRead<'a, T>{
|
||||
pub const fn new(origin: &'a mut T, left_to_read: usize) -> Self{
|
||||
Self{
|
||||
left_to_read,
|
||||
origin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Read> Read for SubRead<'_, T>{
|
||||
#[inline(always)]
|
||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let max_read = max(self.left_to_read, buf.len());
|
||||
let read = self.origin.read(&mut buf[..max_read])?;
|
||||
self.left_to_read -= read;
|
||||
Ok(read)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
|
||||
if buf.len() > self.left_to_read{
|
||||
return Err(io::Error::new(ErrorKind::UnexpectedEof, "Would run over end of SubRead"));
|
||||
}
|
||||
self.left_to_read -= buf.len();
|
||||
self.origin.read_exact(buf)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rmc_struct_header")]
|
||||
pub fn read_struct<T: Sized, R: Read>(mut reader: &mut R, version: u8, pred: impl FnOnce(&mut SubRead<R>) -> Result<T>) -> Result<T> {
|
||||
let ver: u8 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
if ver != version{
|
||||
if ver != version {
|
||||
return Err(VersionMismatch(ver));
|
||||
}
|
||||
|
||||
let size: u32 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
|
||||
let mut vec = vec![0u8; size as usize];
|
||||
Ok(pred(&mut SubRead::new(reader, size as usize))?)
|
||||
}
|
||||
|
||||
reader.read_exact(&mut vec)?;
|
||||
|
||||
let mut cursor = Cursor::new(vec);
|
||||
|
||||
Ok(pred(&mut cursor)?)
|
||||
}
|
||||
#[cfg(not(feature = "rmc_struct_header"))]
|
||||
pub fn read_struct<T: Sized, R: Read>(mut reader: &mut R, version: u8, pred: impl FnOnce(&mut R) -> Result<T>) -> Result<T> {
|
||||
Ok(pred(&mut reader)?)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,49 @@
|
|||
use std::io::{Read, Write};
|
||||
use bytemuck::bytes_of;
|
||||
use log::error;
|
||||
use rocket::form::validate::Len;
|
||||
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use super::{Result, RmcSerialize};
|
||||
|
||||
impl RmcSerialize for String{
|
||||
fn deserialize(mut reader: &mut dyn Read) -> Result<Self> {
|
||||
fn deserialize(mut reader: &mut impl Read) -> Result<Self> {
|
||||
let len: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
let mut data = vec![0; len as usize - 1];
|
||||
if len == 0{
|
||||
return Ok("".to_string());
|
||||
}
|
||||
let mut data = vec![0; len as usize];
|
||||
reader.read_exact(&mut data)?;
|
||||
|
||||
let null: u8 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
if null != 0{
|
||||
if *data.last().unwrap() != 0{
|
||||
error!("unable to find null terminator... continuing anyways");
|
||||
}
|
||||
data.pop();
|
||||
|
||||
Ok(String::from_utf8(data)?)
|
||||
}
|
||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||
(&self[..]).serialize(writer)
|
||||
}
|
||||
fn serialize_write_size(&self) -> Result<u32> {
|
||||
(&self[..]).serialize_write_size()
|
||||
}
|
||||
}
|
||||
|
||||
impl RmcSerialize for &str{
|
||||
fn deserialize(_reader: &mut dyn Read) -> Result<Self> {
|
||||
fn deserialize(_reader: &mut impl Read) -> Result<Self> {
|
||||
panic!("cannot serialize to &str")
|
||||
}
|
||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
|
||||
let u16_len: u16 = (self.len() + 1) as u16;
|
||||
writer.write(bytes_of(&u16_len))?;
|
||||
writer.write_all(bytes_of(&u16_len))?;
|
||||
|
||||
writer.write(self.as_bytes())?;
|
||||
writer.write(&[0])?;
|
||||
writer.write_all(self.as_bytes())?;
|
||||
writer.write_all(&[0])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
#[inline(always)]
|
||||
fn serialize_write_size(&self) -> Result<u32> {
|
||||
Ok(2 + self.as_bytes().len() as u32 + 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ pub enum Variant{
|
|||
}
|
||||
|
||||
impl RmcSerialize for Variant{
|
||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
|
||||
match self{
|
||||
Variant::None => {
|
||||
writer.write_all(&[0])?;
|
||||
|
|
@ -50,7 +50,7 @@ impl RmcSerialize for Variant{
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
|
||||
match u8::deserialize(reader)?{
|
||||
0 => Ok(Variant::None),
|
||||
1 => Ok(Variant::SInt64(i64::deserialize(reader)?)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue