feat: refactor prudp code and start working on refactoring rmc
This commit is contained in:
parent
7d24a71f09
commit
3ea7c7e671
37 changed files with 2029 additions and 456 deletions
848
Cargo.lock
generated
848
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -25,6 +25,9 @@ prost = "0.13.4"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
|
|
||||||
macros = { path = "macros" }
|
macros = { path = "macros" }
|
||||||
|
rocket = { version = "0.5.1", features = ["json", "serde_json"] }
|
||||||
|
serde = { version = "1.0.217", features = ["derive"] }
|
||||||
|
async-trait = "0.1.86"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
tonic-build = "0.12.3"
|
tonic-build = "0.12.3"
|
||||||
|
|
|
||||||
121
src/main.rs
121
src/main.rs
|
|
@ -14,25 +14,21 @@ use simplelog::{ColorChoice, CombinedLogger, Config, LevelFilter, TerminalMode,
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use crate::nex::account::Account;
|
use crate::nex::account::Account;
|
||||||
use crate::protocols::{auth, block_if_maintenance};
|
use crate::prudp::socket::{EncryptionPair, Unsecure};
|
||||||
use crate::protocols::auth::AuthProtocolConfig;
|
|
||||||
use crate::protocols::matchmake_common::MatchmakeData;
|
|
||||||
use crate::protocols::server::RMCProtocolServer;
|
|
||||||
use crate::prudp::socket::{ActiveSecureConnectionData, EncryptionPair, Socket};
|
|
||||||
use crate::prudp::packet::{VirtualPort};
|
use crate::prudp::packet::{VirtualPort};
|
||||||
use crate::prudp::router::Router;
|
use crate::prudp::router::Router;
|
||||||
use crate::prudp::secure::{generate_secure_encryption_pairs, read_secure_connection_data};
|
use crate::prudp::sockaddr::PRUDPSockAddr;
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::prudp::station_url::Type::PRUDP;
|
||||||
use crate::rmc::structures::RmcSerialize;
|
|
||||||
|
|
||||||
mod endianness;
|
mod endianness;
|
||||||
mod prudp;
|
mod prudp;
|
||||||
pub mod rmc;
|
pub mod rmc;
|
||||||
mod protocols;
|
//mod protocols;
|
||||||
|
|
||||||
mod nex;
|
mod nex;
|
||||||
mod grpc;
|
mod grpc;
|
||||||
mod kerberos;
|
mod kerberos;
|
||||||
|
mod web;
|
||||||
|
|
||||||
static KERBEROS_SERVER_PASSWORD: Lazy<String> = Lazy::new(||{
|
static KERBEROS_SERVER_PASSWORD: Lazy<String> = Lazy::new(||{
|
||||||
env::var("AUTH_SERVER_PASSWORD")
|
env::var("AUTH_SERVER_PASSWORD")
|
||||||
|
|
@ -97,6 +93,7 @@ async fn main() {
|
||||||
|
|
||||||
start_servers().await;
|
start_servers().await;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
struct AuthServer{
|
struct AuthServer{
|
||||||
router: Arc<Router>,
|
router: Arc<Router>,
|
||||||
|
|
@ -236,74 +233,66 @@ async fn start_secure_server() -> SecureServer{
|
||||||
router,
|
router,
|
||||||
socket,
|
socket,
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
async fn start_servers(){
|
async fn start_servers(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let a = tokio::spawn(async{
|
||||||
|
let (router_auth, _) =
|
||||||
|
Router::new(SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT)).await.expect("unable to start router");
|
||||||
|
|
||||||
|
let mut socket_auth = router_auth.add_socket(VirtualPort::new(1,10), Unsecure("CD&ML")).await
|
||||||
|
.expect("unable to add socket");
|
||||||
|
|
||||||
|
let mut conn = socket_auth.accept().await.unwrap();
|
||||||
|
info!("got conn");
|
||||||
|
|
||||||
|
if let Some(data) = conn.recv().await{
|
||||||
|
let str = String::from_utf8(data).unwrap();
|
||||||
|
|
||||||
|
println!("{}", str)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let b = tokio::spawn(async{
|
||||||
|
let auth_ip = SocketAddrV4::new(*OWN_IP_PRIVATE, *AUTH_SERVER_PORT);
|
||||||
|
let auth_port = VirtualPort::new(1,10);
|
||||||
|
|
||||||
|
let auth_sockaddr = PRUDPSockAddr::new(auth_ip,auth_port);
|
||||||
|
|
||||||
|
|
||||||
|
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), Unsecure("CD&ML")).await
|
||||||
|
.expect("unable to add socket");
|
||||||
|
|
||||||
|
let conn = socket_secure.connect(auth_sockaddr).await.unwrap();
|
||||||
|
|
||||||
|
let conn = conn.duplicate_sender();
|
||||||
|
|
||||||
|
conn.send("Yippie".as_bytes().to_owned()).await;
|
||||||
|
|
||||||
|
info!("got conn");
|
||||||
|
});
|
||||||
|
|
||||||
|
a.await;
|
||||||
|
b.await;
|
||||||
|
|
||||||
|
/*
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
let auth_server = start_auth_server().await;
|
let auth_server = start_auth_server().await;
|
||||||
#[cfg(feature = "secure")]
|
#[cfg(feature = "secure")]
|
||||||
let secure_server = start_secure_server().await;
|
let secure_server = start_secure_server().await;
|
||||||
|
let web_server = web::start_web().await;
|
||||||
|
|
||||||
#[cfg(feature = "auth")]
|
#[cfg(feature = "auth")]
|
||||||
auth_server.join_handle.await.expect("auth server crashed");
|
auth_server.join_handle.await.expect("auth server crashed");
|
||||||
#[cfg(feature = "secure")]
|
#[cfg(feature = "secure")]
|
||||||
secure_server.join_handle.await.expect("auth server crashed");
|
secure_server.join_handle.await.expect("auth server crashed");
|
||||||
}
|
web_server.await.expect("webserver crashed");*/
|
||||||
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test{
|
|
||||||
use std::io::Cursor;
|
|
||||||
use std::num::ParseIntError;
|
|
||||||
use std::str::from_utf8;
|
|
||||||
use hmac::digest::consts::U5;
|
|
||||||
use rc4::{KeyInit, Rc4, StreamCipher};
|
|
||||||
use crate::prudp::packet::PRUDPPacket;
|
|
||||||
use crate::rmc;
|
|
||||||
|
|
||||||
fn from_hex_stream(val: &str) -> Result<Vec<u8>, ParseIntError> {
|
|
||||||
let res: Result<Vec<u8>, _> = val.as_bytes()
|
|
||||||
.chunks_exact(2)
|
|
||||||
.map(|c| from_utf8(c).expect("unable to convert back to string"))
|
|
||||||
.map(|s| u8::from_str_radix(s, 16))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn simulate_packets(){
|
|
||||||
let val = from_hex_stream("ead001037d00afa1e200a5000200d9e4a4050368c18c6de4e2fb1cc40f0c020100768744db99f92c5005a061fd2a1df280cd64d5c1a565952c6befa607cbaf34661312b16db0fa6fccfb81e28b5a3a9bed02b49152bbc99cc112b7e29b9e45ec3d4b89df0fe71390883d9a927c264d07ada0de9cd28499e3ccdf3fd079e4a9848d4d783778c42da2af06106a7326634dc5bec5c3438ef18e30109839ffcc").expect("uuuuh");
|
|
||||||
|
|
||||||
let mut packet = PRUDPPacket::new(&mut Cursor::new(&val)).expect("invalid packet");
|
|
||||||
|
|
||||||
let mut rc4: Rc4<U5> =
|
|
||||||
Rc4::new_from_slice("CD&ML".as_bytes().into()).expect("invalid key");
|
|
||||||
|
|
||||||
rc4.apply_keystream(&mut packet.payload);
|
|
||||||
|
|
||||||
println!("packet: {:?}", packet);
|
|
||||||
|
|
||||||
let rmc_packet = rmc::message::RMCMessage::new(&mut Cursor::new(&packet.payload)).expect("unable to read message");
|
|
||||||
|
|
||||||
let mut a = Cursor::new(&rmc_packet.rest_of_data);
|
|
||||||
|
|
||||||
//let pid = rmc::structures::string::read(&mut a).expect("unable to read pid");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn simulate_packets_response(){
|
|
||||||
let val = from_hex_stream("ead001032501a1af6200a500010013ffcdbc3a2ebc44efc6e38ea32a72b40201002e8644db19fe2a5005a2637d2a16f3b1fe5633037c1ed61c5aefad8afebdf2ff8600e9350fba1298b570c70f6dd647eac2d3faf0ab74ef761e2ee43dc10e249e5f91aed6813dcc04b3c707d9442b6e353b9b0b654e98f860fe5379c41d3c2a1874b7dd37ebf499e03bd2fd3e9a9203c0959feb760c38f504dcd0c9e99b17fd410657da4efa3e01c8a68ab3042d6d489788d5580778d32249cdf1fba8bf68cf4019d116ea7c580622ea1e3635139d91b44635d5e95b6c35b33898fdc0117fa6fc7162840d07a49f1e7089aa0ea65409a8ddeb2334449ba73a0ff7de462cf4a706a696de0f0521b84ae5a3f8587f3585d202d3cc0fb0451519c1b830b5e3cdd6de52e9add7325cbbf08a7c2f8b875934942b226703a22b4bc8931932dab055049051e4144b02").expect("uuuuh");
|
|
||||||
|
|
||||||
let mut packet = PRUDPPacket::new(&mut Cursor::new(&val)).expect("invalid packet");
|
|
||||||
|
|
||||||
let mut rc4: Rc4<U5> =
|
|
||||||
Rc4::new_from_slice("CD&ML".as_bytes().into()).expect("invalid key");
|
|
||||||
|
|
||||||
rc4.apply_keystream(&mut packet.payload);
|
|
||||||
|
|
||||||
println!("packet: {:?}", packet);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ use std::sync::Arc;
|
||||||
use log::error;
|
use log::error;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use crate::protocols::auth::AuthProtocolConfig;
|
use crate::protocols::auth::AuthProtocolConfig;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||||
use crate::rmc::structures::RmcSerialize;
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
@ -7,7 +7,6 @@ use crate::grpc::account;
|
||||||
use crate::kerberos::KerberosDateTime;
|
use crate::kerberos::KerberosDateTime;
|
||||||
use crate::protocols::auth::AuthProtocolConfig;
|
use crate::protocols::auth::AuthProtocolConfig;
|
||||||
use crate::protocols::auth::ticket_generation::generate_ticket;
|
use crate::protocols::auth::ticket_generation::generate_ticket;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc;
|
use crate::rmc;
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||||
|
|
@ -4,7 +4,6 @@ use tokio::sync::Mutex;
|
||||||
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||||
use crate::protocols::auth::{AuthProtocolConfig, get_login_data_by_pid};
|
use crate::protocols::auth::{AuthProtocolConfig, get_login_data_by_pid};
|
||||||
use crate::protocols::auth::ticket_generation::generate_ticket;
|
use crate::protocols::auth::ticket_generation::generate_ticket;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||||
use crate::rmc::response::ErrorCode::Core_Unknown;
|
use crate::rmc::response::ErrorCode::Core_Unknown;
|
||||||
|
|
@ -2,7 +2,6 @@ use std::io::Cursor;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::{Mutex, RwLock};
|
use tokio::sync::{Mutex, RwLock};
|
||||||
use crate::protocols::matchmake_common::MatchmakeData;
|
use crate::protocols::matchmake_common::MatchmakeData;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||||
use crate::rmc::structures::qresult::QResult;
|
use crate::rmc::structures::qresult::QResult;
|
||||||
|
|
@ -5,7 +5,6 @@ use rand::random;
|
||||||
use tokio::sync::{Mutex, RwLock};
|
use tokio::sync::{Mutex, RwLock};
|
||||||
use crate::kerberos::KerberosDateTime;
|
use crate::kerberos::KerberosDateTime;
|
||||||
use crate::protocols::notification::Notification;
|
use crate::protocols::notification::Notification;
|
||||||
use crate::prudp::socket::{ActiveConnectionData, ConnectionData, SocketData};
|
|
||||||
use crate::rmc::structures::matchmake::{Gathering, MatchmakeParam, MatchmakeSession};
|
use crate::rmc::structures::matchmake::{Gathering, MatchmakeParam, MatchmakeSession};
|
||||||
use crate::rmc::structures::variant::Variant;
|
use crate::rmc::structures::variant::Variant;
|
||||||
|
|
||||||
|
|
@ -44,7 +43,7 @@ impl ExtendedMatchmakeSession{
|
||||||
|
|
||||||
let mm_session = MatchmakeSession{
|
let mm_session = MatchmakeSession{
|
||||||
gathering: Gathering{
|
gathering: Gathering{
|
||||||
self_gid: random(),
|
self_gid: 1,
|
||||||
owner_pid: active_secure_connection_data.pid,
|
owner_pid: active_secure_connection_data.pid,
|
||||||
host_pid: active_secure_connection_data.pid,
|
host_pid: active_secure_connection_data.pid,
|
||||||
..session.gathering.clone()
|
..session.gathering.clone()
|
||||||
|
|
@ -7,7 +7,6 @@ use rand::random;
|
||||||
use tokio::sync::{Mutex, RwLock};
|
use tokio::sync::{Mutex, RwLock};
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use crate::protocols::matchmake_common::{ExtendedMatchmakeSession, MatchmakeData};
|
use crate::protocols::matchmake_common::{ExtendedMatchmakeSession, MatchmakeData};
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||||
use crate::rmc::structures::matchmake::{AutoMatchmakeParam, MatchmakeSession};
|
use crate::rmc::structures::matchmake::{AutoMatchmakeParam, MatchmakeSession};
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
use log::info;
|
use log::info;
|
||||||
use tokio::sync::{Mutex, RwLock};
|
use tokio::sync::{Mutex, RwLock};
|
||||||
|
use tokio::time::sleep;
|
||||||
use crate::protocols::matchmake_common::{add_matchmake_session, ExtendedMatchmakeSession, MatchmakeData};
|
use crate::protocols::matchmake_common::{add_matchmake_session, ExtendedMatchmakeSession, MatchmakeData};
|
||||||
use crate::protocols::matchmake_extension::method_auto_matchmake_with_param_postpone::auto_matchmake_with_param_postpone;
|
use crate::protocols::matchmake_extension::method_auto_matchmake_with_param_postpone::auto_matchmake_with_param_postpone;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||||
use crate::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam};
|
use crate::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam};
|
||||||
|
|
@ -29,13 +30,17 @@ pub async fn create_matchmake_session_with_param(
|
||||||
|
|
||||||
session.add_player(&socket, conn.clone(), create_matchmake_session.join_message).await;
|
session.add_player(&socket, conn.clone(), create_matchmake_session.join_message).await;
|
||||||
|
|
||||||
println!("{:?}", session);
|
|
||||||
|
|
||||||
let mut response = Vec::new();
|
let mut response = Vec::new();
|
||||||
|
|
||||||
|
|
||||||
session.session.serialize(&mut response).expect("unable to serialize session");
|
session.session.serialize(&mut response).expect("unable to serialize session");
|
||||||
|
|
||||||
|
println!("{}", hex::encode(&response));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rmcmessage.success_with_data(response)
|
rmcmessage.success_with_data(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,7 +56,32 @@ pub async fn create_matchmake_session_with_param_raw_params(
|
||||||
return rmcmessage.error_result_with_code(ErrorCode::Core_InvalidArgument);
|
return rmcmessage.error_result_with_code(ErrorCode::Core_InvalidArgument);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
create_matchmake_session_with_param(rmcmessage, connection_data, socket, data, matchmake_param).await
|
create_matchmake_session_with_param(rmcmessage, connection_data, socket, data, matchmake_param).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test{
|
||||||
|
use std::io::Cursor;
|
||||||
|
use crate::prudp::packet::PRUDPPacket;
|
||||||
|
use crate::rmc::message::RMCMessage;
|
||||||
|
use crate::rmc::structures::matchmake::MatchmakeSession;
|
||||||
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test(){
|
||||||
|
let data = hex::decode("ead001030000a1af12001800050002010000000000000000000000000000000000").unwrap();
|
||||||
|
|
||||||
|
let packet = PRUDPPacket::new(&mut Cursor::new(data)).unwrap();
|
||||||
|
|
||||||
|
println!("{:?}", packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_2(){
|
||||||
|
let data = hex::decode("250000008e0100000001000000001700000051b39957b90b00000100000051b3995701000001000000").unwrap();
|
||||||
|
|
||||||
|
let msg = RMCMessage::new(&mut Cursor::new(data)).unwrap();
|
||||||
|
|
||||||
|
println!("{:?}", msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,6 @@ use std::sync::Arc;
|
||||||
use log::info;
|
use log::info;
|
||||||
use tokio::sync::{Mutex, RwLock};
|
use tokio::sync::{Mutex, RwLock};
|
||||||
use crate::protocols::matchmake_common::MatchmakeData;
|
use crate::protocols::matchmake_common::MatchmakeData;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||||
use crate::rmc::structures::RmcSerialize;
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
@ -6,7 +6,6 @@ use log::warn;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use crate::grpc;
|
use crate::grpc;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{ErrorCode, RMCResponse};
|
use crate::rmc::response::{ErrorCode, RMCResponse};
|
||||||
|
|
||||||
|
|
@ -17,7 +16,7 @@ pub mod secure;
|
||||||
pub mod matchmake_extension;
|
pub mod matchmake_extension;
|
||||||
pub mod matchmake_common;
|
pub mod matchmake_common;
|
||||||
pub mod matchmake;
|
pub mod matchmake;
|
||||||
mod notification;
|
pub mod notification;
|
||||||
pub mod nat_traversal;
|
pub mod nat_traversal;
|
||||||
|
|
||||||
static IS_MAINTENANCE: Lazy<bool> = Lazy::new(|| {
|
static IS_MAINTENANCE: Lazy<bool> = Lazy::new(|| {
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::time::Duration;
|
||||||
use tokio::sync::{Mutex, RwLock};
|
use tokio::sync::{Mutex, RwLock};
|
||||||
|
use tokio::time::sleep;
|
||||||
use crate::protocols::matchmake_common::MatchmakeData;
|
use crate::protocols::matchmake_common::MatchmakeData;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||||
use crate::rmc::structures::matchmake::CreateMatchmakeSessionParam;
|
use crate::rmc::structures::matchmake::CreateMatchmakeSessionParam;
|
||||||
|
|
@ -12,6 +13,7 @@ pub async fn report_nat_properties(
|
||||||
socket: &Arc<SocketData>,
|
socket: &Arc<SocketData>,
|
||||||
connection_data: &Arc<Mutex<ConnectionData>>,
|
connection_data: &Arc<Mutex<ConnectionData>>,
|
||||||
) -> RMCResponseResult{
|
) -> RMCResponseResult{
|
||||||
|
sleep(Duration::from_millis(50)).await;
|
||||||
rmcmessage.success_with_data(Vec::new())
|
rmcmessage.success_with_data(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3,7 +3,6 @@ use rand::random;
|
||||||
use crate::prudp::packet::{PRUDPHeader, PRUDPPacket, PacketOption, TypesFlags};
|
use crate::prudp::packet::{PRUDPHeader, PRUDPPacket, PacketOption, TypesFlags};
|
||||||
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
||||||
use crate::prudp::packet::types::DATA;
|
use crate::prudp::packet::types::DATA;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::structures::RmcSerialize;
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
|
@ -30,10 +29,11 @@ impl ConnectionData{
|
||||||
let message = RMCMessage{
|
let message = RMCMessage{
|
||||||
protocol_id: 14,
|
protocol_id: 14,
|
||||||
method_id: 1,
|
method_id: 1,
|
||||||
call_id: random(),
|
call_id: 1,
|
||||||
rest_of_data: data
|
rest_of_data: data
|
||||||
};
|
};
|
||||||
|
|
||||||
|
println!("notif: {}", hex::encode(message.to_data()));
|
||||||
|
|
||||||
|
|
||||||
let mut prudp_packet = PRUDPPacket{
|
let mut prudp_packet = PRUDPPacket{
|
||||||
|
|
@ -99,23 +99,6 @@ mod test{
|
||||||
println!("{:?}", notif);
|
println!("{:?}", notif);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test3(){
|
|
||||||
|
|
||||||
let data = hex::decode("ead001032900a1af620084000300020100250000008e0100000001000000001700000051b39957b90b00000100000051b399570100000100000000000000000000000000000000000000").unwrap();
|
|
||||||
let packet = PRUDPPacket::new(&mut Cursor::new(data)).expect("invalid packet");
|
|
||||||
|
|
||||||
println!("{:?}", packet);
|
|
||||||
|
|
||||||
let rmc = RMCMessage::new(&mut Cursor::new(packet.payload)).expect("invalid rmc message");
|
|
||||||
|
|
||||||
println!("{:?}", rmc);
|
|
||||||
|
|
||||||
let notif = Notification::deserialize(&mut Cursor::new(rmc.rest_of_data)).expect("invalid notification");
|
|
||||||
|
|
||||||
println!("{:?}", notif);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_rmc_serialization(){
|
fn test_rmc_serialization(){
|
||||||
let notif = Notification{
|
let notif = Notification{
|
||||||
|
|
@ -2,7 +2,6 @@ use std::io::{Cursor, Write};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use bytemuck::bytes_of;
|
use bytemuck::bytes_of;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::prudp::station_url::{nat_types, StationUrl};
|
use crate::prudp::station_url::{nat_types, StationUrl};
|
||||||
use crate::prudp::station_url::Type::PRUDPS;
|
use crate::prudp::station_url::Type::PRUDPS;
|
||||||
use crate::prudp::station_url::UrlOptions::{Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID};
|
use crate::prudp::station_url::UrlOptions::{Address, NatFiltering, NatMapping, NatType, Port, PrincipalID, RVConnectionID};
|
||||||
|
|
@ -3,11 +3,11 @@ use std::sync::Arc;
|
||||||
use log::error;
|
use log::error;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{RMCResponseResult};
|
use crate::rmc::response::{RMCResponseResult};
|
||||||
use crate::rmc::response::ErrorCode::Core_InvalidArgument;
|
use crate::rmc::response::ErrorCode::Core_InvalidArgument;
|
||||||
use crate::rmc::structures::qbuffer;
|
use crate::rmc::structures::{qbuffer, RmcSerialize};
|
||||||
|
use crate::rmc::structures::qbuffer::QBuffer;
|
||||||
|
|
||||||
pub async fn send_report(rmcmessage: &RMCMessage, report_id: u32, data: Vec<u8>) -> RMCResponseResult{
|
pub async fn send_report(rmcmessage: &RMCMessage, report_id: u32, data: Vec<u8>) -> RMCResponseResult{
|
||||||
let result = tokio::fs::write(format!("./reports/{}", report_id), data).await;
|
let result = tokio::fs::write(format!("./reports/{}", report_id), data).await;
|
||||||
|
|
@ -17,7 +17,7 @@ pub async fn send_report(rmcmessage: &RMCMessage, report_id: u32, data: Vec<u8>)
|
||||||
Err(e) => error!("{}", e)
|
Err(e) => error!("{}", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
return rmcmessage.success_with_data(Vec::new());
|
rmcmessage.success_with_data(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_report_raw_params(rmcmessage: &RMCMessage, _: &Arc<SocketData>, _conn_data: &Arc<Mutex<ConnectionData>>, _: ()) -> RMCResponseResult{
|
pub async fn send_report_raw_params(rmcmessage: &RMCMessage, _: &Arc<SocketData>, _conn_data: &Arc<Mutex<ConnectionData>>, _: ()) -> RMCResponseResult{
|
||||||
|
|
@ -27,7 +27,7 @@ pub async fn send_report_raw_params(rmcmessage: &RMCMessage, _: &Arc<SocketData>
|
||||||
return rmcmessage.error_result_with_code(Core_InvalidArgument);
|
return rmcmessage.error_result_with_code(Core_InvalidArgument);
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(data) = qbuffer::read(&mut reader) else {
|
let Ok(QBuffer(data)) = QBuffer::deserialize(&mut reader) else {
|
||||||
return rmcmessage.error_result_with_code(Core_InvalidArgument);
|
return rmcmessage.error_result_with_code(Core_InvalidArgument);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -5,10 +5,11 @@ use std::sync::Arc;
|
||||||
use log::error;
|
use log::error;
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
use crate::prudp::packet::PRUDPPacket;
|
use crate::prudp::packet::PRUDPPacket;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
|
||||||
use crate::rmc::message::RMCMessage;
|
use crate::rmc::message::RMCMessage;
|
||||||
use crate::rmc::response::{RMCResponse, RMCResponseResult, send_response};
|
use crate::rmc::response::{RMCResponse, RMCResponseResult, send_response};
|
||||||
use crate::rmc::response::ErrorCode::Core_NotImplemented;
|
use crate::rmc::response::ErrorCode::Core_NotImplemented;
|
||||||
|
use crate::web::DirectionalData::Incoming;
|
||||||
|
use crate::web::WEB_DATA;
|
||||||
|
|
||||||
type ContainedProtocolList = Box<[Box<dyn for<'a> Fn(&'a RMCMessage, &'a Arc<SocketData>, &'a Arc<Mutex<ConnectionData>>) -> Pin<Box<dyn Future<Output = Option<RMCResponse>> + Send + 'a>> + Send + Sync>]>;
|
type ContainedProtocolList = Box<[Box<dyn for<'a> Fn(&'a RMCMessage, &'a Arc<SocketData>, &'a Arc<Mutex<ConnectionData>>) -> Pin<Box<dyn Future<Output = Option<RMCResponse>> + Send + 'a>> + Send + Sync>]>;
|
||||||
|
|
||||||
|
|
@ -20,6 +21,13 @@ impl RMCProtocolServer{
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn process_message(&self, packet: PRUDPPacket, socket: Arc<SocketData>, connection: Arc<Mutex<ConnectionData>>){
|
pub async fn process_message(&self, packet: PRUDPPacket, socket: Arc<SocketData>, connection: Arc<Mutex<ConnectionData>>){
|
||||||
|
let locked = connection.lock().await;
|
||||||
|
let addr = locked.sock_addr.regular_socket_addr;
|
||||||
|
drop(locked);
|
||||||
|
let mut web = WEB_DATA.lock().await;
|
||||||
|
web.data.push((addr, Incoming(hex::encode(&packet.payload))));
|
||||||
|
drop(web);
|
||||||
|
|
||||||
let Ok(rmc) = RMCMessage::new(&mut Cursor::new(&packet.payload)) else {
|
let Ok(rmc) = RMCMessage::new(&mut Cursor::new(&packet.payload)) else {
|
||||||
error!("error reading rmc message");
|
error!("error reading rmc message");
|
||||||
return;
|
return;
|
||||||
|
|
@ -2,6 +2,6 @@ pub mod packet;
|
||||||
pub mod router;
|
pub mod router;
|
||||||
pub mod socket;
|
pub mod socket;
|
||||||
mod auth_module;
|
mod auth_module;
|
||||||
mod sockaddr;
|
pub mod sockaddr;
|
||||||
pub mod secure;
|
//pub mod secure;
|
||||||
pub mod station_url;
|
pub mod station_url;
|
||||||
|
|
@ -96,10 +96,11 @@ impl Debug for TypesFlags {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
#[derive(PartialEq, Eq, Copy, Clone, Pod, Zeroable, SwapEndian, Hash)]
|
#[derive(PartialEq, Eq, Ord, PartialOrd, Copy, Clone, Pod, Zeroable, SwapEndian, Hash)]
|
||||||
pub struct VirtualPort(pub(crate) u8);
|
pub struct VirtualPort(pub(crate) u8);
|
||||||
|
|
||||||
impl VirtualPort {
|
impl VirtualPort {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn get_stream_type(self) -> u8 {
|
pub const fn get_stream_type(self) -> u8 {
|
||||||
(self.0 & 0xF0) >> 4
|
(self.0 & 0xF0) >> 4
|
||||||
|
|
@ -236,7 +237,7 @@ impl PacketOption{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||||
pub struct PRUDPPacket {
|
pub struct PRUDPPacket {
|
||||||
pub header: PRUDPHeader,
|
pub header: PRUDPHeader,
|
||||||
pub packet_signature: [u8; 16],
|
pub packet_signature: [u8; 16],
|
||||||
|
|
@ -375,6 +376,7 @@ impl PRUDPPacket {
|
||||||
types_and_flags: flags,
|
types_and_flags: flags,
|
||||||
sequence_id: self.header.sequence_id,
|
sequence_id: self.header.sequence_id,
|
||||||
substream_id: self.header.substream_id,
|
substream_id: self.header.substream_id,
|
||||||
|
session_id: self.header.session_id,
|
||||||
..base.header
|
..base.header
|
||||||
},
|
},
|
||||||
options,
|
options,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use once_cell::sync::Lazy;
|
||||||
use log::{error, info, trace};
|
use log::{error, info, trace};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use crate::prudp::socket::SocketData;
|
use crate::prudp::socket::{new_socket_pair, AnyInternalSocket, CryptoHandler, ExternalSocket};
|
||||||
use crate::prudp::packet::{PRUDPPacket, VirtualPort};
|
use crate::prudp::packet::{PRUDPPacket, VirtualPort};
|
||||||
use crate::prudp::router::Error::VirtualPortTaken;
|
use crate::prudp::router::Error::VirtualPortTaken;
|
||||||
|
|
||||||
|
|
@ -22,10 +22,9 @@ static SERVER_DATAGRAMS: Lazy<u8> = Lazy::new(||{
|
||||||
});
|
});
|
||||||
|
|
||||||
pub struct Router {
|
pub struct Router {
|
||||||
endpoints: RwLock<[Option<Arc<SocketData>>; 16]>,
|
endpoints: RwLock<[Option<Arc<dyn AnyInternalSocket>>; 16]>,
|
||||||
running: AtomicBool,
|
running: AtomicBool,
|
||||||
socket: Arc<UdpSocket>,
|
socket: Arc<UdpSocket>,
|
||||||
//pub auth_module: Arc<dyn AuthModule>
|
|
||||||
_no_outside_construction: PhantomData<()>
|
_no_outside_construction: PhantomData<()>
|
||||||
}
|
}
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
@ -36,9 +35,6 @@ pub enum Error{
|
||||||
|
|
||||||
|
|
||||||
impl Router {
|
impl Router {
|
||||||
fn process_prudp_packet(&self, _packet: &PRUDPPacket){
|
|
||||||
|
|
||||||
}
|
|
||||||
async fn process_prudp_packets<'a>(self: Arc<Self>, _socket: Arc<UdpSocket>, addr: SocketAddrV4, udp_message: Vec<u8>){
|
async fn process_prudp_packets<'a>(self: Arc<Self>, _socket: Arc<UdpSocket>, addr: SocketAddrV4, udp_message: Vec<u8>){
|
||||||
let mut stream = Cursor::new(&udp_message);
|
let mut stream = Cursor::new(&udp_message);
|
||||||
|
|
||||||
|
|
@ -69,7 +65,9 @@ impl Router {
|
||||||
|
|
||||||
trace!("sending packet to endpoint");
|
trace!("sending packet to endpoint");
|
||||||
|
|
||||||
endpoint.process_packet(connection, &packet).await;
|
tokio::spawn(async move {
|
||||||
|
endpoint.recieve_packet(connection, packet).await
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,6 +86,7 @@ impl Router {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let current_msg = &msg_buffer[0..len];
|
let current_msg = &msg_buffer[0..len];
|
||||||
|
|
||||||
tokio::spawn(self.clone().process_prudp_packets(socket.clone(), addr, current_msg.to_vec()));
|
tokio::spawn(self.clone().process_prudp_packets(socket.clone(), addr, current_msg.to_vec()));
|
||||||
|
|
@ -144,18 +143,22 @@ impl Router {
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns Some(()) i
|
// returns Some(()) i
|
||||||
pub(crate) async fn add_socket(&self, socket: Arc<SocketData>) -> Result<(), Error>{
|
pub(crate) async fn add_socket<E: CryptoHandler>(&self, virtual_port: VirtualPort, encryption: E)
|
||||||
|
-> Result<ExternalSocket, Error>{
|
||||||
let mut endpoints = self.endpoints.write().await;
|
let mut endpoints = self.endpoints.write().await;
|
||||||
|
|
||||||
let idx = socket.get_virual_port().get_port_number() as usize;
|
let idx = virtual_port.get_port_number() as usize;
|
||||||
|
|
||||||
if endpoints[idx].is_none() {
|
// dont create the socket if we dont need to
|
||||||
endpoints[idx] = Some(socket);
|
if !endpoints[idx].is_none(){
|
||||||
} else {
|
|
||||||
return Err(VirtualPortTaken(idx as u8));
|
return Err(VirtualPortTaken(idx as u8));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
let (internal, external) = new_socket_pair(virtual_port, encryption, self.socket.clone());
|
||||||
|
|
||||||
|
endpoints[idx] = Some(internal);
|
||||||
|
|
||||||
|
Ok(external)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_own_address(&self) -> SocketAddrV4{
|
pub fn get_own_address(&self) -> SocketAddrV4{
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,12 @@ pub fn read_secure_connection_data(data: &[u8], act: &Account) -> Option<([u8; 3
|
||||||
|
|
||||||
type Rc4U32 = StreamCipherCoreWrapper<Rc4Core<U32>>;
|
type Rc4U32 = StreamCipherCoreWrapper<Rc4Core<U32>>;
|
||||||
|
|
||||||
pub fn generate_secure_encryption_pairs(mut session_key: [u8; 32], count: u8) -> Vec<EncryptionPair>{
|
pub fn generate_secure_encryption_pairs(mut session_key: [u8; 32], count: u8) -> Vec<EncryptionPair<Rc4<U32>>>{
|
||||||
let mut vec = Vec::with_capacity(count as usize);
|
let mut vec = Vec::with_capacity(count as usize);
|
||||||
|
|
||||||
vec.push(EncryptionPair{
|
vec.push(EncryptionPair{
|
||||||
send: Box::new(Rc4U32::new_from_slice(&session_key).expect("unable to create rc4")),
|
send: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"),
|
||||||
recv: Box::new(Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"))
|
recv: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4")
|
||||||
});
|
});
|
||||||
|
|
||||||
for _ in 1..=count{
|
for _ in 1..=count{
|
||||||
|
|
@ -91,8 +91,8 @@ pub fn generate_secure_encryption_pairs(mut session_key: [u8; 32], count: u8) ->
|
||||||
}
|
}
|
||||||
|
|
||||||
vec.push(EncryptionPair{
|
vec.push(EncryptionPair{
|
||||||
send: Box::new(Rc4U32::new_from_slice(&session_key).expect("unable to create rc4")),
|
send: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"),
|
||||||
recv: Box::new(Rc4U32::new_from_slice(&session_key).expect("unable to create rc4"))
|
recv: Rc4U32::new_from_slice(&session_key).expect("unable to create rc4")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,24 @@ use crate::prudp::packet::VirtualPort;
|
||||||
|
|
||||||
type Md5Hmac = Hmac<md5::Md5>;
|
type Md5Hmac = Hmac<md5::Md5>;
|
||||||
|
|
||||||
#[derive(Eq, PartialEq, Hash, Debug, Copy, Clone)]
|
#[derive(Eq, PartialEq, Hash, Debug, Copy, Clone, Ord, PartialOrd)]
|
||||||
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{
|
impl PRUDPSockAddr{
|
||||||
pub fn calculate_connection_signature(&self) -> [u8; 16] {
|
|
||||||
|
pub fn new(regular_socket_addr: SocketAddrV4, virtual_port: VirtualPort) -> Self{
|
||||||
|
Self{
|
||||||
|
regular_socket_addr,
|
||||||
|
virtual_port
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn calculate_connection_signature(&self) -> [u8; 16] {
|
||||||
let mut hmac = Md5Hmac::new_from_slice(&[0; 16]).expect("fuck");
|
let mut hmac = Md5Hmac::new_from_slice(&[0; 16]).expect("fuck");
|
||||||
|
|
||||||
let mut data = self.regular_socket_addr.ip().octets().to_vec();
|
let mut data = self.regular_socket_addr.ip().octets().to_vec();
|
||||||
|
|
|
||||||
1165
src/prudp/socket.rs
1165
src/prudp/socket.rs
File diff suppressed because it is too large
Load diff
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod message;
|
pub mod message;
|
||||||
pub mod structures;
|
pub mod structures;
|
||||||
pub mod response;
|
pub mod response;
|
||||||
|
pub mod protocols;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
17
src/rmc/protocols/mod.rs
Normal file
17
src/rmc/protocols/mod.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
use crate::prudp::socket::ExternalConnection;
|
||||||
|
use crate::rmc::structures::connection_data::ConnectionData;
|
||||||
|
|
||||||
|
pub trait RmcCallable{
|
||||||
|
fn rmc_call(protocol_id: u8, method_id: u8, rest: Vec<u8>);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocalRmcObjectWrapper<T: RmcCallable>(T);
|
||||||
|
impl<T: RmcCallable> LocalRmcObjectWrapper<T>{
|
||||||
|
pub fn new(object: T, conn: ExternalConnection) -> Self{
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -6,8 +6,10 @@ use crate::prudp::packet::{PRUDPPacket};
|
||||||
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
||||||
use crate::prudp::packet::PacketOption::FragmentId;
|
use crate::prudp::packet::PacketOption::FragmentId;
|
||||||
use crate::prudp::packet::types::DATA;
|
use crate::prudp::packet::types::DATA;
|
||||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
use crate::prudp::socket::ExternalConnection;
|
||||||
use crate::rmc::structures::qresult::ERROR_MASK;
|
use crate::rmc::structures::qresult::ERROR_MASK;
|
||||||
|
use crate::web::DirectionalData::{Incoming, Outgoing};
|
||||||
|
use crate::web::WEB_DATA;
|
||||||
|
|
||||||
pub enum RMCResponseResult {
|
pub enum RMCResponseResult {
|
||||||
Success{
|
Success{
|
||||||
|
|
@ -76,33 +78,8 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re
|
||||||
|
|
||||||
Ok(data_out)
|
Ok(data_out)
|
||||||
}
|
}
|
||||||
pub async fn send_response(original_packet: &PRUDPPacket, socket: &SocketData, connection: &mut ConnectionData, rmcresponse: RMCResponse){
|
pub async fn send_response(original_packet: &PRUDPPacket, connection: &mut ExternalConnection, rmcresponse: RMCResponse){
|
||||||
|
connection.send(rmcresponse.to_data()).await;
|
||||||
let ConnectionData{
|
|
||||||
active_connection_data,
|
|
||||||
..
|
|
||||||
} = connection;
|
|
||||||
|
|
||||||
let Some(active_connection) = active_connection_data else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut packet = original_packet.base_response_packet();
|
|
||||||
|
|
||||||
|
|
||||||
packet.header.types_and_flags.set_types(DATA);
|
|
||||||
packet.header.types_and_flags.set_flag((original_packet.header.types_and_flags.get_flags() & RELIABLE) | NEED_ACK);
|
|
||||||
|
|
||||||
//packet.header.session_id = active_connection.server_session_id;
|
|
||||||
packet.header.substream_id = 0;
|
|
||||||
|
|
||||||
packet.options.push(FragmentId(0));
|
|
||||||
|
|
||||||
packet.payload = rmcresponse.to_data();
|
|
||||||
|
|
||||||
//tokio::time::sleep(Duration::from_millis(500)).await;
|
|
||||||
|
|
||||||
connection.finish_and_send_packet_to(socket, packet).await;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//taken from kinnays error list directly
|
//taken from kinnays error list directly
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ pub mod qbuffer;
|
||||||
pub mod primitives;
|
pub mod primitives;
|
||||||
pub mod matchmake;
|
pub mod matchmake;
|
||||||
pub mod variant;
|
pub mod variant;
|
||||||
|
mod ranking;
|
||||||
|
|
||||||
pub trait RmcSerialize: Sized{
|
pub trait RmcSerialize: Sized{
|
||||||
fn serialize(&self, writer: &mut dyn Write) -> Result<()>;
|
fn serialize(&self, writer: &mut dyn Write) -> Result<()>;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,30 @@
|
||||||
use std::io::Read;
|
use std::io::{Read, Write};
|
||||||
|
use bytemuck::bytes_of;
|
||||||
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||||
use crate::rmc::structures::Result;
|
use crate::rmc::structures::{Result, RmcSerialize};
|
||||||
pub fn read(reader: &mut impl Read) -> Result<Vec<u8>>{
|
use crate::rmc::structures::qresult::QResult;
|
||||||
let size: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
|
|
||||||
|
|
||||||
let mut vec = vec![0; size as usize];
|
|
||||||
|
|
||||||
reader.read_exact(&mut vec)?;
|
#[derive(Debug)]
|
||||||
|
pub struct QBuffer(pub Vec<u8>);
|
||||||
|
|
||||||
Ok(vec)
|
impl RmcSerialize for QBuffer{
|
||||||
|
fn serialize(&self, writer: &mut dyn Write) -> Result<()> {
|
||||||
|
let len_u16 = self.0.len() as u16;
|
||||||
|
|
||||||
|
writer.write(bytes_of(&len_u16))?;
|
||||||
|
writer.write(&self.0)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(mut reader: &mut dyn Read) -> Result<Self> {
|
||||||
|
let size: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||||
|
|
||||||
|
let mut vec = vec![0; size as usize];
|
||||||
|
|
||||||
|
reader.read_exact(&mut vec)?;
|
||||||
|
|
||||||
|
Ok(Self(vec))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
69
src/rmc/structures/ranking.rs
Normal file
69
src/rmc/structures/ranking.rs
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
use macros::RmcSerialize;
|
||||||
|
use crate::rmc::structures::qbuffer::QBuffer;
|
||||||
|
|
||||||
|
#[derive(RmcSerialize, Debug)]
|
||||||
|
#[rmc_struct(0)]
|
||||||
|
struct UploadCompetitionData{
|
||||||
|
winning_team/*?*/: u32,
|
||||||
|
splatfest_id/*?*/: u32,
|
||||||
|
unk_2/*?*/: u32,
|
||||||
|
unk_3: u32,
|
||||||
|
team_id_1: u8,
|
||||||
|
team_id_2: u8,
|
||||||
|
unk_5: u32,
|
||||||
|
player_data/*?*/: QBuffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Pod, Zeroable)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct UserData{
|
||||||
|
name: [u16; 0x10],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test{
|
||||||
|
use std::io::Cursor;
|
||||||
|
use bytemuck::from_bytes;
|
||||||
|
use tokio::io::AsyncReadExt;
|
||||||
|
use crate::rmc::structures::ranking::{UploadCompetitionData, UserData};
|
||||||
|
use crate::rmc::structures::RmcSerialize;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
let data: [u8; 0xBD] = [
|
||||||
|
0x00, 0xB8, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFC, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||||
|
0x00, 0x1F, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00, 0x00, 0x49, 0x00,
|
||||||
|
0x7A, 0x00, 0x7A, 0x00, 0x79, 0x00, 0x53, 0x00, 0x50, 0x00, 0x46, 0x00, 0x4E, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x03, 0xF2, 0x00, 0x00, 0x00,
|
||||||
|
0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x1F, 0x5E, 0x00, 0x00, 0x00,
|
||||||
|
0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x0C, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x90, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x0A, 0x00, 0x00, 0x14, 0x87, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
||||||
|
0x02, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x00, 0x00,
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut cursor = Cursor::new(data);
|
||||||
|
|
||||||
|
let data = UploadCompetitionData::deserialize(&mut cursor).expect("unable to deserialize data");
|
||||||
|
|
||||||
|
let user_data: &UserData = from_bytes(&data.player_data.0[..size_of::<UserData>()]);
|
||||||
|
|
||||||
|
let pos = user_data.name.iter()
|
||||||
|
.position(|v| *v == 0x0000)
|
||||||
|
.unwrap_or(0x10);
|
||||||
|
|
||||||
|
let mut name = user_data.name[0..pos].to_vec();
|
||||||
|
|
||||||
|
name.iter_mut().for_each(|v| *v = v.swap_bytes());
|
||||||
|
|
||||||
|
let name = String::from_utf16(&name).expect("unable to get name");
|
||||||
|
|
||||||
|
println!("{:?}", name);
|
||||||
|
|
||||||
|
assert!(u8::deserialize(&mut cursor).is_err())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -36,3 +36,4 @@ impl RmcSerialize for &str{
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
37
src/web/mod.rs
Normal file
37
src/web/mod.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
use std::net::SocketAddrV4;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use rocket::{get, routes, Rocket};
|
||||||
|
use rocket::serde::json::Json;
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
|
use serde::Serialize;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
async fn server_data() -> Json<WebData> {
|
||||||
|
Json(WEB_DATA.lock().await.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start_web() -> JoinHandle<()>{
|
||||||
|
tokio::spawn(async{
|
||||||
|
rocket::build()
|
||||||
|
.mount("/",routes![server_data])
|
||||||
|
.launch().await
|
||||||
|
.expect("unable to start webserver");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
#[derive(Serialize, Clone)]
|
||||||
|
pub enum DirectionalData{
|
||||||
|
Incoming(String),
|
||||||
|
Outgoing(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Default, Clone)]
|
||||||
|
pub struct WebData{
|
||||||
|
pub data: Vec<(SocketAddrV4, DirectionalData)>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static WEB_DATA: Lazy<Mutex<WebData>> = Lazy::new(|| Mutex::new(
|
||||||
|
WebData{
|
||||||
|
data: Vec::new(),
|
||||||
|
}
|
||||||
|
));
|
||||||
Loading…
Add table
Add a link
Reference in a new issue