feat: refactor prudp code and start working on refactoring rmc

This commit is contained in:
DJMrTV 2025-02-18 22:55:33 +01:00
commit 3ea7c7e671
37 changed files with 2029 additions and 456 deletions

View file

@ -1,6 +1,7 @@
pub mod message;
pub mod structures;
pub mod response;
pub mod protocols;

17
src/rmc/protocols/mod.rs Normal file
View 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!()
}
}

View file

@ -6,8 +6,10 @@ use crate::prudp::packet::{PRUDPPacket};
use crate::prudp::packet::flags::{NEED_ACK, RELIABLE};
use crate::prudp::packet::PacketOption::FragmentId;
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::web::DirectionalData::{Incoming, Outgoing};
use crate::web::WEB_DATA;
pub enum RMCResponseResult {
Success{
@ -76,33 +78,8 @@ pub fn generate_response(protocol_id: u8, response: RMCResponseResult) -> io::Re
Ok(data_out)
}
pub async fn send_response(original_packet: &PRUDPPacket, socket: &SocketData, connection: &mut ConnectionData, rmcresponse: RMCResponse){
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;
pub async fn send_response(original_packet: &PRUDPPacket, connection: &mut ExternalConnection, rmcresponse: RMCResponse){
connection.send(rmcresponse.to_data()).await;
}
//taken from kinnays error list directly

View file

@ -30,6 +30,7 @@ pub mod qbuffer;
pub mod primitives;
pub mod matchmake;
pub mod variant;
mod ranking;
pub trait RmcSerialize: Sized{
fn serialize(&self, writer: &mut dyn Write) -> Result<()>;

View file

@ -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::rmc::structures::Result;
pub fn read(reader: &mut impl Read) -> Result<Vec<u8>>{
let size: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
use crate::rmc::structures::{Result, RmcSerialize};
use crate::rmc::structures::qresult::QResult;
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))
}
}

View 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())
}
}

View file

@ -35,4 +35,5 @@ impl RmcSerialize for &str{
Ok(())
}
}
}