1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 10:14:06 +02:00

write wip

This commit is contained in:
Robin Appelman 2021-07-15 22:41:58 +02:00
commit 5ec81e168f
4 changed files with 108 additions and 34 deletions

View file

@ -1,26 +1,28 @@
use bitbuffer::{BitRead, LittleEndian};
use bitbuffer::{BitRead, BitReadStream, Endianness};
use crate::{ReadResult, Stream};
use std::cmp::min;
use crate::ReadResult;
#[derive(Debug)]
pub struct SetConVarMessage {
vars: Vec<(String, String)>,
pub struct ConVar {
key: String,
value: String,
}
impl BitRead<'_, LittleEndian> for SetConVarMessage {
fn read(stream: &mut Stream) -> ReadResult<Self> {
let count: u8 = stream.read()?;
let mut vars: Vec<(String, String)> = Vec::with_capacity(min(count, 128) as usize);
for _ in 0..count {
let key = stream
.read()
.unwrap_or_else(|_| "Malformed cvar name".to_string());
let value = stream
.read()
.unwrap_or_else(|_| "Malformed cvar value".to_string());
vars.push((key, value));
}
Ok(SetConVarMessage { vars })
impl<E: Endianness> BitRead<'_, E> for ConVar {
fn read(stream: &mut BitReadStream<'_, E>) -> ReadResult<Self> {
let key = stream
.read()
.unwrap_or_else(|_| "Malformed cvar name".to_string());
let value = stream
.read()
.unwrap_or_else(|_| "Malformed cvar value".to_string());
Ok(ConVar { key, value })
}
}
#[derive(Debug, BitRead)]
pub struct SetConVarMessage {
length: u8,
#[size = "length"]
vars: Vec<ConVar>,
}

View file

@ -1,4 +1,4 @@
use bitbuffer::{BitRead, LittleEndian};
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
use num_enum::TryFromPrimitive;
use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
@ -79,7 +79,21 @@ pub enum UserMessage<'a> {
Train(TrainMessage),
VoiceSubtitle(VoiceSubtitleMessage),
Shake(ShakeMessage),
Unknown(UnknownUserMessage<'a>),
Unknown(UserMessageType, UnknownUserMessage<'a>),
}
impl UserMessage<'_> {
pub fn message_type(&self) -> UserMessageType {
match self {
UserMessage::SayText2(_) => UserMessageType::SayText2,
UserMessage::Text(_) => UserMessageType::TextMsg,
UserMessage::ResetHUD(_) => UserMessageType::ResetHUD,
UserMessage::Train(_) => UserMessageType::Train,
UserMessage::VoiceSubtitle(_) => UserMessageType::VoiceSubtitle,
UserMessage::Shake(_) => UserMessageType::Shake,
UserMessage::Unknown(ty, _) => *ty,
}
}
}
impl<'a> BitRead<'a, LittleEndian> for UserMessage<'a> {
@ -95,7 +109,7 @@ impl<'a> BitRead<'a, LittleEndian> for UserMessage<'a> {
UserMessageType::Train => UserMessage::Train(data.read()?),
UserMessageType::VoiceSubtitle => UserMessage::VoiceSubtitle(data.read()?),
UserMessageType::Shake => UserMessage::Shake(data.read()?),
_ => UserMessage::Unknown(data.read()?),
_ => UserMessage::Unknown(message_type, data.read()?),
};
Ok(message)
}
@ -107,6 +121,23 @@ impl<'a> BitRead<'a, LittleEndian> for UserMessage<'a> {
}
}
impl<'a> BitWrite<LittleEndian> for UserMessage<'a> {
fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
(self.message_type() as u8).write(stream)?;
stream.reserve_length(11, |stream| match self {
UserMessage::SayText2(body) => stream.write(body),
UserMessage::Text(body) => stream.write(body),
UserMessage::ResetHUD(body) => stream.write(body),
UserMessage::Train(body) => stream.write(body),
UserMessage::VoiceSubtitle(body) => stream.write(body),
UserMessage::Shake(body) => stream.write(body),
UserMessage::Unknown(_, body) => stream.write(body),
})?;
Ok(())
}
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)]
pub enum ChatMessageKind {
#[serde(rename = "TF_Chat_All")]
@ -138,6 +169,21 @@ impl BitRead<'_, LittleEndian> for ChatMessageKind {
}
}
impl BitWrite<LittleEndian> for ChatMessageKind {
fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
match self {
ChatMessageKind::ChatAll => "TF_Chat_All",
ChatMessageKind::ChatTeam => "TF_Chat_Team",
ChatMessageKind::ChatAllDead => "TF_Chat_AllDead",
ChatMessageKind::ChatTeamDead => "TF_Chat_Team_Dead",
ChatMessageKind::ChatAllSpec => "TF_Chat_AllSpec",
ChatMessageKind::NameChange => "#TF_Name_Change",
ChatMessageKind::Empty => "",
}
.write(stream)
}
}
#[derive(Debug, Clone)]
pub struct SayText2Message {
pub client: u8,
@ -218,7 +264,26 @@ impl BitRead<'_, LittleEndian> for SayText2Message {
}
}
#[derive(BitRead, Debug, Clone)]
impl BitWrite<LittleEndian> for SayText2Message {
fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
self.client.write(stream)?;
self.raw.write(stream)?;
let from = self.from.as_deref().unwrap_or_default();
if self.kind == ChatMessageKind::ChatAllDead {
let raw = format!("*DEAD* \x03${}\x01: {}", from, self.text);
raw.write(stream)?;
} else {
self.kind.write(stream)?;
from.write(stream)?;
self.text.write(stream)?;
}
Ok(())
}
}
#[derive(BitRead, BitWrite, Debug, Clone)]
#[discriminant_bits = 8]
pub enum HudTextLocation {
PrintNotify = 1,
@ -227,32 +292,31 @@ pub enum HudTextLocation {
PrintCenter,
}
#[derive(BitRead, Debug, Clone)]
#[derive(BitRead, BitWrite, Debug, Clone)]
pub struct TextMessage {
pub location: HudTextLocation,
pub text: String,
#[size = 4]
pub substitute: Vec<String>,
pub substitute: [String; 4],
}
#[derive(BitRead, Debug, Clone)]
#[derive(BitRead, BitWrite, Debug, Clone)]
pub struct ResetHudMessage {
pub data: u8,
}
#[derive(BitRead, Debug, Clone)]
#[derive(BitRead, BitWrite, Debug, Clone)]
pub struct TrainMessage {
pub data: u8,
}
#[derive(BitRead, Debug, Clone)]
#[derive(BitRead, BitWrite, Debug, Clone)]
pub struct VoiceSubtitleMessage {
client: u8,
menu: u8,
item: u8,
}
#[derive(BitRead, Debug, Clone)]
#[derive(BitRead, BitWrite, Debug, Clone)]
pub struct ShakeMessage {
command: u8,
amplitude: f32,
@ -272,3 +336,9 @@ impl<'a> BitRead<'a, LittleEndian> for UnknownUserMessage<'a> {
})
}
}
impl<'a> BitWrite<LittleEndian> for UnknownUserMessage<'a> {
fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> ReadResult<()> {
self.data.write(stream)
}
}

