Break: read replay packets

This commit is contained in:
eigenein committed 2023-04-29 22:17:12 +02:00
1 parent 615537ce45
commit fb5f52038d
16 files changed
+232 -119

No files matched your search

+28
View File
@@ -0,0 +1,28 @@
use byteorder::{LittleEndian, ReadBytesExt};
use serde::Serialize;
use crate::result::Result;
#[derive(Debug, Serialize)]
pub enum EntityMethod {
/// TODO: team composition.
Subtype2F,
/// Default variant when subtype is not known.
Unknown { sub_type: u32, payload: Vec<u8> },
}
impl EntityMethod {
pub fn new(payload: Vec<u8>) -> Result<Self> {
let mut reader = payload.as_slice();
reader.read_u32::<LittleEndian>()?;
let sub_type = reader.read_u32::<LittleEndian>()?;
let this = match sub_type {
0x2F => Self::Subtype2F,
_ => Self::Unknown { sub_type, payload },
};
Ok(this)
}
}
+32
View File
@@ -0,0 +1,32 @@
use std::io::Read;
use byteorder::{LittleEndian, ReadBytesExt};
use serde::Serialize;
use crate::models::data::payload::Payload;
use crate::result::Result;
#[derive(Debug, Serialize)]
pub struct Packet {
pub clock: f32,
pub payload: Payload,
}
impl Packet {
pub fn from_reader(reader: &mut impl Read) -> Result<Option<Self>> {
let Ok(length) = reader.read_u32::<LittleEndian>() else { return Ok(None) };
let type_ = reader.read_u32::<LittleEndian>()?;
let clock = reader.read_f32::<LittleEndian>()?;
let payload = Self::read_payload(reader, length as usize)?;
let payload = Payload::new(type_, payload)?;
let this = Self { clock, payload };
Ok(Some(this))
}
fn read_payload(reader: &mut impl Read, length: usize) -> Result<Vec<u8>> {
let mut buffer = Vec::new();
buffer.resize(length, 0);
reader.read_exact(&mut buffer)?;
Ok(buffer)
}
}
+51
View File
@@ -0,0 +1,51 @@
use std::io::Read;
use byteorder::{LittleEndian, ReadBytesExt};
use serde::Serialize;
use serde_with::serde_as;
use crate::models::data::replay_header::ReplayHeader;
use crate::models::data::{assert_magic, read_pickled, read_string, EntityMethod};
use crate::result::Result;
#[serde_as]
#[derive(Debug, Serialize)]
pub enum Payload {
ReplayHeader(ReplayHeader),
EntityMethod(EntityMethod),
/// Default payload when type is not known.
Unknown(#[serde_as(as = "serde_with::hex::Hex")] Vec<u8>),
}
impl Payload {
pub fn new(type_: u32, payload: Vec<u8>) -> Result<Self> {
let this = match type_ {
0 => {
let mut reader = payload.as_slice();
reader.read_exact(&mut [0; 10])?;
let author_nickname = read_string(&mut reader)?;
let arena_unique_id = reader.read_u64::<LittleEndian>()?;
let arena_type_id = reader.read_u32::<LittleEndian>()?;
let summary = {
assert_magic(reader.read_u8()?, 0xFF)?;
let pickled_length = reader.read_u16::<LittleEndian>()?;
assert_magic(reader.read_u8()?, 0x00)?;
read_pickled(&mut reader, pickled_length as usize)?
};
Self::ReplayHeader(ReplayHeader {
summary,
author_nickname,
arena_unique_id,
arena_type_id,
})
}
8 => Self::EntityMethod(EntityMethod::new(payload)?),
_ => Self::Unknown(payload),
};
Ok(this)
}
}
+11
View File
@@ -0,0 +1,11 @@
use serde::Serialize;
use crate::models::data::Summary;
#[derive(Debug, Serialize)]
pub struct ReplayHeader {
pub summary: Summary,
pub author_nickname: String,
pub arena_unique_id: u64,
pub arena_type_id: u32,
}
+27
View File
@@ -0,0 +1,27 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Summary {
#[serde(rename = "playersBattleCategoriesIds")]
pub players_battle_categories_ids: HashMap<u32, (u8, u32)>,
#[serde(rename = "battleLevel")]
pub battle_level: u8,
#[serde(rename = "battleCategoryId")]
pub battle_category_id: u8,
#[serde(rename = "mouseEnabled")]
pub is_mouse_enabled: bool,
#[serde(rename = "mmType")]
pub matchmaker_type: u8,
#[serde(rename = "camouflageSlot")]
pub camouflage_slot: u8,
#[serde(rename = "avgMmr")]
pub average_mmr: Vec<f64>,
}