rust-nex/src/rmc/protocols/mod.rs

104 lines
2.9 KiB
Rust
Raw Normal View History

2025-03-23 10:54:01 +01:00
#![allow(async_fn_in_trait)]
pub mod auth;
use macros::method_id;
use std::collections::HashMap;
use std::ops::Add;
use std::sync::{Arc, Condvar};
use std::time::Duration;
use async_trait::async_trait;
use chrono::TimeDelta;
use macros::{rmc_proto, rmc_struct};
use paste::paste;
use tokio::sync::{Mutex, Notify};
use tokio::time::{sleep_until, Instant};
use crate::prudp::socket::{ExternalConnection, SendingConnection};
2025-03-23 10:54:01 +01:00
use crate::rmc::response::ErrorCode;
use crate::rmc::structures::connection_data::ConnectionData;
2025-03-23 10:54:01 +01:00
use crate::rmc::structures::Error;
2025-03-08 00:56:44 +01:00
use crate::rmc::structures::matchmake::AutoMatchmakeParam;
2025-03-08 00:56:44 +01:00
pub struct RmcConnection(pub SendingConnection, pub RmcResponseReceiver);
2025-03-23 10:54:01 +01:00
pub struct RmcResponseReceiver(Notify, Mutex<HashMap<(u32), Vec<u8>>>);
impl RmcResponseReceiver{
// returns none if timed out
2025-03-23 10:54:01 +01:00
pub async fn get_response_data(&self, call_id: u32) -> Option<Vec<u8>>{
let mut end_wait_time = Instant::now();
end_wait_time += Duration::from_secs(5);
let sleep_fut = sleep_until(end_wait_time);
tokio::pin!(sleep_fut);
loop {
let mut locked = self.1.lock().await;
2025-03-23 10:54:01 +01:00
if let Some(v) = locked.remove(&call_id){
return Some(v);
}
2025-03-23 10:54:01 +01:00
drop(locked);
let notif_fut = self.0.notified();
tokio::select! {
_ = &mut sleep_fut => {
return None;
}
_ = notif_fut => {
continue;
}
}
}
}
}
2025-03-23 10:54:01 +01:00
pub trait HasRmcConnection{
fn get_response_receiver(&self) -> &RmcConnection;
}
2025-03-08 00:56:44 +01:00
pub trait RemoteObject{
fn new(conn: RmcConnection) -> Self;
}
impl RemoteObject for (){
fn new(_: RmcConnection) -> Self {}
}
2025-03-23 10:54:01 +01:00
pub trait RmcCallable{
2025-03-08 00:56:44 +01:00
//type Remote: RemoteObject;
//fn new_callable(remote: Self::Remote);
2025-03-23 10:54:01 +01:00
async fn rmc_call(&self, responder: &SendingConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec<u8>);
}
2025-03-08 00:56:44 +01:00
2025-03-23 10:54:01 +01:00
#[macro_export]
macro_rules! define_rmc_proto {
(proto $name:ident{
$($protocol:path),*
}) => {
2025-03-23 10:54:01 +01:00
paste::paste!{
2025-03-08 00:56:44 +01:00
trait [<Local $name>]: std::any::Any $( + [<Raw $protocol>] + $protocol)* {
2025-03-23 10:54:01 +01:00
async fn rmc_call(&self, remote_response_connection: &crate::prudp::socket::SendingConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec<u8>){
match protocol_id{
$(
2025-03-23 10:54:01 +01:00
[<Raw $protocol Info>]::PROTOCOL_ID => <Self as [<Raw $protocol>]>::rmc_call_proto(self, remote_response_connection, method_id, call_id, rest).await,
)*
v => log::error!("invalid protocol called on rmc object {}", v)
}
}
}
2025-03-23 10:54:01 +01:00
struct [<Remote $name>](crate::rmc::protocols::RmcConnection);
2025-03-08 00:56:44 +01:00
2025-03-23 10:54:01 +01:00
}
};
}