feat(matchmake): a bunch of things
This commit is contained in:
parent
2443569861
commit
7d24a71f09
13 changed files with 220 additions and 30 deletions
|
|
@ -66,7 +66,7 @@ impl KerberosDateTime{
|
|||
|
||||
#[inline]
|
||||
pub fn get_month(&self) -> u8{
|
||||
((self.0 >> 22) & 0b111111) as u8
|
||||
((self.0 >> 22) & 0b1111) as u8
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -154,3 +154,17 @@ impl Ticket{
|
|||
data.into_boxed_slice()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test{
|
||||
use chrono::{Datelike, Utc};
|
||||
use crate::kerberos::KerberosDateTime;
|
||||
|
||||
#[test]
|
||||
fn kerberos_time_convert_test(){
|
||||
let time = KerberosDateTime(135904948834);
|
||||
|
||||
println!("{}", time.to_regular_time().to_rfc2822());
|
||||
}
|
||||
}
|
||||
|
|
@ -64,11 +64,9 @@ static OWN_IP_PRIVATE: Lazy<Ipv4Addr> = Lazy::new(||{
|
|||
.expect("no public ip specified")
|
||||
});
|
||||
|
||||
static OWN_IP_PUBLIC: Lazy<Ipv4Addr> = Lazy::new(||{
|
||||
static OWN_IP_PUBLIC: Lazy<String> = Lazy::new(||{
|
||||
env::var("SERVER_IP_PUBLIC")
|
||||
.ok()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(*OWN_IP_PRIVATE)
|
||||
.unwrap_or(OWN_IP_PRIVATE.to_string())
|
||||
});
|
||||
|
||||
static SECURE_STATION_URL: Lazy<String> = Lazy::new(||
|
||||
|
|
@ -194,7 +192,8 @@ async fn start_secure_server() -> SecureServer{
|
|||
Box::new(block_if_maintenance),
|
||||
Box::new(protocols::secure::bound_protocol()),
|
||||
Box::new(protocols::matchmake::bound_protocol(matchmake_data.clone())),
|
||||
Box::new(protocols::matchmake_extension::bound_protocol(matchmake_data))
|
||||
Box::new(protocols::matchmake_extension::bound_protocol(matchmake_data)),
|
||||
Box::new(protocols::nat_traversal::bound_protocol())
|
||||
]));
|
||||
|
||||
let socket =
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ impl ExtendedMatchmakeSession{
|
|||
("@GIR".to_owned(), Variant::SInt64(3))
|
||||
]
|
||||
},
|
||||
system_password_enabled: false,
|
||||
..session
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use std::io::Cursor;
|
||||
use std::sync::Arc;
|
||||
use log::info;
|
||||
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;
|
||||
|
|
@ -16,15 +17,6 @@ pub async fn create_matchmake_session_with_param(
|
|||
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;
|
||||
|
|
@ -37,8 +29,11 @@ pub async fn create_matchmake_session_with_param(
|
|||
|
||||
session.add_player(&socket, conn.clone(), create_matchmake_session.join_message).await;
|
||||
|
||||
println!("{:?}", session);
|
||||
|
||||
let mut response = Vec::new();
|
||||
|
||||
|
||||
session.session.serialize(&mut response).expect("unable to serialize session");
|
||||
|
||||
rmcmessage.success_with_data(response)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ pub mod matchmake_extension;
|
|||
pub mod matchmake_common;
|
||||
pub mod matchmake;
|
||||
mod notification;
|
||||
pub mod nat_traversal;
|
||||
|
||||
static IS_MAINTENANCE: Lazy<bool> = Lazy::new(|| {
|
||||
env::var("IS_MAINTENANCE")
|
||||
|
|
|
|||
27
src/protocols/nat_traversal/method_report_nat_properties.rs
Normal file
27
src/protocols/nat_traversal/method_report_nat_properties.rs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
use std::io::Cursor;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use crate::protocols::matchmake_common::MatchmakeData;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
use crate::rmc::structures::matchmake::CreateMatchmakeSessionParam;
|
||||
|
||||
pub async fn report_nat_properties(
|
||||
rmcmessage: &RMCMessage,
|
||||
socket: &Arc<SocketData>,
|
||||
connection_data: &Arc<Mutex<ConnectionData>>,
|
||||
) -> RMCResponseResult{
|
||||
rmcmessage.success_with_data(Vec::new())
|
||||
}
|
||||
|
||||
pub async fn report_nat_properties_raw_params(
|
||||
rmcmessage: &RMCMessage,
|
||||
socket: &Arc<SocketData>,
|
||||
connection_data: &Arc<Mutex<ConnectionData>>,
|
||||
_: ()
|
||||
) -> RMCResponseResult{
|
||||
let mut reader = Cursor::new(&rmcmessage.rest_of_data);
|
||||
|
||||
report_nat_properties(rmcmessage, socket, connection_data).await
|
||||
}
|
||||
10
src/protocols/nat_traversal/mod.rs
Normal file
10
src/protocols/nat_traversal/mod.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
mod method_report_nat_properties;
|
||||
|
||||
use crate::define_protocol;
|
||||
use crate::protocols::nat_traversal::method_report_nat_properties::report_nat_properties_raw_params;
|
||||
|
||||
define_protocol!{
|
||||
3() => {
|
||||
5 => report_nat_properties_raw_params
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
use macros::RmcSerialize;
|
||||
use rand::random;
|
||||
use crate::prudp::packet::{PRUDPHeader, PRUDPPacket, TypesFlags};
|
||||
use crate::prudp::packet::{PRUDPHeader, PRUDPPacket, PacketOption, TypesFlags};
|
||||
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
||||
use crate::prudp::packet::types::DATA;
|
||||
use crate::prudp::socket::{ConnectionData, SocketData};
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
#[derive(RmcSerialize)]
|
||||
#[derive(Debug, Eq, PartialEq, RmcSerialize)]
|
||||
#[rmc_struct(0)]
|
||||
pub struct Notification{
|
||||
pub pid_source: u32,
|
||||
|
|
@ -18,6 +18,7 @@ pub struct Notification{
|
|||
pub param_3: u32,
|
||||
}
|
||||
|
||||
|
||||
impl ConnectionData{
|
||||
pub async fn send_notification(&mut self, socket: &SocketData, notif: Notification){
|
||||
println!("sending notification");
|
||||
|
|
@ -33,20 +34,143 @@ impl ConnectionData{
|
|||
rest_of_data: data
|
||||
};
|
||||
|
||||
let prudp_packet = PRUDPPacket{
|
||||
|
||||
|
||||
let mut prudp_packet = PRUDPPacket{
|
||||
header: PRUDPHeader{
|
||||
types_and_flags: TypesFlags::default().types(DATA).flags(NEED_ACK | RELIABLE),
|
||||
source_port: socket.get_virual_port(),
|
||||
destination_port: self.sock_addr.virtual_port,
|
||||
..Default::default()
|
||||
},
|
||||
options: Vec::new(),
|
||||
options: vec![
|
||||
PacketOption::FragmentId(0),
|
||||
],
|
||||
payload: message.to_data(),
|
||||
packet_signature: [0;16]
|
||||
};
|
||||
|
||||
|
||||
|
||||
self.finish_and_send_packet_to(socket, prudp_packet).await;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test{
|
||||
use std::io::Cursor;
|
||||
use rand::random;
|
||||
use crate::protocols::notification::Notification;
|
||||
use crate::prudp::packet::{PRUDPHeader, PRUDPPacket, PacketOption, TypesFlags};
|
||||
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
||||
use crate::prudp::packet::types::DATA;
|
||||
use crate::rmc::message::RMCMessage;
|
||||
use crate::rmc::structures::RmcSerialize;
|
||||
|
||||
#[test]
|
||||
fn test(){
|
||||
let data = hex::decode("ead001032900a1af62000000000000000000000000000000000000000000020100250000000e57238a6601000000001700000051b39957b90b00003661636851b3995701000001000000").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]
|
||||
fn test2(){
|
||||
|
||||
let data = hex::decode("250000000e57b6801001000000001700000051b39957b90b0000248a5a9851b3995701000001000000").unwrap();
|
||||
//let packet = PRUDPPacket::new(&mut Cursor::new(data)).expect("invalid packet");
|
||||
|
||||
//println!("{:?}", packet);
|
||||
|
||||
let rmc = RMCMessage::new(&mut Cursor::new(data)).expect("invalid rmc message");
|
||||
|
||||
println!("{:?}", rmc);
|
||||
|
||||
let notif = Notification::deserialize(&mut Cursor::new(rmc.rest_of_data)).expect("invalid notification");
|
||||
|
||||
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]
|
||||
fn test_rmc_serialization(){
|
||||
let notif = Notification{
|
||||
pid_source: random(),
|
||||
notif_type: random(),
|
||||
param_1: random(),
|
||||
param_2: random(),
|
||||
str_param: "".to_string(),
|
||||
param_3: random(),
|
||||
};
|
||||
|
||||
let mut notif_data = Vec::new();
|
||||
|
||||
notif.serialize(&mut notif_data).unwrap();
|
||||
|
||||
let message = RMCMessage{
|
||||
protocol_id: 14,
|
||||
method_id: 1,
|
||||
call_id: random(),
|
||||
rest_of_data: notif_data
|
||||
};
|
||||
|
||||
let mut prudp_packet = PRUDPPacket{
|
||||
header: PRUDPHeader{
|
||||
..Default::default()
|
||||
},
|
||||
options: vec![
|
||||
PacketOption::FragmentId(0),
|
||||
],
|
||||
payload: message.to_data(),
|
||||
packet_signature: [0;16]
|
||||
};
|
||||
|
||||
prudp_packet.set_sizes();
|
||||
|
||||
|
||||
|
||||
let mut packet_data: Vec<u8> = Vec::new();
|
||||
|
||||
prudp_packet.write_to(&mut packet_data).expect("what");
|
||||
|
||||
let packet_deserialized = PRUDPPacket::new(&mut Cursor::new(packet_data)).unwrap();
|
||||
|
||||
assert_eq!(prudp_packet, packet_deserialized);
|
||||
|
||||
let message_deserialized = RMCMessage::new(&mut Cursor::new(packet_deserialized.payload)).unwrap();
|
||||
|
||||
assert_eq!(message, message_deserialized);
|
||||
|
||||
let notification_deserialized = Notification::deserialize(&mut Cursor::new(message_deserialized.rest_of_data)).unwrap();
|
||||
|
||||
assert_eq!(notification_deserialized, notif);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,9 @@ impl RMCProtocolServer{
|
|||
|
||||
for proto in &self.0 {
|
||||
if let Some(response) = proto(&rmc, &socket, &connection).await {
|
||||
|
||||
if matches!(response.response_result, RMCResponseResult::Error {..}){
|
||||
error!("an rmc error occurred")
|
||||
}
|
||||
let mut locked = connection.lock().await;
|
||||
send_response(&packet, &socket, &mut locked, response).await;
|
||||
drop(locked);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ pub enum Error {
|
|||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Copy, Clone, Pod, Zeroable, SwapEndian, Default)]
|
||||
#[derive(Copy, Clone, Pod, Zeroable, SwapEndian, Default, Eq, PartialEq)]
|
||||
pub struct TypesFlags(u16);
|
||||
|
||||
impl TypesFlags {
|
||||
|
|
@ -141,7 +141,7 @@ impl Debug for VirtualPort {
|
|||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone, Pod, Zeroable, SwapEndian)]
|
||||
#[derive(Debug, Copy, Clone, Pod, Zeroable, SwapEndian, Eq, PartialEq)]
|
||||
pub struct PRUDPHeader {
|
||||
pub magic: [u8; 2],
|
||||
pub version: u8,
|
||||
|
|
@ -173,7 +173,7 @@ impl Default for PRUDPHeader{
|
|||
}
|
||||
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum PacketOption{
|
||||
SupportedFunctions(u32),
|
||||
ConnectionSignature([u8; 16]),
|
||||
|
|
@ -236,7 +236,7 @@ impl PacketOption{
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub struct PRUDPPacket {
|
||||
pub header: PRUDPHeader,
|
||||
pub packet_signature: [u8; 16],
|
||||
|
|
@ -290,9 +290,12 @@ impl PRUDPPacket {
|
|||
|
||||
|
||||
let packet_signature: [u8; 16] = reader.read_struct(IS_BIG_ENDIAN)?;
|
||||
//let packet_signature: [u8; 16] = [0; 16];
|
||||
|
||||
assert_eq!(reader.stream_position().ok(), Some(14 + 16));
|
||||
|
||||
|
||||
|
||||
let mut packet_specific_buffer = vec![0u8; header.packet_specific_size as usize];
|
||||
|
||||
reader.read_exact(&mut packet_specific_buffer)?;
|
||||
|
|
@ -474,6 +477,8 @@ impl PRUDPPacket {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
|
||||
use crate::prudp::packet::types::DATA;
|
||||
use super::{OptionId, PacketOption, PRUDPHeader, TypesFlags, VirtualPort};
|
||||
#[test]
|
||||
fn size_test() {
|
||||
|
|
@ -523,4 +528,13 @@ mod test {
|
|||
|
||||
let header_data: [u8; 8] = bytes.try_into().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_types_flags(){
|
||||
let types = TypesFlags::default().types(DATA).flags(NEED_ACK | RELIABLE);
|
||||
|
||||
assert_ne!((types.0 >> 4) & NEED_ACK, 0);
|
||||
assert_ne!((types.0 >> 4) & RELIABLE, 0);
|
||||
assert_ne!((types.0 & 0xFF) as u8 & DATA, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -195,7 +195,7 @@ impl SocketData {
|
|||
}
|
||||
|
||||
if (packet.header.types_and_flags.get_flags() & MULTI_ACK) != 0 {
|
||||
println!("got ack");
|
||||
println!("got multi ack");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -458,6 +458,8 @@ impl SocketData {
|
|||
|
||||
impl ConnectionData{
|
||||
pub async fn finish_and_send_packet_to(&mut self, socket: &SocketData, mut packet: PRUDPPacket){
|
||||
|
||||
|
||||
if (packet.header.types_and_flags.get_flags() & RELIABLE) != 0{
|
||||
let Some(active_connection) = self.active_connection_data.as_mut() else {
|
||||
error!("tried to send a secure packet to an inactive connection");
|
||||
|
|
@ -491,7 +493,6 @@ impl ConnectionData{
|
|||
|
||||
|
||||
packet.calculate_and_assign_signature(socket.access_key, potential_session_key, Some(self.server_signature));
|
||||
|
||||
let mut vec = Vec::new();
|
||||
|
||||
packet.write_to(&mut vec).expect("somehow failed to convert backet to bytes");
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use log::error;
|
|||
use crate::endianness::{IS_BIG_ENDIAN, ReadExtensions};
|
||||
use crate::rmc::response::{ErrorCode, RMCResponseResult};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct RMCMessage{
|
||||
pub protocol_id: u16,
|
||||
pub call_id: u32,
|
||||
|
|
@ -60,13 +60,15 @@ impl RMCMessage{
|
|||
|
||||
output.write_all(bytes_of(&size)).expect("unable to write size");
|
||||
|
||||
let proto_id = self.protocol_id as u8;
|
||||
let proto_id = self.protocol_id as u8 | 0x80;
|
||||
|
||||
output.write_all(bytes_of(&proto_id)).expect("unable to write size");
|
||||
|
||||
output.write_all(bytes_of(&self.call_id)).expect("unable to write size");
|
||||
output.write_all(bytes_of(&self.method_id)).expect("unable to write size");
|
||||
|
||||
output.write_all(&self.rest_of_data).expect("unable to write data");
|
||||
|
||||
output
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ pub async fn send_response(original_packet: &PRUDPPacket, socket: &SocketData, c
|
|||
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.session_id = active_connection.server_session_id;
|
||||
packet.header.substream_id = 0;
|
||||
|
||||
packet.options.push(FragmentId(0));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue