use crate::entity::field::FieldValue;
use crate::entity::{Entity, EntityEvents};
use crate::error::ParserError;
use crate::parser::Context;
use crate::proto::{
CDemoStringTables, CSvcMsgCreateStringTable, CSvcMsgUpdateStringTable, EDemoCommands, Message,
};
use crate::string_table::StringTableEntryUpdate;
use std::cell::RefCell;
use std::rc::Rc;
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RewriteInterests: u32 {
const DEMO_MESSAGE = 1 << 0;
const PACKET_MESSAGE = 1 << 1;
const PACKET_MESSAGES = 1 << 2;
const DEMO_STRING_TABLES = 1 << 3;
const STRING_TABLE_ENTRIES = 1 << 4;
const SVC_CREATE_STRING_TABLE = 1 << 5;
const SVC_UPDATE_STRING_TABLE = 1 << 6;
const ENTITY_FIELDS = 1 << 7;
}
}
pub enum MessageRewrite {
Keep,
Rewrite,
Replace(Vec<u8>),
Drop,
}
#[allow(unused_variables)]
pub trait DemoRewriter {
fn interests(&self) -> RewriteInterests {
RewriteInterests::empty()
}
fn rewrite_demo_message(
&mut self,
ctx: &Context,
tick: u32,
msg_type: EDemoCommands,
payload: &[u8],
) -> Result<MessageRewrite, ParserError> {
Ok(MessageRewrite::Keep)
}
fn rewrite_packet_message(
&mut self,
ctx: &Context,
tick: u32,
msg_type: i32,
payload: &[u8],
) -> Result<MessageRewrite, ParserError> {
Ok(MessageRewrite::Keep)
}
fn rewrite_packet_messages(
&mut self,
ctx: &Context,
tick: u32,
messages: &mut Vec<PacketMessage>,
) -> Result<(), ParserError> {
Ok(())
}
fn rewrite_demo_string_tables(
&mut self,
ctx: &Context,
tick: u32,
message: &mut CDemoStringTables,
) -> Result<MessageRewrite, ParserError> {
Ok(MessageRewrite::Keep)
}
fn rewrite_string_table_entry(
&mut self,
ctx: &Context,
tick: u32,
table_name: &str,
entry: &mut StringTableEntryUpdate,
) -> Result<(), ParserError> {
Ok(())
}
fn rewrite_svc_create_string_table(
&mut self,
ctx: &Context,
tick: u32,
message: &mut CSvcMsgCreateStringTable,
) -> Result<MessageRewrite, ParserError> {
Ok(MessageRewrite::Keep)
}
fn rewrite_svc_update_string_table(
&mut self,
ctx: &Context,
tick: u32,
message: &mut CSvcMsgUpdateStringTable,
) -> Result<MessageRewrite, ParserError> {
Ok(MessageRewrite::Keep)
}
fn replace_entity_field(
&mut self,
ctx: &Context,
event: EntityEvents,
entity: &Entity,
field_name: &str,
value: &FieldValue,
) -> Option<FieldValue> {
None
}
fn should_rewrite_entity(
&mut self,
ctx: &Context,
event: EntityEvents,
entity: &Entity,
) -> bool {
true
}
}
impl<T> DemoRewriter for Rc<RefCell<T>>
where
T: DemoRewriter,
{
fn interests(&self) -> RewriteInterests {
self.borrow().interests()
}
fn rewrite_demo_message(
&mut self,
ctx: &Context,
tick: u32,
msg_type: EDemoCommands,
payload: &[u8],
) -> Result<MessageRewrite, ParserError> {
self.borrow_mut()
.rewrite_demo_message(ctx, tick, msg_type, payload)
}
fn rewrite_packet_message(
&mut self,
ctx: &Context,
tick: u32,
msg_type: i32,
payload: &[u8],
) -> Result<MessageRewrite, ParserError> {
self.borrow_mut()
.rewrite_packet_message(ctx, tick, msg_type, payload)
}
fn rewrite_packet_messages(
&mut self,
ctx: &Context,
tick: u32,
messages: &mut Vec<PacketMessage>,
) -> Result<(), ParserError> {
self.borrow_mut()
.rewrite_packet_messages(ctx, tick, messages)
}
fn rewrite_demo_string_tables(
&mut self,
ctx: &Context,
tick: u32,
message: &mut CDemoStringTables,
) -> Result<MessageRewrite, ParserError> {
self.borrow_mut()
.rewrite_demo_string_tables(ctx, tick, message)
}
fn rewrite_string_table_entry(
&mut self,
ctx: &Context,
tick: u32,
table_name: &str,
entry: &mut StringTableEntryUpdate,
) -> Result<(), ParserError> {
self.borrow_mut()
.rewrite_string_table_entry(ctx, tick, table_name, entry)
}
fn rewrite_svc_create_string_table(
&mut self,
ctx: &Context,
tick: u32,
message: &mut CSvcMsgCreateStringTable,
) -> Result<MessageRewrite, ParserError> {
self.borrow_mut()
.rewrite_svc_create_string_table(ctx, tick, message)
}
fn rewrite_svc_update_string_table(
&mut self,
ctx: &Context,
tick: u32,
message: &mut CSvcMsgUpdateStringTable,
) -> Result<MessageRewrite, ParserError> {
self.borrow_mut()
.rewrite_svc_update_string_table(ctx, tick, message)
}
fn replace_entity_field(
&mut self,
ctx: &Context,
event: EntityEvents,
entity: &Entity,
field_name: &str,
value: &FieldValue,
) -> Option<FieldValue> {
self.borrow_mut()
.replace_entity_field(ctx, event, entity, field_name, value)
}
fn should_rewrite_entity(
&mut self,
ctx: &Context,
event: EntityEvents,
entity: &Entity,
) -> bool {
self.borrow_mut().should_rewrite_entity(ctx, event, entity)
}
}
pub fn rewrite_protobuf_message<M, F>(
msg: &[u8],
mut rewrite: F,
) -> Result<MessageRewrite, ParserError>
where
M: Message + Default,
F: FnMut(&mut M) -> Result<MessageRewrite, ParserError>,
{
let mut decoded = M::decode(msg)?;
match rewrite(&mut decoded)? {
MessageRewrite::Keep => Ok(MessageRewrite::Keep),
MessageRewrite::Drop => Ok(MessageRewrite::Drop),
MessageRewrite::Replace(bytes) => Ok(MessageRewrite::Replace(bytes)),
MessageRewrite::Rewrite => Ok(MessageRewrite::Replace(decoded.encode_to_vec())),
}
}
#[derive(Clone, Debug)]
pub struct PacketMessage {
pub msg_type: i32,
pub payload: Vec<u8>,
}
impl PacketMessage {
pub fn new(msg_type: i32, payload: impl Into<Vec<u8>>) -> Self {
Self {
msg_type,
payload: payload.into(),
}
}
pub fn encoded<M>(msg_type: i32, message: &M) -> Self
where
M: Message,
{
Self::new(msg_type, message.encode_to_vec())
}
pub fn decode<M>(&self) -> Result<M, ParserError>
where
M: Message + Default,
{
Ok(M::decode(self.payload.as_slice())?)
}
pub fn replace_with<M>(&mut self, message: &M)
where
M: Message,
{
self.payload = message.encode_to_vec();
}
}