use std::{cell::RefCell, collections::HashMap, ffi::CStr, rc::Rc};
use bitvec::{order::Lsb0, slice::BitSlice as _BitSlice, vec::BitVec as _BitVec};
use crate::utils::get_initial_delta;
#[derive(Clone, Debug)]
pub struct Aux {
pub delta_decoders: DeltaDecoderTable,
pub max_client: u8,
pub custom_messages: CustomMessage,
pub is_hltv: bool,
}
impl Aux {
pub fn new_raw() -> Self {
Self {
delta_decoders: get_initial_delta(),
max_client: 1,
custom_messages: CustomMessage::new(),
is_hltv: false,
}
}
pub fn new2() -> AuxRefCell {
Rc::new(RefCell::new(Self::new_raw()))
}
}
pub type AuxRefCell = Rc<RefCell<Aux>>;
#[derive(Debug, Clone)]
pub struct Demo {
pub header: Header,
pub directory: Directory,
pub _aux: Option<AuxRefCell>,
}
#[derive(Debug, Clone)]
pub struct Header {
pub magic: Vec<u8>,
pub demo_protocol: i32,
pub network_protocol: i32,
pub map_name: ByteString,
pub game_directory: ByteString,
pub map_checksum: u32,
pub directory_offset: i32,
}
#[derive(Debug, Clone)]
pub struct Directory {
pub entries: Vec<DirectoryEntry>,
}
#[derive(Debug, Clone)]
pub struct DirectoryEntry {
pub type_: i32,
pub description: ByteString,
pub flags: i32,
pub cd_track: i32,
pub track_time: f32,
pub frame_count: i32,
pub frame_offset: i32,
pub file_length: i32,
pub frames: Vec<Frame>,
}
#[derive(Debug, Clone)]
pub struct Frame {
pub time: f32,
pub frame: i32,
pub frame_data: FrameData,
}
#[derive(Debug, Clone)]
pub enum FrameData {
NetworkMessage(Box<(NetworkMessageType, NetworkMessage)>),
DemoStart,
ConsoleCommand(ConsoleCommand),
ClientData(ClientData),
NextSection,
Event(Event),
WeaponAnimation(WeaponAnimation),
Sound(Sound),
DemoBuffer(DemoBuffer),
}
#[derive(Debug, Clone)]
pub struct ConsoleCommand {
pub command: ByteString,
}
type Point<T> = Vec<T>;
#[derive(Debug, Clone)]
pub struct ClientData {
pub origin: Point<f32>,
pub viewangles: Point<f32>,
pub weapon_bits: i32,
pub fov: f32,
}
#[derive(Debug, Clone)]
pub struct Event {
pub flags: i32,
pub index: i32,
pub delay: f32,
pub args: EventArgs,
}
#[derive(Debug, Clone)]
pub struct EventArgs {
pub flags: i32,
pub entity_index: i32,
pub origin: Point<f32>,
pub angles: Point<f32>,
pub velocity: Point<f32>,
pub ducking: i32,
pub fparam1: f32,
pub fparam2: f32,
pub iparam1: i32,
pub iparam2: i32,
pub bparam1: i32,
pub bparam2: i32,
}
#[derive(Debug, Clone)]
pub struct Sound {
pub channel: i32,
pub sample: Vec<u8>,
pub attenuation: f32,
pub volume: f32,
pub flags: i32,
pub pitch: i32,
}
#[derive(Debug, Clone)]
pub struct WeaponAnimation {
pub anim: i32,
pub body: i32,
}
#[derive(Debug, Clone)]
pub struct DemoBuffer {
pub buffer: Vec<u8>,
}
#[derive(Debug, Clone)]
pub enum NetworkMessageType {
Start,
Normal,
Unknown(u8),
}
impl TryFrom<u8> for NetworkMessageType {
type Error = &'static str;
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::Start),
1 => Ok(Self::Normal),
2..=9 => Err("network message type cannot overlap with other messages"),
rest => Ok(Self::Unknown(rest)),
}
}
}
#[derive(Debug, Clone)]
pub struct NetworkMessage {
pub info: DemoInfo,
pub sequence_info: SequenceInfo,
pub message_length: u32,
pub messages: MessageData,
}
#[derive(Debug, Clone)]
pub struct DemoInfo {
pub timestamp: f32,
pub refparams: RefParams,
pub usercmd: UserCmd,
pub movevars: MoveVars,
pub view: Point<f32>,
pub viewmodel: i32,
}
#[derive(Debug, Clone)]
pub struct RefParams {
pub view_origin: Point<f32>,
pub view_angles: Point<f32>,
pub forward: Point<f32>,
pub right: Point<f32>,
pub up: Point<f32>,
pub frame_time: f32,
pub time: f32,
pub intermission: i32,
pub paused: i32,
pub spectator: i32,
pub on_ground: i32,
pub water_level: i32,
pub sim_vel: Point<f32>,
pub sim_org: Point<f32>,
pub view_height: Point<f32>,
pub ideal_pitch: f32,
pub cl_viewangles: Point<f32>,
pub health: i32,
pub crosshair_angle: Point<f32>,
pub view_size: f32,
pub punch_angle: Point<f32>,
pub max_clients: i32,
pub view_entity: i32,
pub player_num: i32,
pub max_entities: i32,
pub demo_playback: i32,
pub hardware: i32,
pub smoothing: i32,
pub ptr_cmd: i32,
pub ptr_move_vars: i32,
pub view_port: Vec<i32>,
pub next_view: i32,
pub only_client_draw: i32,
}
#[derive(Debug, Clone)]
pub struct UserCmd {
pub lerp_msec: i16,
pub msec: u8,
pub unknown1: u8,
pub view_angles: Point<f32>,
pub forward_move: f32,
pub side_move: f32,
pub up_move: f32,
pub light_level: i8,
pub unknonwn2: u8,
pub buttons: u16,
pub impulse: i8,
pub weapon_select: i8,
pub unknown3: u8,
pub unknown4: u8,
pub impact_index: i32,
pub impact_position: Point<f32>,
}
#[derive(Debug, Clone)]
pub struct MoveVars {
pub gravity: f32,
pub stopspeed: f32,
pub maxspeed: f32,
pub spectatormaxspeed: f32,
pub accelerate: f32,
pub airaccelerate: f32,
pub wateraccelerate: f32,
pub friction: f32,
pub edgefriction: f32,
pub waterfriction: f32,
pub entgravity: f32,
pub bounce: f32,
pub stepsize: f32,
pub maxvelocity: f32,
pub zmax: f32,
pub wave_height: f32,
pub footsteps: i32,
pub sky_name: ByteString,
pub rollangle: f32,
pub rollspeed: f32,
pub skycolor: Point<f32>,
pub skyvec: Point<f32>,
}
#[derive(Debug, Clone)]
pub struct SequenceInfo {
pub incoming_sequence: i32,
pub incoming_acknowledged: i32,
pub incoming_reliable_acknowledged: i32,
pub incoming_reliable_sequence: i32,
pub outgoing_sequence: i32,
pub reliable_sequence: i32,
pub last_reliable_sequence: i32,
}
#[derive(Debug, Clone)]
pub enum MessageData {
Parsed(Vec<NetMessage>),
Raw(Vec<u8>),
None,
}
#[derive(Debug, Clone, Copy)]
pub enum MessageDataParseMode {
Parse,
Raw,
None,
}
pub type BitVec = _BitVec<u8, Lsb0>;
pub type BitSlice = _BitSlice<u8, Lsb0>;
pub type ByteVec = Vec<u8>;
pub type Delta = HashMap<String, ByteVec>;
pub type DeltaDecoder = Vec<DeltaDecoderS>;
pub type DeltaDecoderTable = HashMap<String, DeltaDecoder>;
#[derive(Debug, Clone)]
pub struct DeltaDecoderS {
pub name: ByteVec,
pub bits: u32,
pub divisor: f32,
pub flags: u32,
}
#[repr(u32)]
pub enum DeltaType {
Byte = 1,
Short = 1 << 1,
Float = 1 << 2,
Integer = 1 << 3,
Angle = 1 << 4,
TimeWindow8 = 1 << 5,
TimeWindowBig = 1 << 6,
String = 1 << 7,
Signed = 1 << 31,
}
#[derive(Debug, Clone)]
pub enum NetMessage {
UserMessage(UserMessage),
EngineMessage(Box<EngineMessage>),
}
pub type CustomMessage = HashMap<u8, SvcNewUserMsg>;
#[derive(Debug, Clone)]
pub struct UserMessage {
pub id: u8,
pub name: ByteVec,
pub data: ByteVec,
}
#[repr(u8)]
#[derive(Debug, Clone)]
pub enum EngineMessage {
SvcBad = 0,
SvcNop = 1,
SvcDisconnect(SvcDisconnect) = 2,
SvcEvent(SvcEvent) = 3,
SvcVersion(SvcVersion) = 4,
SvcSetView(SvcSetView) = 5,
SvcSound(Box<SvcSound>) = 6,
SvcTime(SvcTime) = 7,
SvcPrint(SvcPrint) = 8,
SvcStuffText(SvcStuffText) = 9,
SvcSetAngle(SvcSetAngle) = 10,
SvcServerInfo(SvcServerInfo) = 11,
SvcLightStyle(SvcLightStyle) = 12,
SvcUpdateUserInfo(SvcUpdateUserInfo) = 13,
SvcDeltaDescription(SvcDeltaDescription) = 14,
SvcClientData(SvcClientData) = 15,
SvcStopSound(SvcStopSound) = 16,
SvcPings(SvcPings) = 17,
SvcParticle(SvcParticle) = 18,
SvcDamage = 19,
SvcSpawnStatic(SvcSpawnStatic) = 20,
SvcEventReliable(SvcEventReliable) = 21,
SvcSpawnBaseline(SvcSpawnBaseline) = 22,
SvcTempEntity(SvcTempEntity) = 23,
SvcSetPause(SvcSetPause) = 24,
SvcSignOnNum(SvcSignOnNum) = 25,
SvcCenterPrint(SvcCenterPrint) = 26,
SvcKilledMonster = 27,
SvcFoundSecret = 28,
SvcSpawnStaticSound(SvcSpawnStaticSound) = 29,
SvcIntermission = 30,
SvcFinale(SvcFinale) = 31,
SvcCdTrack(SvcCdTrack) = 32,
SvcRestore(SvcRestore) = 33,
SvcCutscene(SvcCutscene) = 34,
SvcWeaponAnim(SvcWeaponAnim) = 35,
SvcDecalName(SvcDecalName) = 36,
SvcRoomType(SvcRoomType) = 37,
SvcAddAngle(SvcAddAngle) = 38,
SvcNewUserMsg(SvcNewUserMsg) = 39,
SvcPacketEntities(SvcPacketEntities) = 40,
SvcDeltaPacketEntities(SvcDeltaPacketEntities) = 41,
SvcChoke = 42,
SvcResourceList(SvcResourceList) = 43,
SvcNewMovevars(SvcNewMovevars) = 44,
SvcResourceRequest(SvcResourceRequest) = 45,
SvcCustomization(SvcCustomization) = 46,
SvcCrosshairAngle(SvcCrosshairAngle) = 47,
SvcSoundFade(SvcSoundFade) = 48,
SvcFileTxferFailed(SvcFileTxferFailed) = 49,
SvcHltv(SvcHltv) = 50,
SvcDirector(SvcDirector) = 51,
SvcVoiceInit(SvcVoiceInit) = 52,
SvcVoiceData(SvcVoiceData) = 53,
SvcSendExtraInfo(SvcSendExtraInfo) = 54,
SvcTimeScale(SvcTimeScale) = 55,
SvcResourceLocation(SvcResourceLocation) = 56,
SvcSendCvarValue(SvcSendCvarValue) = 57,
SvcSendCvarValue2(SvcSendCvarValue2) = 58,
}
#[derive(Debug, Clone)]
pub struct SvcDisconnect {
pub reason: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcEvent {
pub event_count: BitVec,
pub events: Vec<EventS>,
}
#[derive(Debug, Clone)]
pub struct EventS {
pub event_index: BitVec,
pub has_packet_index: bool,
pub packet_index: Option<BitVec>,
pub has_delta: Option<bool>,
pub delta: Option<Delta>,
pub has_fire_time: bool,
pub fire_time: Option<BitVec>,
}
#[derive(Debug, Clone)]
pub struct SvcVersion {
pub protocol_version: u32,
}
#[derive(Debug, Clone)]
pub struct SvcSetView {
pub entity_index: i16,
}
#[derive(Debug, Clone)]
pub struct SvcSound {
pub flags: BitVec,
pub volume: Option<BitVec>,
pub attenuation: Option<BitVec>,
pub channel: BitVec,
pub entity_index: BitVec,
pub sound_index_long: Option<BitVec>,
pub sound_index_short: Option<BitVec>,
pub has_x: bool,
pub has_y: bool,
pub has_z: bool,
pub origin_x: Option<OriginCoord>,
pub origin_y: Option<OriginCoord>,
pub origin_z: Option<OriginCoord>,
pub pitch: BitVec,
}
#[derive(Debug, Clone)]
pub struct OriginCoord {
pub int_flag: bool,
pub fraction_flag: bool,
pub is_negative: Option<bool>,
pub int_value: Option<BitVec>,
pub fraction_value: Option<BitVec>,
}
#[derive(Debug, Clone)]
pub struct SvcTime {
pub time: f32,
}
#[derive(Debug, Clone)]
pub struct SvcPrint {
pub message: ByteString,
}
#[derive(Debug, Clone)]
pub struct SvcStuffText {
pub command: ByteString,
}
#[derive(Debug, Clone)]
pub struct SvcSetAngle {
pub pitch: i16,
pub yaw: i16,
pub roll: i16,
}
#[derive(Debug, Clone)]
pub struct SvcServerInfo {
pub protocol: i32,
pub spawn_count: i32,
pub map_checksum: i32,
pub client_dll_hash: ByteString,
pub max_players: u8,
pub player_index: u8,
pub is_deathmatch: u8,
pub game_dir: ByteVec,
pub hostname: ByteVec,
pub map_file_name: ByteVec,
pub map_cycle: ByteVec,
pub unknown: u8,
}
#[derive(Debug, Clone)]
pub struct SvcLightStyle {
pub index: u8,
pub light_info: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcUpdateUserInfo {
pub index: u8,
pub id: u32,
pub user_info: ByteString,
pub cd_key_hash: ByteString,
}
#[derive(Debug, Clone)]
pub struct SvcDeltaDescription {
pub name: ByteVec,
pub total_fields: u16,
pub fields: DeltaDecoder,
pub clone: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcClientData {
pub has_delta_update_mask: bool,
pub delta_update_mask: Option<BitVec>,
pub client_data: Delta,
pub weapon_data: Option<Vec<ClientDataWeaponData>>,
}
#[derive(Debug, Clone)]
pub struct ClientDataWeaponData {
pub weapon_index: BitVec,
pub weapon_data: Delta,
}
#[derive(Debug, Clone)]
pub struct SvcStopSound {
pub entity_index: i16,
}
#[derive(Debug, Clone)]
pub struct SvcPings {
pub pings: Vec<PingS>,
}
#[derive(Debug, Clone)]
pub struct PingS {
pub has_ping_data: bool,
pub player_id: Option<u8>,
pub ping: Option<u8>,
pub loss: Option<u8>,
}
#[derive(Debug, Clone)]
pub struct SvcParticle {
pub origin: Vec<i16>,
pub direction: ByteVec,
pub count: u8,
pub color: u8,
}
#[derive(Debug, Clone)]
pub struct SvcSpawnStatic {
pub model_index: i16,
pub sequence: i8,
pub frame: i8,
pub color_map: i16,
pub skin: i8,
pub origin_x: i16,
pub rotation_x: i8,
pub origin_y: i16,
pub rotation_y: i8,
pub origin_z: i16,
pub rotation_z: i8,
pub has_render_mode: i8,
pub render_color: Option<ByteVec>,
}
#[derive(Debug, Clone)]
pub struct SvcEventReliable {
pub event_index: BitVec,
pub event_args: Delta,
pub has_fire_time: bool,
pub fire_time: Option<BitVec>,
}
#[derive(Debug, Clone)]
pub struct SvcSpawnBaseline {
pub entities: Vec<EntityS>,
pub total_extra_data: BitVec,
pub extra_data: Vec<Delta>,
}
#[derive(Debug, Clone)]
pub struct EntityS {
pub entity_index: u16,
pub index: BitVec,
pub type_: BitVec,
pub delta: Delta,
}
#[derive(Debug, Clone)]
pub struct SvcTempEntity {
pub entity_type: u8,
pub entity: TempEntity,
}
#[repr(u8)]
#[derive(Debug, Clone)]
pub enum TempEntity {
TeBeamPoints(TeBeamPoints) = 0,
TeBeamEntPoint(ByteVec) = 1,
TeGunshot(ByteVec) = 2,
TeExplosion(ByteVec) = 3,
TeTarExplosion(ByteVec) = 4,
TeSmoke(ByteVec) = 5,
TeTracer(ByteVec) = 6,
TeLightning(ByteVec) = 7,
TeBeamEnts(ByteVec) = 8,
TeSparks(ByteVec) = 9,
TeLavaSplash(ByteVec) = 10,
TeTeleport(ByteVec) = 11,
TeExplosion2(ByteVec) = 12,
TeBspDecal(TeBspDecal) = 13,
TeImplosion(ByteVec) = 14,
TeSpriteTrail(ByteVec) = 15,
TeSprite(ByteVec) = 17,
TeBeamSprite(ByteVec) = 18,
TeBeamTorus(ByteVec) = 19,
TeBeamDisk(ByteVec) = 20,
TeBeamCylinder(ByteVec) = 21,
TeBeamFollow(ByteVec) = 22,
TeGlowSprite(ByteVec) = 23,
TeBeamRing(ByteVec) = 24,
TeStreakSplash(ByteVec) = 25,
TeDLight(ByteVec) = 27,
TeELight(ByteVec) = 28,
TeTextMessage(TeTextMessage) = 29,
TeLine(ByteVec) = 30,
TeBox(ByteVec) = 31,
TeKillBeam(ByteVec) = 99,
TeLargeFunnel(ByteVec) = 100,
TeBloodStream(ByteVec) = 101,
TeShowLine(ByteVec) = 102,
TeBlood(ByteVec) = 103,
TeDecal(ByteVec) = 104,
TeFizz(ByteVec) = 105,
TeModel(ByteVec) = 106,
TeExplodeModel(ByteVec) = 107,
TeBreakModel(ByteVec) = 108,
TeGunshotDecal(ByteVec) = 109,
TeSpriteSpray(ByteVec) = 110,
TeArmorRicochet(ByteVec) = 111,
TePlayerDecal(ByteVec) = 112,
TeBubbles(ByteVec) = 113,
TeBubbleTrail(ByteVec) = 114,
TeBloodSprite(ByteVec) = 115,
TeWorldDecal(ByteVec) = 116,
TeWorldDecalHigh(ByteVec) = 117,
TeDecalHigh(ByteVec) = 118,
TeProjectile(ByteVec) = 119,
TeSpray(ByteVec) = 120,
TePlayerSprites(ByteVec) = 121,
TeParticleBurst(ByteVec) = 122,
TeFireField(ByteVec) = 123,
TePlayerAttachment(ByteVec) = 124,
TeKillPlayerAttachment(ByteVec) = 125,
TeMultigunShot(ByteVec) = 126,
TeUserTracer(ByteVec) = 127,
}
impl TempEntity {
pub fn id(&self) -> u8 {
match self {
TempEntity::TeBeamPoints(_) => 0,
TempEntity::TeBeamEntPoint(_) => 1,
TempEntity::TeGunshot(_) => 2,
TempEntity::TeExplosion(_) => 3,
TempEntity::TeTarExplosion(_) => 4,
TempEntity::TeSmoke(_) => 5,
TempEntity::TeTracer(_) => 6,
TempEntity::TeLightning(_) => 7,
TempEntity::TeBeamEnts(_) => 8,
TempEntity::TeSparks(_) => 9,
TempEntity::TeLavaSplash(_) => 10,
TempEntity::TeTeleport(_) => 11,
TempEntity::TeExplosion2(_) => 12,
TempEntity::TeBspDecal(_) => 13,
TempEntity::TeImplosion(_) => 14,
TempEntity::TeSpriteTrail(_) => 15,
TempEntity::TeSprite(_) => 17,
TempEntity::TeBeamSprite(_) => 18,
TempEntity::TeBeamTorus(_) => 19,
TempEntity::TeBeamDisk(_) => 20,
TempEntity::TeBeamCylinder(_) => 21,
TempEntity::TeBeamFollow(_) => 22,
TempEntity::TeGlowSprite(_) => 23,
TempEntity::TeBeamRing(_) => 24,
TempEntity::TeStreakSplash(_) => 25,
TempEntity::TeDLight(_) => 27,
TempEntity::TeELight(_) => 28,
TempEntity::TeTextMessage(_) => 29,
TempEntity::TeLine(_) => 30,
TempEntity::TeBox(_) => 31,
TempEntity::TeKillBeam(_) => 99,
TempEntity::TeLargeFunnel(_) => 100,
TempEntity::TeBloodStream(_) => 101,
TempEntity::TeShowLine(_) => 102,
TempEntity::TeBlood(_) => 103,
TempEntity::TeDecal(_) => 104,
TempEntity::TeFizz(_) => 105,
TempEntity::TeModel(_) => 106,
TempEntity::TeExplodeModel(_) => 107,
TempEntity::TeBreakModel(_) => 108,
TempEntity::TeGunshotDecal(_) => 109,
TempEntity::TeSpriteSpray(_) => 110,
TempEntity::TeArmorRicochet(_) => 111,
TempEntity::TePlayerDecal(_) => 112,
TempEntity::TeBubbles(_) => 113,
TempEntity::TeBubbleTrail(_) => 114,
TempEntity::TeBloodSprite(_) => 115,
TempEntity::TeWorldDecal(_) => 116,
TempEntity::TeWorldDecalHigh(_) => 117,
TempEntity::TeDecalHigh(_) => 118,
TempEntity::TeProjectile(_) => 119,
TempEntity::TeSpray(_) => 120,
TempEntity::TePlayerSprites(_) => 121,
TempEntity::TeParticleBurst(_) => 122,
TempEntity::TeFireField(_) => 123,
TempEntity::TePlayerAttachment(_) => 124,
TempEntity::TeKillPlayerAttachment(_) => 125,
TempEntity::TeMultigunShot(_) => 126,
TempEntity::TeUserTracer(_) => 127,
}
}
}
#[derive(Debug, Clone)]
pub struct TeBeamPoints {
pub start_position: Vec<i16>,
pub end_position: Vec<i16>,
pub sprite_index: i16,
pub start_frame: u8,
pub frame_rate: u8,
pub life: u8,
pub width: u8,
pub noise: u8,
pub color: ByteVec,
pub speed: u8,
}
#[derive(Debug, Clone)]
pub struct TeBeamEntPoint {
pub start_entity: i16,
pub end_position: Vec<i16>,
pub sprite_index: i16,
pub start_frame: u8,
pub frame_rate: u8,
pub life: u8,
pub width: u8,
pub noise: u8,
pub color: ByteVec,
pub speed: u8,
}
#[derive(Debug, Clone)]
pub struct TeGunShot {
pub position: Vec<i16>,
}
#[derive(Debug, Clone)]
pub struct TeExplosion {
pub position: Vec<i16>,
pub sprite_index: i16,
pub scale: u8,
pub frame_rame: u8,
pub flags: u8,
}
#[derive(Debug, Clone)]
pub struct TeTarExplosion {
pub position: Vec<i16>,
}
#[derive(Debug, Clone)]
pub struct TeSmoke {
pub position: Vec<i16>,
pub sprite_index: i16,
pub scale: u8,
pub frame_rate: u8,
}
#[derive(Debug, Clone)]
pub struct TeTracer {
pub start_position: Vec<i16>,
pub end_position: Vec<i16>,
}
#[derive(Debug, Clone)]
pub struct TeLightning {
pub start_position: Vec<i16>,
pub end_position: Vec<i16>,
pub life: u8,
pub width: u8,
pub noise: u8,
pub model_index: i16,
}
#[derive(Debug, Clone)]
pub struct TeBeamEnts {
pub start_entity: i16,
pub end_entity: i16,
pub sprite_index: i16,
pub start_frame: u8,
pub life: u8,
pub width: u8,
pub noise: u8,
pub color: ByteVec,
pub speed: u8,
}
#[derive(Debug, Clone)]
pub struct TeSparks {
pub position: Vec<i16>,
}
#[derive(Debug, Clone)]
pub struct TeLavaSplash {
pub position: Vec<i16>,
}
#[derive(Debug, Clone)]
pub struct TeTeleport {
pub position: Vec<i16>,
}
#[derive(Debug, Clone)]
pub struct TeExplosion2 {
pub position: Vec<i16>,
pub color: u8,
pub count: u8,
}
#[derive(Debug, Clone)]
pub struct TeBspDecal {
pub unknown1: ByteVec,
pub entity_index: i16,
pub unknown2: Option<ByteVec>,
}
#[derive(Debug, Clone)]
pub struct TeImplosion {
pub position: Vec<i16>,
pub radius: u8,
pub count: u8,
pub life: u8,
}
#[derive(Debug, Clone)]
pub struct TeSpriteTrail {
pub start_position: Vec<i16>,
pub end_position: Vec<i16>,
pub sprite_index: i16,
pub count: u8,
pub life: u8,
pub scale: u8,
pub velocity: u8,
pub velocity_randomness: u8,
}
#[derive(Debug, Clone)]
pub struct TeSprite {
pub position: Vec<i16>,
pub sprite_index: i16,
pub scale: u8,
pub brightness: u8,
}
#[derive(Debug, Clone)]
pub struct TeBeamSprite {
pub start_position: Vec<i16>,
pub end_position: Vec<i16>,
pub beam_sprite_index: i16,
pub end_sprite_index: i16,
}
#[derive(Debug, Clone)]
pub struct TeBeamTorus {
pub position: Vec<i16>,
pub axis: Vec<i16>,
pub sprite_index: i16,
pub start_frame: u8,
pub life: u8,
pub width: u8,
pub noise: u8,
pub color: ByteVec,
pub speed: u8,
}
#[derive(Debug, Clone)]
pub struct TeBeamDisk {
pub position: Vec<i16>,
pub axis: Vec<i16>,
pub sprite_index: i16,
pub start_frame: u8,
pub life: u8,
pub width: u8,
pub noise: u8,
pub color: ByteVec,
pub speed: u8,
}
#[derive(Debug, Clone)]
pub struct TeBeamCylinder {
pub position: Vec<i16>,
pub axis: Vec<i16>,
pub sprite_index: i16,
pub start_frame: u8,
pub life: u8,
pub width: u8,
pub noise: u8,
pub color: ByteVec,
pub speed: u8,
}
#[derive(Debug, Clone)]
pub struct TeBeamFollow {
pub start_entity: i16,
pub sprite_index: i16,
pub start_frame: u8,
pub life: u8,
pub width: u8,
pub color: ByteVec,
}
#[derive(Debug, Clone)]
pub struct TeGlowSprite {
pub position: Vec<i16>,
pub model_index: i16,
pub scale: u8,
pub size: u8,
pub brightness: u8,
}
#[derive(Debug, Clone)]
pub struct TeBeamRing {
pub start_entity: i16,
pub end_entity: i16,
pub sprite_index: i16,
pub start_frame: u8,
pub frame_rate: u8,
pub life: u8,
pub width: u8,
pub noise: u8,
pub color: ByteVec,
pub speed: u8,
}
#[derive(Debug, Clone)]
pub struct TeStreakSplash {
pub start_position: Vec<i16>,
pub vector: Vec<i16>,
pub color: i16,
pub count: u8,
pub velocity: i16,
pub velocity_randomness: i16,
}
#[derive(Debug, Clone)]
pub struct TeDLight {
pub position: Vec<i16>,
pub radius: u8,
pub color: ByteVec,
pub life: u8,
pub decay_rate: u8,
}
#[derive(Debug, Clone)]
pub struct TeELight {
pub entity_index: i16,
pub position: Vec<i16>,
pub radius: i16,
pub color: ByteVec,
pub life: u8,
pub decay_rate: i16,
}
#[derive(Debug, Clone)]
pub struct TeTextMessage {
pub channel: i8,
pub x: i16,
pub y: i16,
pub effect: i8,
pub text_color: ByteVec,
pub effect_color: ByteVec,
pub fade_in_time: i16,
pub fade_out_time: i16,
pub hold_time: i16,
pub effect_time: Option<i16>,
pub message: ByteString,
}
#[derive(Debug, Clone)]
pub struct TeLine {
pub start_position: Vec<i16>,
pub end_position: Vec<i16>,
pub life: i16,
pub color: ByteVec,
}
#[derive(Debug, Clone)]
pub struct TeBox {
pub start_position: Vec<i16>,
pub end_position: Vec<i16>,
pub life: i16,
pub color: ByteVec,
}
#[derive(Debug, Clone)]
pub struct TeKillBeam {
pub entity_index: i16,
}
#[derive(Debug, Clone)]
pub struct TeLargeFunnel {
pub start_position: Vec<i16>,
pub entity_index: i16,
pub flags: i16,
}
#[derive(Debug, Clone)]
pub struct TeBloodStream {
pub position: Vec<i16>,
pub vector: i16,
pub color: u8,
pub count: u8,
}
#[derive(Debug, Clone)]
pub struct TeShowLine {
pub start_position: Vec<i16>,
pub end_position: Vec<i16>,
}
#[derive(Debug, Clone)]
pub struct TeBlood {
pub position: Vec<i16>,
pub vector: i16,
pub color: u8,
pub count: u8,
}
#[derive(Debug, Clone)]
pub struct TeDecal {
pub positiion: Vec<i16>,
pub decal_index: u8,
pub entity_index: i16,
}
#[derive(Debug, Clone)]
pub struct TeFizz {
pub entity_index: i16,
pub model_index: i16,
pub scale: u8,
}
#[derive(Debug, Clone)]
pub struct TeModel {
pub position: Vec<i16>,
pub velocity: Vec<i16>,
pub angle_yaw: u8,
pub model_index: i16,
pub flags: u8,
pub life: u8,
}
#[derive(Debug, Clone)]
pub struct TeExplodeModel {
pub position: Vec<i16>,
pub velocity: Vec<i16>,
pub model_index: i16,
pub count: i16,
pub life: u8,
}
#[derive(Debug, Clone)]
pub struct TeBreakModel {
pub position: Vec<i16>,
pub size: Vec<i16>,
pub velocity: Vec<i16>,
pub velocity_randomness: u8,
pub object_index: i16,
pub count: u8,
pub life: u8,
pub flags: u8,
}
#[derive(Debug, Clone)]
pub struct TeGunshotDecal {
pub position: Vec<i16>,
pub entity_index: i16,
pub decal: u8,
}
#[derive(Debug, Clone)]
pub struct TeSpriteSpray {
pub position: Vec<i16>,
pub velocity: Vec<i16>,
pub model_index: i16,
pub count: u8,
pub speed: u8,
pub random: u8,
}
#[derive(Debug, Clone)]
pub struct TeArmorRicochet {
pub position: Vec<i16>,
pub scale: u8,
}
#[derive(Debug, Clone)]
pub struct TePlayerDecal {
pub player_index: u8,
pub position: Vec<i16>,
pub entity_index: i16,
pub decal_index: u8,
}
#[derive(Debug, Clone)]
pub struct TeBubbles {
pub min_start_positition: Vec<i16>,
pub max_start_position: Vec<i16>,
pub scale: i16,
pub model_index: i16,
pub count: u8,
pub speed: i16,
}
#[derive(Debug, Clone)]
pub struct TeBubbleTrail {
pub min_start_positition: Vec<i16>,
pub max_start_position: Vec<i16>,
pub scale: i16,
pub model_index: i16,
pub count: u8,
pub speed: i16,
}
#[derive(Debug, Clone)]
pub struct TeBloodSprite {
pub position: Vec<i16>,
pub model_index: i16,
pub decal_index: i16,
pub color: u8,
pub scale: u8,
}
#[derive(Debug, Clone)]
pub struct TeWorldDecal {
pub position: Vec<i16>,
pub texture_index: u8,
}
#[derive(Debug, Clone)]
pub struct TeWorldDecalHigh {
pub position: Vec<i16>,
pub texture_index: u8,
}
#[derive(Debug, Clone)]
pub struct TeDecalHigh {
pub position: Vec<i16>,
pub decal_index: u8,
pub entity_index: i16,
}
#[derive(Debug, Clone)]
pub struct TeProjectile {
pub position: Vec<i16>,
pub velocity: Vec<i16>,
pub model_index: i16,
pub life: u8,
pub color: u8,
}
#[derive(Debug, Clone)]
pub struct TeSpray {
pub position: Vec<i16>,
pub direction: Vec<i16>,
pub model_index: i16,
pub count: u8,
pub life: u8,
pub owner: u8,
}
#[derive(Debug, Clone)]
pub struct TePlayerSprites {
pub entity_index: i16,
pub model_index: i16,
pub count: u8,
pub variance: u8,
}
#[derive(Debug, Clone)]
pub struct TeParticleBurst {
pub origin: Vec<i16>,
pub scale: i16,
pub color: u8,
pub duration: u8,
}
#[derive(Debug, Clone)]
pub struct TeFireField {
pub origin: Vec<i16>,
pub scale: i16,
pub model_index: i16,
pub count: u8,
pub flags: u8,
pub duration: u8,
}
#[derive(Debug, Clone)]
pub struct TePlayerAttachment {
pub entity_index: u8,
pub scale: i16,
pub model_index: i16,
pub life: i16,
}
#[derive(Debug, Clone)]
pub struct TeKillPlayerAttachment {
pub entity_index: u8,
}
#[derive(Debug, Clone)]
pub struct TeMultigunShot {
pub origin: Vec<i16>,
pub direction: Vec<i16>,
pub noise: Vec<i16>,
pub count: u8,
pub decal_index: u8,
}
#[derive(Debug, Clone)]
pub struct TeUserTracer {
pub origin: Vec<i16>,
pub velocity: Vec<i16>,
pub life: u8,
pub color: u8,
pub scale: u8,
}
#[derive(Debug, Clone)]
pub struct SvcSetPause {
pub is_paused: i8,
}
#[derive(Debug, Clone)]
pub struct SvcSignOnNum {
pub sign: i8,
}
#[derive(Debug, Clone)]
pub struct SvcCenterPrint {
pub message: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcSpawnStaticSound {
pub origin: Vec<i16>,
pub sound_index: u16,
pub volume: u8,
pub attenuation: u8,
pub entity_index: u16,
pub pitch: u8,
pub flags: u8,
}
#[derive(Debug, Clone)]
pub struct SvcFinale {
pub text: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcCdTrack {
pub track: i8,
pub loop_track: i8,
}
#[derive(Debug, Clone)]
pub struct SvcRestore {
pub save_name: ByteVec,
pub map_count: u8,
pub map_names: Vec<ByteVec>,
}
#[derive(Debug, Clone)]
pub struct SvcCutscene {
pub text: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcWeaponAnim {
pub sequence_number: i8,
pub weapon_model_body_group: i8,
}
#[derive(Debug, Clone)]
pub struct SvcDecalName {
pub position_index: u8,
pub decal_name: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcRoomType {
pub room_type: u16,
}
#[derive(Debug, Clone)]
pub struct SvcAddAngle {
pub angle_to_add: i16,
}
#[derive(Debug, Clone)]
pub struct SvcNewUserMsg {
pub index: u8,
pub size: i8,
pub name: ByteString,
}
#[derive(Debug, Clone)]
pub struct SvcPacketEntities {
pub entity_count: BitVec,
pub entity_states: Vec<EntityState>,
}
#[derive(Debug, Clone)]
pub struct EntityState {
pub entity_index: u16,
pub increment_entity_number: bool,
pub is_absolute_entity_index: Option<bool>,
pub absolute_entity_index: Option<BitVec>,
pub entity_index_difference: Option<BitVec>,
pub has_custom_delta: bool,
pub has_baseline_index: bool,
pub baseline_index: Option<BitVec>,
pub delta: Delta,
}
#[derive(Debug, Clone)]
pub struct SvcDeltaPacketEntities {
pub entity_count: BitVec,
pub delta_sequence: BitVec,
pub entity_states: Vec<EntityStateDelta>,
}
#[derive(Debug, Clone)]
pub struct EntityStateDelta {
pub entity_index: u16,
pub remove_entity: bool,
pub is_absolute_entity_index: bool,
pub absolute_entity_index: Option<BitVec>,
pub entity_index_difference: Option<BitVec>,
pub has_custom_delta: Option<bool>,
pub delta: Option<Delta>,
}
#[derive(Debug, Clone)]
pub struct SvcResourceList {
pub resource_count: BitVec,
pub resources: Vec<Resource>,
pub consistencies: Vec<Consistency>,
}
#[derive(Debug, Clone)]
pub struct Resource {
pub type_: BitVec,
pub name: BitVec,
pub index: BitVec,
pub size: BitVec,
pub flags: BitVec,
pub md5_hash: Option<BitVec>,
pub has_extra_info: bool,
pub extra_info: Option<BitVec>,
}
#[derive(Debug, Clone)]
pub struct Consistency {
pub is_short_index: Option<bool>,
pub short_index: Option<BitVec>,
pub long_index: Option<BitVec>,
}
#[derive(Debug, Clone)]
pub struct SvcNewMovevars {
pub gravity: f32,
pub stop_speed: f32,
pub max_speed: f32,
pub spectator_max_speed: f32,
pub accelerate: f32,
pub airaccelerate: f32,
pub water_accelerate: f32,
pub friction: f32,
pub edge_friction: f32,
pub water_friction: f32,
pub ent_garvity: f32,
pub bounce: f32,
pub step_size: f32,
pub max_velocity: f32,
pub z_max: f32,
pub wave_height: f32,
pub footsteps: u8,
pub roll_angle: f32,
pub roll_speed: f32,
pub sky_color: Vec<f32>,
pub sky_vec: Vec<f32>,
pub sky_name: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcResourceRequest {
pub spawn_count: i32,
pub unknown: Vec<u8>,
}
#[derive(Debug, Clone)]
pub struct SvcCustomization {
pub player_index: u8,
pub type_: u8,
pub name: ByteVec,
pub index: u16,
pub download_size: u32,
pub flags: u8,
pub md5_hash: Option<ByteVec>,
}
#[derive(Debug, Clone)]
pub struct SvcCrosshairAngle {
pub pitch: i16,
pub yaw: i16,
}
#[derive(Debug, Clone)]
pub struct SvcSoundFade {
pub initial_percent: u8,
pub hold_time: u8,
pub fade_out_time: u8,
pub fade_in_time: u8,
}
#[derive(Debug, Clone)]
pub struct SvcFileTxferFailed {
pub file_name: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcHltv {
pub mode: u8,
}
#[derive(Debug, Clone)]
pub struct SvcDirector {
pub length: u8,
pub command: u8,
pub message: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcVoiceInit {
pub codec_name: ByteVec,
pub quality: i8,
}
#[derive(Debug, Clone)]
pub struct SvcVoiceData {
pub player_index: u8,
pub size: u16,
pub data: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcSendExtraInfo {
pub fallback_dir: ByteVec,
pub can_cheat: u8,
}
#[derive(Debug, Clone)]
pub struct SvcTimeScale {
pub time_scale: f32,
}
#[derive(Debug, Clone)]
pub struct SvcResourceLocation {
pub download_url: ByteVec,
}
#[derive(Debug, Clone)]
pub struct SvcSendCvarValue {
pub name: ByteString,
}
#[derive(Debug, Clone)]
pub struct SvcSendCvarValue2 {
pub request_id: u32,
pub name: ByteString,
}
#[derive(Clone)]
pub struct ByteString(pub ByteVec);
impl ByteString {
pub fn to_str(&self) -> eyre::Result<&str> {
CStr::from_bytes_until_nul(self.0.as_slice())
.map_err(|err| eyre::eyre!(err))
.and_then(|cstr| Ok(cstr.to_str()?))
}
pub fn as_slice(&self) -> &[u8] {
self.0.as_slice()
}
pub fn padded(&self, size: usize) -> Self {
let mut res = self.clone();
if size == res.0.len() {
return res;
}
res.0.resize(size, 0);
res
}
}
impl std::fmt::Debug for ByteString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("ByteString")
.field(&self.to_str().unwrap_or("cannot print").trim())
.field(&self.0)
.finish()
}
}
impl From<&[u8]> for ByteString {
fn from(value: &[u8]) -> Self {
ByteString(value.to_vec())
}
}
impl From<Vec<u8>> for ByteString {
fn from(value: Vec<u8>) -> Self {
ByteString(value)
}
}
impl From<&str> for ByteString {
fn from(value: &str) -> Self {
value.as_bytes().into()
}
}
impl From<ByteString> for Vec<u8> {
fn from(value: ByteString) -> Self {
value.0
}
}