feat(matchmake): add create_matchmake_session_with_param and change some/add other stuff
This commit is contained in:
parent
296bb6df32
commit
c6b83b3ad9
9 changed files with 220 additions and 36 deletions
|
|
@ -25,7 +25,7 @@ pub fn derive_key(pid: u32, password: [u8; 16]) -> [u8; 16]{
|
|||
|
||||
key
|
||||
}
|
||||
#[derive(Pod, Zeroable, Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Pod, Zeroable, Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
#[repr(transparent)]
|
||||
pub struct KerberosDateTime(pub u64);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
use std::collections::{BTreeMap};
|
||||
use std::sync::Arc;
|
||||
use log::error;
|
||||
use tokio::sync::Mutex;
|
||||
use rand::random;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use crate::kerberos::KerberosDateTime;
|
||||
use crate::protocols::notification::Notification;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::structures::matchmake::MatchmakeSession;
|
||||
use crate::prudp::socket::{ActiveConnectionData, ConnectionData, SocketData};
|
||||
use crate::rmc::structures::matchmake::{Gathering, MatchmakeParam, MatchmakeSession};
|
||||
use crate::rmc::structures::variant::Variant;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct ExtendedMatchmakeSession{
|
||||
pub session: MatchmakeSession,
|
||||
pub connected_players: Vec<Arc<Mutex<ConnectionData>>>,
|
||||
|
|
@ -16,22 +20,75 @@ pub struct MatchmakeData{
|
|||
}
|
||||
|
||||
impl ExtendedMatchmakeSession{
|
||||
pub async fn from_matchmake_session(session: MatchmakeSession, host: &Mutex<ConnectionData>) -> Self{
|
||||
let host = host.lock().await;
|
||||
|
||||
let ConnectionData{
|
||||
active_connection_data,
|
||||
..
|
||||
} = &*host;
|
||||
|
||||
let Some(active_connection_data) = active_connection_data else{
|
||||
return Default::default();
|
||||
};
|
||||
|
||||
let ActiveConnectionData{
|
||||
active_secure_connection_data,
|
||||
..
|
||||
} = active_connection_data;
|
||||
|
||||
let Some(active_secure_connection_data) = active_secure_connection_data else{
|
||||
return Default::default();
|
||||
};
|
||||
|
||||
|
||||
let mm_session = MatchmakeSession{
|
||||
gathering: Gathering{
|
||||
self_gid: random(),
|
||||
owner_pid: active_secure_connection_data.pid,
|
||||
host_pid: active_secure_connection_data.pid,
|
||||
..session.gathering.clone()
|
||||
},
|
||||
datetime: KerberosDateTime::now(),
|
||||
session_key: (0..32).map(|_| random()).collect(),
|
||||
matchmake_param: MatchmakeParam{
|
||||
params: vec![
|
||||
("@SR".to_owned(), Variant::Bool(true)),
|
||||
("@GIR".to_owned(), Variant::SInt64(3))
|
||||
]
|
||||
},
|
||||
..session
|
||||
};
|
||||
|
||||
Self{
|
||||
session: mm_session,
|
||||
connected_players: Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn add_player(&mut self, socket: &SocketData, conn: Arc<Mutex<ConnectionData>>, join_msg: String) {
|
||||
let Some(pid) = conn.lock().await.active_connection_data.as_ref()
|
||||
let locked = conn.lock().await;
|
||||
|
||||
let Some(joining_pid) = locked.active_connection_data.as_ref()
|
||||
.map(|c|
|
||||
c.active_secure_connection_data.as_ref()
|
||||
.map(|c| c.pid
|
||||
)
|
||||
.map(|c| c.pid)
|
||||
).flatten() else {
|
||||
error!("tried to add player without secure connection");
|
||||
return
|
||||
};
|
||||
|
||||
drop(locked);
|
||||
|
||||
self.connected_players.push(conn);
|
||||
self.session.participation_count = self.connected_players.len() as u32;
|
||||
|
||||
|
||||
for conn in &self.connected_players{
|
||||
let Some(other_pid) = conn.lock().await.active_connection_data.as_ref()
|
||||
for other_connection in &self.connected_players{
|
||||
let mut conn = other_connection.lock().await;
|
||||
|
||||
|
||||
let Some(other_pid) = conn.active_connection_data.as_ref()
|
||||
.map(|c|
|
||||
c.active_secure_connection_data.as_ref()
|
||||
.map(|c| c.pid
|
||||
|
|
@ -41,22 +98,38 @@ impl ExtendedMatchmakeSession{
|
|||
return
|
||||
};
|
||||
|
||||
let mut conn = conn.lock().await;
|
||||
/*if other_pid == self.session.gathering.owner_pid &&
|
||||
joining_pid == self.session.gathering.owner_pid{
|
||||
continue;
|
||||
}*/
|
||||
|
||||
conn.send_notification(socket, Notification{
|
||||
pid_source: pid,
|
||||
pid_source: joining_pid,
|
||||
notif_type: 3001,
|
||||
param_1: self.session.gathering.self_gid,
|
||||
param_2: other_pid,
|
||||
str_param: join_msg.clone(),
|
||||
param_3: self.session.participation_count
|
||||
}).await;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
pub async fn add_matchmake_session(mm_data: Arc<RwLock<MatchmakeData>>,session: ExtendedMatchmakeSession) -> Arc<Mutex<ExtendedMatchmakeSession>> {
|
||||
let gid = session.session.gathering.self_gid;
|
||||
|
||||
let mut mm_data = mm_data.write().await;
|
||||
|
||||
let session = Arc::new(Mutex::new(session));
|
||||
|
||||
mm_data.matchmake_sessions.insert(gid, session.clone());
|
||||
|
||||
session
|
||||
}
|
||||
|
||||
impl MatchmakeData {
|
||||
|
||||
|
||||
|
||||
pub async fn try_find_session_with_criteria(&self, ) -> Option<Arc<Mutex<ExtendedMatchmakeSession>>>{
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
use std::io::Cursor;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use chrono::SecondsFormat::Millis;
|
||||
use log::info;
|
||||
use rand::random;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use tokio::time::sleep;
|
||||
use crate::protocols::matchmake_common::{ExtendedMatchmakeSession, MatchmakeData};
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::structures::matchmake::{AutoMatchmakeParam};
|
||||
use crate::rmc::structures::matchmake::{AutoMatchmakeParam, MatchmakeSession};
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
|
||||
|
|
@ -18,7 +22,7 @@ pub async fn auto_matchmake_with_param_postpone(
|
|||
mm_data: Arc<RwLock<MatchmakeData>>,
|
||||
auto_matchmake_param: AutoMatchmakeParam
|
||||
) -> RMCResponseResult{
|
||||
println!("auto_matchmake_with_param_postpone: {:?}", auto_matchmake_param);
|
||||
//println!("auto_matchmake_with_param_postpone: {:?}", auto_matchmake_param);
|
||||
let locked_conn = conn.lock().await;
|
||||
let Some(secure_conn) =
|
||||
locked_conn.active_connection_data.as_ref().map(|a| a.active_secure_connection_data.as_ref()).flatten() else {
|
||||
|
|
@ -38,35 +42,41 @@ pub async fn auto_matchmake_with_param_postpone(
|
|||
// up anything else unnescesarily
|
||||
drop(mm_data_read);
|
||||
|
||||
let gid = random();
|
||||
|
||||
let mut matchmake_session = auto_matchmake_param.matchmake_session.clone();
|
||||
matchmake_session.gathering.self_gid = gid;
|
||||
matchmake_session.gathering.host_pid = pid;
|
||||
matchmake_session.gathering.owner_pid = pid;
|
||||
|
||||
let session =
|
||||
ExtendedMatchmakeSession::from_matchmake_session(auto_matchmake_param.matchmake_session, &conn).await;
|
||||
|
||||
let gid = session.session.gathering.self_gid;
|
||||
|
||||
let mut mm_data = mm_data.write().await;
|
||||
|
||||
let session = Arc::new(Mutex::new(ExtendedMatchmakeSession{
|
||||
session: matchmake_session.clone(),
|
||||
connected_players: Vec::new()
|
||||
}));
|
||||
let session = Arc::new(Mutex::new(session));
|
||||
|
||||
mm_data.matchmake_sessions.insert(gid, session.clone());
|
||||
|
||||
session
|
||||
};
|
||||
|
||||
let mut session = session.lock().await;
|
||||
let mut locked_session = session.lock().await;
|
||||
|
||||
//todo: refactor so that this works
|
||||
session.add_player(socket, conn.clone(), auto_matchmake_param.join_message).await;
|
||||
{
|
||||
let session = session.clone();
|
||||
let socket = socket.clone();
|
||||
let connection = conn.clone();
|
||||
let join_msg = auto_matchmake_param.join_message.clone();
|
||||
tokio::spawn(async move{
|
||||
sleep(Duration::from_millis(500)).await;
|
||||
println!("adding player");
|
||||
let mut session = session.lock().await;
|
||||
session.add_player(&socket, connection, join_msg).await;
|
||||
});
|
||||
}
|
||||
|
||||
info!("new session: {:?}", locked_session);
|
||||
|
||||
let mut response = Vec::new();
|
||||
|
||||
session.session.serialize(&mut response).expect("unable to serialize matchmake session");
|
||||
locked_session.session.serialize(&mut response).expect("unable to serialize matchmake session");
|
||||
|
||||
rmcmessage.success_with_data(response)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
use std::io::Cursor;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
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::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::structures::matchmake::{AutoMatchmakeParam, CreateMatchmakeSessionParam};
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
pub async fn create_matchmake_session_with_param(
|
||||
rmcmessage: &RMCMessage,
|
||||
conn: &Arc<Mutex<ConnectionData>>,
|
||||
socket: &Arc<SocketData>,
|
||||
mm_data: Arc<RwLock<MatchmakeData>>,
|
||||
create_matchmake_session: CreateMatchmakeSessionParam
|
||||
) -> RMCResponseResult {
|
||||
let locked_conn = conn.lock().await;
|
||||
let Some(secure_conn) =
|
||||
locked_conn.active_connection_data.as_ref().map(|a| a.active_secure_connection_data.as_ref()).flatten() else {
|
||||
return rmcmessage.error_result_with_code(ErrorCode::Core_Exception);
|
||||
};
|
||||
|
||||
println!("{:?}", create_matchmake_session);
|
||||
|
||||
let pid = secure_conn.pid;
|
||||
|
||||
let mut session =
|
||||
ExtendedMatchmakeSession::from_matchmake_session(create_matchmake_session.matchmake_session, &conn).await;
|
||||
|
||||
session.session.participation_count = create_matchmake_session.participation_count as u32;
|
||||
|
||||
let session = add_matchmake_session(mm_data, session).await;
|
||||
|
||||
let mut session = session.lock().await;
|
||||
|
||||
session.add_player(&socket, conn.clone(), create_matchmake_session.join_message).await;
|
||||
|
||||
let mut response = Vec::new();
|
||||
|
||||
session.session.serialize(&mut response).expect("unable to serialize session");
|
||||
|
||||
rmcmessage.success_with_data(response)
|
||||
}
|
||||
|
||||
pub async fn create_matchmake_session_with_param_raw_params(
|
||||
rmcmessage: &RMCMessage,
|
||||
socket: &Arc<SocketData>,
|
||||
connection_data: &Arc<Mutex<ConnectionData>>,
|
||||
data: Arc<RwLock<MatchmakeData>>
|
||||
) -> RMCResponseResult{
|
||||
let mut reader = Cursor::new(&rmcmessage.rest_of_data);
|
||||
|
||||
let Ok(matchmake_param) = CreateMatchmakeSessionParam::deserialize(&mut reader) else {
|
||||
return rmcmessage.error_result_with_code(ErrorCode::Core_InvalidArgument);
|
||||
};
|
||||
|
||||
|
||||
|
||||
create_matchmake_session_with_param(rmcmessage, connection_data, socket, data, matchmake_param).await
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
mod method_get_playing_session;
|
||||
mod method_auto_matchmake_with_param_postpone;
|
||||
mod method_create_matchmake_session_with_param;
|
||||
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{RwLock};
|
||||
|
|
@ -7,10 +8,12 @@ use crate::define_protocol;
|
|||
use crate::protocols::matchmake_common::MatchmakeData;
|
||||
use method_get_playing_session::get_playing_session_raw_params;
|
||||
use method_auto_matchmake_with_param_postpone::auto_matchmake_with_param_postpone_raw_params;
|
||||
use crate::protocols::matchmake_extension::method_create_matchmake_session_with_param::create_matchmake_session_with_param_raw_params;
|
||||
|
||||
define_protocol!{
|
||||
109(matchmake_data: Arc<RwLock<MatchmakeData>>) => {
|
||||
16 => get_playing_session_raw_params,
|
||||
38 => create_matchmake_session_with_param_raw_params,
|
||||
40 => auto_matchmake_with_param_postpone_raw_params
|
||||
}
|
||||
}
|
||||
|
|
@ -15,17 +15,19 @@ pub struct Notification{
|
|||
pub param_1: u32,
|
||||
pub param_2: u32,
|
||||
pub str_param: String,
|
||||
pub param_3: u32,
|
||||
}
|
||||
|
||||
impl ConnectionData{
|
||||
pub async fn send_notification(&mut self, socket: &SocketData, notif: Notification){
|
||||
println!("sending notification");
|
||||
|
||||
let mut data = Vec::new();
|
||||
|
||||
notif.serialize(&mut data).expect("unable to write");
|
||||
|
||||
let message = RMCMessage{
|
||||
protocol_id: 0xE,
|
||||
protocol_id: 14,
|
||||
method_id: 1,
|
||||
call_id: random(),
|
||||
rest_of_data: data
|
||||
|
|
@ -43,6 +45,8 @@ impl ConnectionData{
|
|||
packet_signature: [0;16]
|
||||
};
|
||||
|
||||
|
||||
|
||||
self.finish_and_send_packet_to(socket, prudp_packet).await;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
use log::info;
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::future::Future;
|
||||
use std::ops::Deref;
|
||||
use std::pin::Pin;
|
||||
|
|
@ -29,6 +31,7 @@ pub struct Socket {
|
|||
type OnConnectHandlerFn = Box<dyn Fn(PRUDPPacket, u8) -> Pin<Box<dyn Future<Output=Option<(Vec<u8>, Vec<EncryptionPair>, Option<ActiveSecureConnectionData>)>> + Send>> + Send + Sync>;
|
||||
type OnDataHandlerFn = Box<dyn Fn(PRUDPPacket, Arc<SocketData>, Arc<Mutex<ConnectionData>>) -> Pin<Box<dyn Future<Output=()> + Send>> + Send + Sync>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ActiveSecureConnectionData {
|
||||
pub(crate) pid: u32,
|
||||
pub(crate) session_key: [u8; 32],
|
||||
|
|
@ -49,6 +52,13 @@ pub struct EncryptionPair{
|
|||
pub recv: Box<dyn StreamCipher + Send>
|
||||
}
|
||||
|
||||
impl Debug for EncryptionPair{
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Stubbed")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ActiveConnectionData {
|
||||
pub reliable_client_counter: u16,
|
||||
pub reliable_server_counter: u16,
|
||||
|
|
@ -60,6 +70,7 @@ pub struct ActiveConnectionData {
|
|||
}
|
||||
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConnectionData {
|
||||
pub sock_addr: PRUDPSockAddr,
|
||||
pub id: u64,
|
||||
|
|
@ -174,8 +185,8 @@ impl SocketData {
|
|||
// dont keep holding the connections list unnescesarily
|
||||
drop(connections);
|
||||
|
||||
let mutual_exclusion_packet_handeling_mtx = conn.1.lock().await;
|
||||
let mut connection = conn.0.lock().await;
|
||||
//let _mutual_exclusion_packet_handeling_mtx = conn.1.lock().await;
|
||||
|
||||
if (packet.header.types_and_flags.get_flags() & ACK) != 0 {
|
||||
//todo: handle acknowledgements and resending packets propperly
|
||||
|
|
@ -387,6 +398,8 @@ impl SocketData {
|
|||
..
|
||||
} = &mut *connection;
|
||||
|
||||
info!("got ping");
|
||||
|
||||
if (packet.header.types_and_flags.get_flags() & NEED_ACK) != 0 {
|
||||
let Some(active_connection) = active_connection_data.as_mut() else {
|
||||
error!("got data packet on non active connection!");
|
||||
|
|
@ -438,6 +451,8 @@ impl SocketData {
|
|||
}
|
||||
_ => error!("unimplemented packet type: {}", packet.header.types_and_flags.get_types())
|
||||
}
|
||||
|
||||
drop(mutual_exclusion_packet_handeling_mtx)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -459,6 +474,10 @@ impl ConnectionData{
|
|||
encryption.apply_keystream(&mut packet.payload);
|
||||
}
|
||||
|
||||
packet.header.session_id = self.active_connection_data.as_ref().map(|v| v.server_session_id).unwrap_or_default();
|
||||
|
||||
|
||||
|
||||
packet.header.source_port = socket.virtual_port;
|
||||
packet.header.destination_port = self.sock_addr.virtual_port;
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use crate::kerberos::KerberosDateTime;
|
|||
use crate::rmc::structures::variant::Variant;
|
||||
|
||||
// rmc structure
|
||||
#[derive(RmcSerialize, Debug, Clone)]
|
||||
#[derive(RmcSerialize, Debug, Clone, Default)]
|
||||
#[rmc_struct(0)]
|
||||
pub struct Gathering {
|
||||
pub self_gid: u32,
|
||||
|
|
@ -19,7 +19,7 @@ pub struct Gathering {
|
|||
}
|
||||
|
||||
// rmc structure
|
||||
#[derive(RmcSerialize, Debug, Clone)]
|
||||
#[derive(RmcSerialize, Debug, Clone, Default)]
|
||||
#[rmc_struct(0)]
|
||||
pub struct MatchmakeParam {
|
||||
pub params: Vec<(String, Variant)>,
|
||||
|
|
@ -27,7 +27,7 @@ pub struct MatchmakeParam {
|
|||
|
||||
|
||||
// rmc structure
|
||||
#[derive(RmcSerialize, Debug, Clone)]
|
||||
#[derive(RmcSerialize, Debug, Clone, Default)]
|
||||
#[rmc_struct(3)]
|
||||
pub struct MatchmakeSession {
|
||||
//inherits from
|
||||
|
|
@ -81,4 +81,16 @@ pub struct AutoMatchmakeParam {
|
|||
pub participation_count: u16,
|
||||
pub search_criteria: Vec<MatchmakeSessionSearchCriteria>,
|
||||
pub target_gids: Vec<u32>,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(RmcSerialize, Debug, Clone)]
|
||||
#[rmc_struct(0)]
|
||||
pub struct CreateMatchmakeSessionParam {
|
||||
pub matchmake_session: MatchmakeSession,
|
||||
pub additional_participants: Vec<u32>,
|
||||
pub gid_for_participation_check: u32,
|
||||
pub create_matchmake_session_option: u32,
|
||||
pub join_message: String,
|
||||
pub participation_count: u16,
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ use crate::kerberos::KerberosDateTime;
|
|||
use crate::rmc::structures;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub enum Variant{
|
||||
#[default]
|
||||
None,
|
||||
SInt64(i64),
|
||||
Double(f64),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue