1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian}; use crate::{Parse, ParserState, Result, Stream}; use self::consolecmd::ConsoleCmdPacket; use self::datatable::DataTablePacket; use self::message::MessagePacket; use self::stop::StopPacket; use self::stringtable::StringTablePacket; use self::synctick::SyncTickPacket; use self::usercmd::UserCmdPacket; use crate::demo::parser::Encode; use serde::{Deserialize, Serialize}; use tracing::{event, span, Level}; pub mod consolecmd; pub mod datatable; pub mod message; pub mod stop; pub mod stringtable; pub mod synctick; pub mod usercmd; #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] #[serde(bound(deserialize = "'a: 'static"))] #[serde(tag = "type")] pub enum Packet<'a> { Sigon(MessagePacket<'a>), Message(MessagePacket<'a>), SyncTick(SyncTickPacket), ConsoleCmd(ConsoleCmdPacket), UserCmd(UserCmdPacket), DataTables(DataTablePacket), Stop(StopPacket), StringTables(StringTablePacket<'a>), } impl Packet<'_> { pub fn tick(&self) -> u32 { match self { Packet::Sigon(msg) => msg.tick, Packet::Message(msg) => msg.tick, Packet::SyncTick(msg) => msg.tick, Packet::ConsoleCmd(msg) => msg.tick, Packet::UserCmd(msg) => msg.tick, Packet::DataTables(msg) => msg.tick, Packet::Stop(msg) => msg.tick, Packet::StringTables(msg) => msg.tick, } } pub fn set_tick(&mut self, tick: u32) { match self { Packet::Sigon(msg) => msg.tick = tick, Packet::Message(msg) => msg.tick = tick, Packet::SyncTick(msg) => msg.tick = tick, Packet::ConsoleCmd(msg) => msg.tick = tick, Packet::UserCmd(msg) => msg.tick = tick, Packet::DataTables(msg) => msg.tick = tick, Packet::Stop(msg) => msg.tick = tick, Packet::StringTables(msg) => msg.tick = tick, } } } #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[derive(BitRead, BitWrite, Debug, Clone, Copy, Eq, PartialEq)] #[discriminant_bits = 8] #[repr(u8)] pub enum PacketType { Sigon = 1, Message = 2, SyncTick = 3, ConsoleCmd = 4, UserCmd = 5, DataTables = 6, Stop = 7, StringTables = 8, } impl Packet<'_> { pub fn packet_type(&self) -> PacketType { match self { Packet::Sigon(_) => PacketType::Sigon, Packet::Message(_) => PacketType::Message, Packet::SyncTick(_) => PacketType::SyncTick, Packet::ConsoleCmd(_) => PacketType::ConsoleCmd, Packet::UserCmd(_) => PacketType::UserCmd, Packet::DataTables(_) => PacketType::DataTables, Packet::Stop(_) => PacketType::Stop, Packet::StringTables(_) => PacketType::StringTables, } } } impl<'a> Parse<'a> for Packet<'a> { fn parse(stream: &mut Stream<'a>, state: &ParserState) -> Result<Self> { let packet_type = PacketType::read(stream)?; let _span = span!(Level::INFO, "reading packet", packet_type = ?packet_type).entered(); event!(Level::INFO, "parsing packet"); Ok(match packet_type { PacketType::Sigon => Packet::Sigon(MessagePacket::parse(stream, state)?), PacketType::Message => Packet::Message(MessagePacket::parse(stream, state)?), PacketType::SyncTick => Packet::SyncTick(SyncTickPacket::parse(stream, state)?), PacketType::ConsoleCmd => Packet::ConsoleCmd(ConsoleCmdPacket::parse(stream, state)?), PacketType::UserCmd => Packet::UserCmd(UserCmdPacket::parse(stream, state)?), PacketType::DataTables => Packet::DataTables(DataTablePacket::parse(stream, state)?), PacketType::Stop => Packet::Stop(StopPacket::parse(stream, state)?), PacketType::StringTables => { Packet::StringTables(StringTablePacket::parse(stream, state)?) } }) } } impl Encode for Packet<'_> { fn encode(&self, stream: &mut BitWriteStream<LittleEndian>, state: &ParserState) -> Result<()> { self.packet_type().write(stream)?; match self { Packet::Sigon(inner) => inner.encode(stream, state), Packet::Message(inner) => inner.encode(stream, state), Packet::SyncTick(inner) => inner.encode(stream, state), Packet::ConsoleCmd(inner) => inner.encode(stream, state), Packet::UserCmd(inner) => inner.encode(stream, state), Packet::DataTables(inner) => inner.encode(stream, state), Packet::Stop(inner) => inner.encode(stream, state), Packet::StringTables(inner) => inner.encode(stream, state), } } }