View file

@ -842,7 +842,8 @@ pub fn write_bit_coord(val: f32, stream: &mut BitWriteStream<LittleEndian>) -> R
fn bit_coord_roundtrip() {
use bitbuffer::BitReadBuffer;
let mut write = BitWriteStream::new(LittleEndian);
let mut data = Vec::with_capacity(128);
let mut write = BitWriteStream::new(&mut data, LittleEndian);
write_bit_coord(0.0, &mut write).unwrap();
let pos1 = write.bit_len();
write_bit_coord(123.0, &mut write).unwrap();
@ -852,7 +853,7 @@ fn bit_coord_roundtrip() {
write_bit_coord(-0.4375, &mut write).unwrap();
let pos4 = write.bit_len();
let mut read = Stream::from(BitReadBuffer::new_owned(write.finish(), LittleEndian));
let mut read = Stream::from(BitReadBuffer::new(&data, LittleEndian));
assert_eq!(0.0, read_bit_coord(&mut read).unwrap());
assert_eq!(pos1, read.pos());
assert_eq!(123.0, read_bit_coord(&mut read).unwrap());

View file

@ -24,12 +24,13 @@ fn test_roundtrip_encode<
>(
val: T,
) {
let mut data = Vec::with_capacity(128);
use bitbuffer::{BitReadBuffer, BitReadStream, BitWriteStream, LittleEndian};
let mut stream = BitWriteStream::new(LittleEndian);
let mut stream = BitWriteStream::new(&mut data, LittleEndian);
val.write(&mut stream).unwrap();
let pos = stream.bit_len();
let mut read = BitReadStream::new(BitReadBuffer::new_owned(stream.finish(), LittleEndian));
let mut read = BitReadStream::new(BitReadBuffer::new_owned(data, LittleEndian));
assert_eq!(val, read.read().unwrap());
assert_eq!(pos, read.pos());
}