add debug logging to ticket generation for debugging

This commit is contained in:
Maple 2026-03-24 23:17:22 +01:00
commit 4ad883a54d
10 changed files with 223 additions and 127 deletions

View file

@ -1,19 +1,17 @@
use crate::rmc::structures::RmcSerialize;
use bytemuck::bytes_of;
use std::io::{Read, Write};
use std::mem::MaybeUninit;
use bytemuck::bytes_of;
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
use crate::rmc::structures::RmcSerialize;
// this is also for implementing `Buffer` this is tecnically not the same as its handled internaly
// this is also for implementing `Buffer` this is tecnically not the same as its handled internaly
// probably but as it has the same mapping it doesn't matter and simplifies things
impl<T: RmcSerialize> RmcSerialize for Vec<T>{
impl<T: RmcSerialize> RmcSerialize for Vec<T> {
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
let u32_len = self.len() as u32;
writer.write_all(bytes_of(&u32_len))?;
for e in self{
for e in self {
e.serialize(writer)?;
}
@ -21,27 +19,31 @@ impl<T: RmcSerialize> RmcSerialize for Vec<T>{
}
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
println!("reading list");
let len: u32 = reader.read_struct(IS_BIG_ENDIAN)?;
println!("readijg list: {:?}", len);
//let mut vec = Vec::with_capacity(len as usize);
let vec = (0..len).map(|_| T::deserialize(reader)).collect::<Result<Vec<_>, _>>()?;
let vec: Vec<T> = (0..len)
.map(|_| T::deserialize(reader))
.collect::<Result<Vec<_>, _>>()?;
Ok(vec)
}
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
let mut val = 0u32;
for i in self{
for i in self {
val += i.serialize_write_size()?;
}
Ok(4 + val)
}
}
impl<const LEN: usize, T: RmcSerialize> RmcSerialize for [T; LEN]{
impl<const LEN: usize, T: RmcSerialize> RmcSerialize for [T; LEN] {
fn serialize(&self, writer: &mut impl Write) -> crate::rmc::structures::Result<()> {
for i in 0..LEN{
for i in 0..LEN {
self[i].serialize(writer)?;
}
@ -51,20 +53,20 @@ impl<const LEN: usize, T: RmcSerialize> RmcSerialize for [T; LEN]{
fn deserialize(reader: &mut impl Read) -> crate::rmc::structures::Result<Self> {
let mut arr = [const { MaybeUninit::<T>::uninit() }; LEN];
for i in 0..LEN{
for i in 0..LEN {
arr[i] = MaybeUninit::new(T::deserialize(reader)?);
}
// all of the elements are now initialized so it is safe to assume they are initialized
let arr = arr.map(|v| unsafe{ v.assume_init() });
let arr = arr.map(|v| unsafe { v.assume_init() });
Ok(arr)
}
#[inline(always)]
fn serialize_write_size(&self) -> crate::rmc::structures::Result<u32> {
let mut val = 0u32;
for i in self{
for i in self {
val += i.serialize_write_size()?;
}
Ok(val)

View file

@ -1,12 +1,12 @@
use std::{fmt, io};
use crate::rmc::structures::helpers::DummyWriter;
use std::io::{Read, Write};
use std::string::FromUtf8Error;
use std::{fmt, io};
use thiserror::Error;
use crate::rmc::structures::helpers::DummyWriter;
//ideas for the future: make a proc macro library which allows generation of struct reads
#[derive(Error, Debug)]
pub enum Error{
pub enum Error {
#[error("Io Error: {0}")]
Io(#[from] io::Error),
#[error("UTF8 conversion Error: {0}")]
@ -18,51 +18,52 @@ pub enum Error{
#[error("an error occurred reading the station url")]
StationUrlInvalid,
#[error("error formatting text: {0}")]
FormatError(#[from] fmt::Error)
FormatError(#[from] fmt::Error),
}
pub type Result<T> = std::result::Result<T, Error>;
pub mod string;
pub mod any;
pub mod qresult;
pub mod buffer;
pub mod connection_data;
pub mod rmc_struct;
pub mod list;
pub mod qbuffer;
pub mod primitives;
pub mod matchmake;
pub mod variant;
pub mod ranking;
pub mod networking;
pub mod helpers;
pub mod list;
pub mod matchmake;
pub mod networking;
pub mod primitives;
pub mod qbuffer;
pub mod qresult;
pub mod ranking;
pub mod rmc_struct;
pub mod string;
pub mod variant;
pub trait RmcSerialize{
pub trait RmcSerialize {
fn serialize(&self, writer: &mut impl Write) -> Result<()>;
fn serialize_write_size(&self) -> Result<u32>{
fn serialize_write_size(&self) -> Result<u32> {
let mut dummy = DummyWriter::new();
self.serialize(&mut dummy)?;
Ok(dummy.get_total_len())
}
fn deserialize(reader: &mut impl Read) -> Result<Self> where Self: Sized;
fn deserialize(reader: &mut impl Read) -> Result<Self>
where
Self: Sized;
fn to_data(&self) -> Result<Vec<u8>>{
let mut data = Vec::with_capacity(
self.serialize_write_size()? as usize
);
fn to_data(&self) -> Result<Vec<u8>> {
let expected_size = self.serialize_write_size()?;
let mut data = Vec::with_capacity(expected_size as usize);
self.serialize(&mut data)?;
debug_assert_eq!(self.serialize_write_size().unwrap(), data.len() as u32);
debug_assert_eq!(expected_size, data.len() as u32);
Ok(data)
}
}
impl RmcSerialize for (){
impl RmcSerialize for () {
fn serialize(&self, _writer: &mut impl Write) -> Result<()> {
Ok(())
}
@ -72,6 +73,4 @@ impl RmcSerialize for (){
fn serialize_write_size(&self) -> Result<u32> {
Ok(0)
}
}
}

View file

@ -280,8 +280,8 @@ impl<T: RmcSerialize, U: RmcSerialize, V: RmcSerialize, W: RmcSerialize, X: RmcS
Ok(self.0.serialize_write_size()?
+ self.1.serialize_write_size()?
+ self.2.serialize_write_size()?
+ self.2.serialize_write_size()?
+ self.3.serialize_write_size()?)
+ self.3.serialize_write_size()?
+ self.4.serialize_write_size()?)
}
}

View file

@ -1,37 +1,42 @@
use crate::rmc::response::ErrorCode;
use crate::rmc::structures::{Result, RmcSerialize};
use bytemuck::{Pod, Zeroable, bytes_of};
use std::io::{Read, Write};
use bytemuck::{bytes_of, Pod, Zeroable};
use v_byte_helpers::SwapEndian;
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
use crate::rmc::response::ErrorCode;
use crate::rmc::structures::{RmcSerialize, Result};
pub const ERROR_MASK: u32 = 1 << 31;
pub const ERROR_MASK: u32 = 1 << 31;
#[derive(Pod, Zeroable, Copy, Clone, SwapEndian, Debug)]
#[repr(transparent)]
pub struct QResult(u32);
impl QResult{
pub fn success(error_code: ErrorCode) -> Self{
impl QResult {
pub fn success(error_code: ErrorCode) -> Self {
let val: u32 = error_code.into();
Self(val & (!ERROR_MASK))
}
pub fn error(error_code: ErrorCode) -> Self{
pub fn error(error_code: ErrorCode) -> Self {
let val: u32 = error_code.into();
Self(val | ERROR_MASK)
}
}
impl RmcSerialize for QResult{
impl RmcSerialize for QResult {
fn serialize(&self, writer: &mut impl Write) -> Result<()> {
writer.write(bytes_of(self))?;
Ok(())
}
fn deserialize(reader: &mut impl Read) -> Result<Self> {
Ok(reader.read_struct(IS_BIG_ENDIAN)?)
let result: Self = reader.read_struct(IS_BIG_ENDIAN)?;
println!("reading qresult: {:x}", result.0);
Ok(result)
}
}
fn serialize_write_size(&self) -> Result<u32> {
Ok(4)
}
}

View file

@ -1,15 +1,13 @@
use crate::rmc::structures::Result;
use std::cmp::max;
use std::fmt::Arguments;
use std::io;
use std::io::{ErrorKind, IoSlice, Read, Write};
use crate::rmc::structures::Result;
#[repr(C, packed)]
struct StructureHeader{
struct StructureHeader {
version: u8,
length: u32
length: u32,
}
#[cfg(feature = "rmc_struct_header")]
@ -38,7 +36,12 @@ impl Write for OnlyWriteVec<'_> {
}
#[cfg(feature = "rmc_struct_header")]
pub fn write_struct<T: Write>(writer: &mut T, version: u8, inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> {
pub fn write_struct<T: Write>(
writer: &mut T,
version: u8,
inner_size: u32,
pred: impl FnOnce(&mut T) -> Result<()>,
) -> Result<()> {
use bytemuck::bytes_of;
writer.write_all(&[version])?;
@ -50,29 +53,31 @@ pub fn write_struct<T: Write>(writer: &mut T, version: u8, inner_size: u32, pred
Ok(())
}
#[cfg(not(feature = "rmc_struct_header"))]
pub fn write_struct<T: Write>(writer: &mut T, _version: u8, _inner_size: u32, pred: impl FnOnce(&mut T) -> Result<()> ) -> Result<()> {
pub fn write_struct<T: Write>(
writer: &mut T,
_version: u8,
_inner_size: u32,
pred: impl FnOnce(&mut T) -> Result<()>,
) -> Result<()> {
pred(writer)
}
pub struct SubRead<'a, T: Read>{
pub struct SubRead<'a, T: Read> {
left_to_read: usize,
origin: &'a mut T
origin: &'a mut T,
}
impl<'a, T: Read> SubRead<'a, T>{
pub const fn new(origin: &'a mut T, left_to_read: usize) -> Self{
Self{
impl<'a, T: Read> SubRead<'a, T> {
pub const fn new(origin: &'a mut T, left_to_read: usize) -> Self {
Self {
left_to_read,
origin
origin,
}
}
}
impl<T: Read> Read for SubRead<'_, T>{
impl<T: Read> Read for SubRead<'_, T> {
#[inline(always)]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let max_read = max(self.left_to_read, buf.len());
@ -83,8 +88,11 @@ impl<T: Read> Read for SubRead<'_, T>{
#[inline(always)]
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
if buf.len() > self.left_to_read{
return Err(io::Error::new(ErrorKind::UnexpectedEof, "Would run over end of SubRead"));
if buf.len() > self.left_to_read {
return Err(io::Error::new(
ErrorKind::UnexpectedEof,
"Would run over end of SubRead",
));
}
self.left_to_read -= buf.len();
self.origin.read_exact(buf)
@ -92,10 +100,14 @@ impl<T: Read> Read for SubRead<'_, T>{
}
#[cfg(feature = "rmc_struct_header")]
pub fn read_struct<T: Sized, R: Read>(reader: &mut R, version: u8, pred: impl FnOnce(&mut SubRead<R>) -> Result<T>) -> Result<T> {
pub fn read_struct<T: Sized, R: Read>(
reader: &mut R,
version: u8,
pred: impl FnOnce(&mut SubRead<R>) -> Result<T>,
) -> Result<T> {
use crate::rmc::structures::Error::VersionMismatch;
use v_byte_helpers::ReadExtensions;
use v_byte_helpers::IS_BIG_ENDIAN;
use v_byte_helpers::ReadExtensions;
let ver: u8 = reader.read_struct(IS_BIG_ENDIAN)?;
if ver != version {
@ -108,6 +120,10 @@ pub fn read_struct<T: Sized, R: Read>(reader: &mut R, version: u8, pred: impl Fn
}
#[cfg(not(feature = "rmc_struct_header"))]
pub fn read_struct<T: Sized, R: Read>(mut reader: &mut R, _version: u8, pred: impl FnOnce(&mut R) -> Result<T>) -> Result<T> {
pub fn read_struct<T: Sized, R: Read>(
mut reader: &mut R,
_version: u8,
pred: impl FnOnce(&mut R) -> Result<T>,
) -> Result<T> {
Ok(pred(&mut reader)?)
}

View file

@ -1,18 +1,18 @@
use std::io::{Read, Write};
use super::{Result, RmcSerialize};
use bytemuck::bytes_of;
use log::error;
use std::io::{Read, Write};
use v_byte_helpers::{IS_BIG_ENDIAN, ReadExtensions};
use super::{Result, RmcSerialize};
impl RmcSerialize for String{
impl RmcSerialize for String {
fn deserialize(reader: &mut impl Read) -> Result<Self> {
let len: u16 = reader.read_struct(IS_BIG_ENDIAN)?;
if len == 0{
if len == 0 {
return Ok("".to_string());
}
let mut data = vec![0; len as usize];
reader.read_exact(&mut data)?;
if *data.last().unwrap() != 0{
if *data.last().unwrap() != 0 {
error!("unable to find null terminator... continuing anyways");
}
data.pop();
@ -27,7 +27,7 @@ impl RmcSerialize for String{
}
}
impl RmcSerialize for &str{
impl RmcSerialize for &str {
fn deserialize(_reader: &mut impl Read) -> Result<Self> {
panic!("cannot serialize to &str")
}
@ -45,4 +45,3 @@ impl RmcSerialize for &str{
Ok(2 + self.as_bytes().len() as u32 + 1)
}
}