#![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}; use crate::rmc::response::ErrorCode; use crate::rmc::structures::connection_data::ConnectionData; use crate::rmc::structures::Error; use crate::rmc::structures::matchmake::AutoMatchmakeParam; pub struct RmcConnection(pub SendingConnection, pub RmcResponseReceiver); pub struct RmcResponseReceiver(Notify, Mutex>>); impl RmcResponseReceiver{ // returns none if timed out pub async fn get_response_data(&self, call_id: u32) -> Option>{ 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; if let Some(v) = locked.remove(&call_id){ return Some(v); } drop(locked); let notif_fut = self.0.notified(); tokio::select! { _ = &mut sleep_fut => { return None; } _ = notif_fut => { continue; } } } } } pub trait HasRmcConnection{ fn get_response_receiver(&self) -> &RmcConnection; } pub trait RemoteObject{ fn new(conn: RmcConnection) -> Self; } impl RemoteObject for (){ fn new(_: RmcConnection) -> Self {} } pub trait RmcCallable{ //type Remote: RemoteObject; //fn new_callable(remote: Self::Remote); async fn rmc_call(&self, responder: &SendingConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec); } #[macro_export] macro_rules! define_rmc_proto { (proto $name:ident{ $($protocol:path),* }) => { paste::paste!{ trait []: std::any::Any $( + [] + $protocol)* { async fn rmc_call(&self, remote_response_connection: &crate::prudp::socket::SendingConnection, protocol_id: u16, method_id: u32, call_id: u32, rest: Vec){ match protocol_id{ $( []::PROTOCOL_ID => ]>::rmc_call_proto(self, remote_response_connection, method_id, call_id, rest).await, )* v => log::error!("invalid protocol called on rmc object {}", v) } } } struct [](crate::rmc::protocols::RmcConnection); } }; }