1
Fork 0
mirror of https://github.com/redstrate/Kawari.git synced 2025-07-09 15:37:45 +00:00

Add ClientChatIpcSegment

This is just a dummy for now, we just need it downstream in Packet
Analzyer.
This commit is contained in:
Joshua Goins 2025-07-04 16:01:15 -04:00
parent 5acf6580f3
commit f2239378f6
2 changed files with 114 additions and 76 deletions

148
build.rs
View file

@ -21,84 +21,82 @@ fn main() {
let key = element.0;
let opcodes = element.1.as_array().unwrap();
if !opcodes.is_empty() {
// beginning
output_str.push_str("#[binrw]\n");
output_str.push_str("#[derive(Clone, PartialEq, Debug)]\n");
output_str.push_str(&format!("pub enum {key} {{\n"));
// beginning
output_str.push_str("#[binrw]\n");
output_str.push_str("#[derive(Clone, PartialEq, Debug)]\n");
output_str.push_str(&format!("pub enum {key} {{\n"));
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
let opcode = opcode.get("opcode").unwrap().as_number().unwrap();
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
let opcode = opcode.get("opcode").unwrap().as_number().unwrap();
output_str.push_str(&format!("#[brw(magic = {opcode}u16)]\n"));
output_str.push_str(&format!("{name},\n"));
}
output_str.push_str("Unknown(u16),\n");
// end
output_str.push_str("}\n\n");
output_str.push_str(&format!("impl {key} {{\n"));
// sizes
output_str.push_str("/// Returns the expected size of the data segment of this IPC opcode, _without_ any headers.\n");
output_str.push_str("pub fn calc_size(&self) -> u32 {\n");
output_str.push_str("match self {\n");
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
let size = opcode.get("size").unwrap().as_number().unwrap();
output_str.push_str(&format!("{key}::{name} => {size},\n"));
}
output_str.push_str(&format!("{key}::Unknown(_) => 0,\n"));
output_str.push_str("}\n\n");
output_str.push_str("}\n\n");
// names
output_str.push_str("/// Returns a human-readable name of the opcode.\n");
output_str.push_str("pub fn get_name(&self) -> &'static str {\n");
output_str.push_str("match self {\n");
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
output_str.push_str(&format!("{key}::{name} => \"{name}\",\n"));
}
output_str.push_str(&format!("{key}::Unknown(_) => \"Unknown\",\n"));
output_str.push_str("}\n\n");
output_str.push_str("}\n\n");
// opcodes
output_str.push_str("/// Returns the integer opcode.\n");
output_str.push_str("pub fn get_opcode(&self) -> u16 {\n");
output_str.push_str("match self {\n");
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
let opcode = opcode.get("opcode").unwrap().as_number().unwrap();
output_str.push_str(&format!("{key}::{name} => {opcode},\n"));
}
output_str.push_str(&format!("{key}::Unknown(opcode) => *opcode,\n"));
output_str.push_str("}\n\n");
output_str.push_str("}\n\n");
// end impl
output_str.push_str("}\n\n");
output_str.push_str(&format!("#[brw(magic = {opcode}u16)]\n"));
output_str.push_str(&format!("{name},\n"));
}
output_str.push_str("Unknown(u16),\n");
// end
output_str.push_str("}\n\n");
output_str.push_str(&format!("impl {key} {{\n"));
// sizes
output_str.push_str("/// Returns the expected size of the data segment of this IPC opcode, _without_ any headers.\n");
output_str.push_str("pub fn calc_size(&self) -> u32 {\n");
output_str.push_str("match self {\n");
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
let size = opcode.get("size").unwrap().as_number().unwrap();
output_str.push_str(&format!("{key}::{name} => {size},\n"));
}
output_str.push_str(&format!("{key}::Unknown(_) => 0,\n"));
output_str.push_str("}\n\n");
output_str.push_str("}\n\n");
// names
output_str.push_str("/// Returns a human-readable name of the opcode.\n");
output_str.push_str("pub fn get_name(&self) -> &'static str {\n");
output_str.push_str("match self {\n");
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
output_str.push_str(&format!("{key}::{name} => \"{name}\",\n"));
}
output_str.push_str(&format!("{key}::Unknown(_) => \"Unknown\",\n"));
output_str.push_str("}\n\n");
output_str.push_str("}\n\n");
// opcodes
output_str.push_str("/// Returns the integer opcode.\n");
output_str.push_str("pub fn get_opcode(&self) -> u16 {\n");
output_str.push_str("match self {\n");
for opcode in opcodes {
let opcode = opcode.as_object().unwrap();
let name = opcode.get("name").unwrap().as_str().unwrap();
let opcode = opcode.get("opcode").unwrap().as_number().unwrap();
output_str.push_str(&format!("{key}::{name} => {opcode},\n"));
}
output_str.push_str(&format!("{key}::Unknown(opcode) => *opcode,\n"));
output_str.push_str("}\n\n");
output_str.push_str("}\n\n");
// end impl
output_str.push_str("}\n\n");
}
std::fs::write("src/opcodes.rs", output_str).expect("Failed to write opcodes file!");

View file

@ -1,7 +1,7 @@
use binrw::binrw;
use crate::{
opcodes::ServerChatIpcType,
opcodes::{ClientChatIpcType, ServerChatIpcType},
packet::{IPC_HEADER_SIZE, IpcSegment, ReadWriteIpcSegment},
};
@ -38,6 +38,36 @@ impl Default for ServerChatIpcSegment {
}
}
pub type ClientChatIpcSegment = IpcSegment<ClientChatIpcType, ClientChatIpcData>;
impl ReadWriteIpcSegment for ClientChatIpcSegment {
fn calc_size(&self) -> u32 {
IPC_HEADER_SIZE + self.op_code.calc_size()
}
fn get_name(&self) -> &'static str {
self.op_code.get_name()
}
fn get_opcode(&self) -> u16 {
self.op_code.get_opcode()
}
}
// TODO: make generic
impl Default for ClientChatIpcSegment {
fn default() -> Self {
Self {
unk1: 0x14,
unk2: 0,
op_code: ClientChatIpcType::Unknown(0),
option: 0,
timestamp: 0,
data: ClientChatIpcData::Unknown { unk: Vec::new() },
}
}
}
#[binrw]
#[br(import(magic: &ServerChatIpcType, size: &u32))]
#[derive(Debug, Clone)]
@ -50,3 +80,13 @@ pub enum ServerChatIpcData {
unk: Vec<u8>,
},
}
#[binrw]
#[br(import(_magic: &ClientChatIpcType, size: &u32))]
#[derive(Debug, Clone)]
pub enum ClientChatIpcData {
Unknown {
#[br(count = size - 32)]
unk: Vec<u8>,
},
}