feat(secure): add get_playing_session and start working on auto_matchmake_with_param_postpone with RmcSerialize macro
This commit is contained in:
parent
d8c184171d
commit
d01acbb931
16 changed files with 338 additions and 23 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
|
@ -798,6 +798,15 @@ version = "0.4.25"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "macros"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchit"
|
name = "matchit"
|
||||||
version = "0.7.3"
|
version = "0.7.3"
|
||||||
|
|
@ -1313,6 +1322,7 @@ dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"hmac",
|
"hmac",
|
||||||
"log",
|
"log",
|
||||||
|
"macros",
|
||||||
"md-5",
|
"md-5",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"prost",
|
"prost",
|
||||||
|
|
|
||||||
|
|
@ -24,5 +24,7 @@ tonic = "0.12.3"
|
||||||
prost = "0.13.4"
|
prost = "0.13.4"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
|
||||||
|
macros = { path = "macros" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tonic-build = "0.12.3"
|
tonic-build = "0.12.3"
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::io;
|
use std::{io, mem};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use bytemuck::Pod;
|
use bytemuck::Pod;
|
||||||
|
|
@ -162,6 +162,14 @@ impl SwapEndian for u64{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SwapEndian for f64{
|
||||||
|
#[inline]
|
||||||
|
fn swap_endian(self) -> Self {
|
||||||
|
//trust me this is safe
|
||||||
|
unsafe{ mem::transmute::<_, f64>(mem::transmute::<_, u64>(self).swap_bytes()) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SwapEndian for i8{
|
impl SwapEndian for i8{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn swap_endian(self) -> Self {
|
fn swap_endian(self) -> Self {
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,16 @@ impl KerberosDateTime{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl RmcSerialize for KerberosDateTime{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
Ok(self.0.serialize(writer)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
Ok(Self(u64::deserialize(reader)?))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Pod, Zeroable, Copy, Clone)]
|
#[derive(Pod, Zeroable, Copy, Clone)]
|
||||||
#[repr(C, packed)]
|
#[repr(C, packed)]
|
||||||
pub struct TicketInternalData{
|
pub struct TicketInternalData{
|
||||||
|
|
|
||||||
17
src/main.rs
17
src/main.rs
|
|
@ -6,14 +6,17 @@ use std::net::{Ipv4Addr, SocketAddrV4};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use macros::RmcSerialize;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use rc4::{KeyInit, Rc4, StreamCipher};
|
use rc4::{KeyInit, Rc4, StreamCipher};
|
||||||
use rc4::consts::U5;
|
use rc4::consts::U5;
|
||||||
use simplelog::{ColorChoice, CombinedLogger, Config, LevelFilter, TerminalMode, TermLogger, WriteLogger};
|
use simplelog::{ColorChoice, CombinedLogger, Config, LevelFilter, TerminalMode, TermLogger, WriteLogger};
|
||||||
|
use tokio::sync::Mutex;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use crate::nex::account::Account;
|
use crate::nex::account::Account;
|
||||||
use crate::protocols::auth;
|
use crate::protocols::auth;
|
||||||
use crate::protocols::auth::AuthProtocolConfig;
|
use crate::protocols::auth::AuthProtocolConfig;
|
||||||
|
use crate::protocols::matchmake_common::MatchmakeData;
|
||||||
use crate::protocols::server::RMCProtocolServer;
|
use crate::protocols::server::RMCProtocolServer;
|
||||||
use crate::prudp::socket::{ActiveSecureConnectionData, EncryptionPair, Socket};
|
use crate::prudp::socket::{ActiveSecureConnectionData, EncryptionPair, Socket};
|
||||||
use crate::prudp::packet::{PRUDPPacket, VirtualPort};
|
use crate::prudp::packet::{PRUDPPacket, VirtualPort};
|
||||||
|
|
@ -21,6 +24,7 @@ use crate::prudp::router::Router;
|
||||||
use crate::prudp::secure::{generate_secure_encryption_pairs, read_secure_connection_data};
|
use crate::prudp::secure::{generate_secure_encryption_pairs, read_secure_connection_data};
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::structures::RmcSerialize;
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
use crate::rmc::structures::variant::Variant;
|
||||||
|
|
||||||
mod endianness;
|
mod endianness;
|
||||||
mod prudp;
|
mod prudp;
|
||||||
|
|
@ -166,8 +170,13 @@ async fn start_secure_server() -> SecureServer{
|
||||||
|
|
||||||
info!("setting up endpoints");
|
info!("setting up endpoints");
|
||||||
|
|
||||||
|
let matchmake_data = Arc::new(Mutex::new(
|
||||||
|
MatchmakeData{}
|
||||||
|
));
|
||||||
|
|
||||||
let rmcserver = RMCProtocolServer::new(Box::new([
|
let rmcserver = RMCProtocolServer::new(Box::new([
|
||||||
Box::new(protocols::secure::bound_protocol())
|
Box::new(protocols::secure::bound_protocol()),
|
||||||
|
Box::new(protocols::matchmake_extension::bound_protocol(matchmake_data))
|
||||||
]));
|
]));
|
||||||
|
|
||||||
let mut socket =
|
let mut socket =
|
||||||
|
|
@ -274,4 +283,10 @@ mod test{
|
||||||
|
|
||||||
println!("packet: {:?}", packet);
|
println!("packet: {:?}", packet);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
struct MatchmakeParam{
|
||||||
|
params: Vec<(String, Variant)>
|
||||||
}
|
}
|
||||||
4
src/protocols/matchmake_common/mod.rs
Normal file
4
src/protocols/matchmake_common/mod.rs
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
pub struct MatchmakeData{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use crate::protocols::matchmake_common::MatchmakeData;
|
||||||
|
use crate::prudp::socket::ConnectionData;
|
||||||
|
use crate::rmc::message::RMCMessage;
|
||||||
|
|
||||||
|
pub async fn auto_matchmake_with_param_postpone_raw_params(rmcmessage: &RMCMessage, _: &mut ConnectionData, data: Arc<Mutex<MatchmakeData>>){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
use std::io::Cursor;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use crate::protocols::matchmake_common::MatchmakeData;
|
||||||
|
use crate::prudp::socket::ConnectionData;
|
||||||
|
use crate::rmc::message::RMCMessage;
|
||||||
|
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||||
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
type PIDList = Vec<u32>;
|
||||||
|
|
||||||
|
async fn get_playing_session(rmcmessage: &RMCMessage, data: Arc<Mutex<MatchmakeData>>) -> RMCResponseResult {
|
||||||
|
//todo: propperly implement this
|
||||||
|
|
||||||
|
let cheeseburger = PIDList::new();
|
||||||
|
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
|
||||||
|
cheeseburger.serialize(&mut vec).expect("somehow unable to write cheeseburger");
|
||||||
|
|
||||||
|
rmcmessage.success_with_data(vec)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_playing_session_raw_params(rmcmessage: &RMCMessage, _: &mut ConnectionData, data: Arc<Mutex<MatchmakeData>>) -> RMCResponseResult{
|
||||||
|
let mut reader = Cursor::new(&rmcmessage.rest_of_data);
|
||||||
|
|
||||||
|
let Ok(list) = PIDList::deserialize(&mut reader) else {
|
||||||
|
return rmcmessage.error_result_with_code(ErrorCode::FPD_FriendNotExists);
|
||||||
|
};
|
||||||
|
|
||||||
|
get_playing_session(rmcmessage, data).await
|
||||||
|
}
|
||||||
14
src/protocols/matchmake_extension/mod.rs
Normal file
14
src/protocols/matchmake_extension/mod.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
mod method_get_playing_session;
|
||||||
|
mod method_auto_matchmake_with_param_postpone;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use crate::define_protocol;
|
||||||
|
use crate::protocols::matchmake_common::MatchmakeData;
|
||||||
|
use method_get_playing_session::get_playing_session_raw_params;
|
||||||
|
|
||||||
|
define_protocol!{
|
||||||
|
109(matchmake_data: Arc<Mutex<MatchmakeData>>) => {
|
||||||
|
16 => get_playing_session_raw_params
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,8 @@ use crate::prudp::socket::ConnectionData;
|
||||||
pub mod auth;
|
pub mod auth;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod secure;
|
pub mod secure;
|
||||||
|
pub mod matchmake_extension;
|
||||||
|
pub mod matchmake_common;
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! define_protocol {
|
macro_rules! define_protocol {
|
||||||
|
|
@ -40,11 +42,17 @@ macro_rules! define_protocol {
|
||||||
-> ::std::pin::Pin<Box<dyn ::std::future::Future<Output = Option<crate::rmc::response::RMCResponse>> + Send + 'message_lifetime>> + Send + Sync>{
|
-> ::std::pin::Pin<Box<dyn ::std::future::Future<Output = Option<crate::rmc::response::RMCResponse>> + Send + 'message_lifetime>> + Send + Sync>{
|
||||||
Box::new(
|
Box::new(
|
||||||
move |v, cd| {
|
move |v, cd| {
|
||||||
Box::pin(async move {
|
Box::pin({
|
||||||
$(
|
$(
|
||||||
let $varname = $varname.clone();
|
let $varname = $varname.clone();
|
||||||
)*
|
)*
|
||||||
protocol(v, cd, $($varname,)*).await
|
|
||||||
|
async move {
|
||||||
|
$(
|
||||||
|
let $varname = $varname.clone();
|
||||||
|
)*
|
||||||
|
protocol(v, cd, $($varname,)*).await
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -17,22 +17,6 @@ impl<'a> RmcSerialize for &'a [u8]{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> RmcSerialize for Vec<u8>{
|
|
||||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
|
||||||
(&self[..]).serialize(writer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
|
||||||
let len: u32 = reader.read_struct(IS_BIG_ENDIAN)?;
|
|
||||||
|
|
||||||
let mut data = vec![0; len as usize];
|
|
||||||
|
|
||||||
reader.read_exact(&mut data)?;
|
|
||||||
|
|
||||||
Ok(data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> RmcSerialize for Box<[u8]>{
|
impl<'a> RmcSerialize for Box<[u8]>{
|
||||||
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
(&self[..]).serialize(writer)
|
(&self[..]).serialize(writer)
|
||||||
|
|
|
||||||
54
src/rmc/structures/matchmake.rs
Normal file
54
src/rmc/structures/matchmake.rs
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
use macros::RmcSerialize;
|
||||||
|
use crate::kerberos::KerberosDateTime;
|
||||||
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
use crate::rmc::structures::variant::Variant;
|
||||||
|
|
||||||
|
// rmc structure
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
struct Gathering{
|
||||||
|
self_gid: u32,
|
||||||
|
owner_pid: u32,
|
||||||
|
host_pid: u32,
|
||||||
|
minimum_participants: u16,
|
||||||
|
maximum_participants: u16,
|
||||||
|
participant_policy: u32,
|
||||||
|
policy_argument: u32,
|
||||||
|
flags: u32,
|
||||||
|
state: u32,
|
||||||
|
description: String
|
||||||
|
}
|
||||||
|
|
||||||
|
// rmc structure
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
struct MatchmakeParam{
|
||||||
|
params: Vec<(String, Variant)>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// rmc structure
|
||||||
|
#[derive(RmcSerialize)]
|
||||||
|
#[rmc_struct(3)]
|
||||||
|
struct MatchmakeSession{
|
||||||
|
//inherits from
|
||||||
|
#[extends]
|
||||||
|
gathering: Gathering,
|
||||||
|
|
||||||
|
gamemode: u32,
|
||||||
|
attributes: Vec<u32>,
|
||||||
|
open_participation: bool,
|
||||||
|
matchmake_system_type: u32,
|
||||||
|
application_buffer: Vec<u8>,
|
||||||
|
participation_count: u32,
|
||||||
|
progress_score: u8,
|
||||||
|
session_key: Vec<u8>,
|
||||||
|
option0: u32,
|
||||||
|
matchmake_param: MatchmakeParam,
|
||||||
|
datetime: KerberosDateTime,
|
||||||
|
user_password: String,
|
||||||
|
refer_gid: u32,
|
||||||
|
user_password_enabled: bool,
|
||||||
|
system_password_enabled: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -10,10 +10,14 @@ pub enum Error{
|
||||||
#[error("Io Error: {0}")]
|
#[error("Io Error: {0}")]
|
||||||
Io(#[from] io::Error),
|
Io(#[from] io::Error),
|
||||||
#[error("UTF8 conversion Error: {0}")]
|
#[error("UTF8 conversion Error: {0}")]
|
||||||
Utf8(#[from] FromUtf8Error)
|
Utf8(#[from] FromUtf8Error),
|
||||||
|
#[error("unexpected value: {0}")]
|
||||||
|
UnexpectedValue(u64),
|
||||||
|
#[error("version mismatch: {0}")]
|
||||||
|
VersionMismatch(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Error>;
|
pub(crate) type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
pub mod string;
|
pub mod string;
|
||||||
pub mod any;
|
pub mod any;
|
||||||
|
|
@ -23,6 +27,9 @@ pub mod connection_data;
|
||||||
pub mod rmc_struct;
|
pub mod rmc_struct;
|
||||||
pub mod list;
|
pub mod list;
|
||||||
pub mod qbuffer;
|
pub mod qbuffer;
|
||||||
|
pub mod primitives;
|
||||||
|
pub mod matchmake;
|
||||||
|
pub mod variant;
|
||||||
|
|
||||||
pub trait RmcSerialize: Sized{
|
pub trait RmcSerialize: Sized{
|
||||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()>;
|
fn serialize(&self, writer: &mut dyn Write) -> Result<()>;
|
||||||
|
|
|
||||||
94
src/rmc/structures/primitives.rs
Normal file
94
src/rmc/structures/primitives.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use bytemuck::bytes_of;
|
||||||
|
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||||
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
impl RmcSerialize for u8{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RmcSerialize for u16{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RmcSerialize for u32{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RmcSerialize for u64{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RmcSerialize for i64{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RmcSerialize for f64{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
Ok(writer.write_all(bytes_of(self))?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RmcSerialize for bool{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
match self{
|
||||||
|
true => writer.write_all(&[1])?,
|
||||||
|
false => writer.write_all(&[0])?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(mut reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
Ok(u8::deserialize(reader)? != 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl<T: RmcSerialize, U: RmcSerialize> RmcSerialize for (T, U){
|
||||||
|
fn serialize(&self, writer: &mut dyn 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> {
|
||||||
|
let first = T::deserialize(reader)?;
|
||||||
|
let second = U::deserialize(reader)?;
|
||||||
|
|
||||||
|
Ok((first, second))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -21,4 +21,5 @@ pub fn write_struct(mut writer: &mut dyn Write, version: u8, pred: impl Fn(&mut
|
||||||
writer.write_all(&scratch_space)?;
|
writer.write_all(&scratch_space)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
63
src/rmc/structures/variant.rs
Normal file
63
src/rmc/structures/variant.rs
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
use crate::kerberos::KerberosDateTime;
|
||||||
|
use crate::rmc::structures;
|
||||||
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
pub enum Variant{
|
||||||
|
None,
|
||||||
|
SInt64(i64),
|
||||||
|
Double(f64),
|
||||||
|
Bool(bool),
|
||||||
|
String(String),
|
||||||
|
DateTime(KerberosDateTime),
|
||||||
|
UInt64(u64),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RmcSerialize for Variant{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> crate::rmc::structures::Result<()> {
|
||||||
|
match self{
|
||||||
|
Variant::None => {
|
||||||
|
writer.write_all(&[0])?;
|
||||||
|
}
|
||||||
|
Variant::SInt64(v) => {
|
||||||
|
writer.write_all(&[1])?;
|
||||||
|
v.serialize(writer)?;
|
||||||
|
}
|
||||||
|
Variant::Double(v) => {
|
||||||
|
writer.write_all(&[2])?;
|
||||||
|
v.serialize(writer)?;
|
||||||
|
}
|
||||||
|
Variant::Bool(v) => {
|
||||||
|
writer.write_all(&[3])?;
|
||||||
|
v.serialize(writer)?;
|
||||||
|
}
|
||||||
|
Variant::String(v) => {
|
||||||
|
writer.write_all(&[4])?;
|
||||||
|
v.serialize(writer)?;
|
||||||
|
}
|
||||||
|
Variant::DateTime(v) => {
|
||||||
|
writer.write_all(&[5])?;
|
||||||
|
v.serialize(writer)?;
|
||||||
|
}
|
||||||
|
Variant::UInt64(v) => {
|
||||||
|
writer.write_all(&[6])?;
|
||||||
|
v.serialize(writer)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(reader: &mut dyn Read) -> crate::rmc::structures::Result<Self> {
|
||||||
|
match u8::deserialize(reader)?{
|
||||||
|
0 => Ok(Variant::None),
|
||||||
|
1 => Ok(Variant::SInt64(i64::deserialize(reader)?)),
|
||||||
|
2 => Ok(Variant::Double(f64::deserialize(reader)?)),
|
||||||
|
3 => Ok(Variant::Bool(bool::deserialize(reader)?)),
|
||||||
|
4 => Ok(Variant::String(String::deserialize(reader)?)),
|
||||||
|
5 => Ok(Variant::DateTime(KerberosDateTime::deserialize(reader)?)),
|
||||||
|
6 => Ok(Variant::UInt64(u64::deserialize(reader)?)),
|
||||||
|
v => Err(structures::Error::UnexpectedValue(v as u64))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue