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

clippy fixes

This commit is contained in:
Robin Appelman 2023-06-03 18:30:30 +02:00
commit a561cbaf64
12 changed files with 345 additions and 398 deletions

4
Cargo.lock generated
View file

@ -90,9 +90,9 @@ dependencies = [
[[package]] [[package]]
name = "bitbuffer_derive" name = "bitbuffer_derive"
version = "0.10.0" version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4090254bfbc71442ff4a426ddba663346e26fd14b55b259281f763e350d7f621" checksum = "052a5a614540ae9bb7de25c2c86a94b6de7374cb7e3230f3128955bdaea62c3f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View file

@ -2,9 +2,8 @@ use std::env;
use std::fs; use std::fs;
use main_error::MainError; use main_error::MainError;
pub use tf_demo_parser::{Demo, DemoParser, Parse, ParseError, ParserState, Stream};
use tf_demo_parser::demo::parser::player_summary_analyzer::PlayerSummaryAnalyzer; use tf_demo_parser::demo::parser::player_summary_analyzer::PlayerSummaryAnalyzer;
pub use tf_demo_parser::{Demo, DemoParser, Parse, ParseError, ParserState, Stream};
#[cfg(feature = "jemallocator")] #[cfg(feature = "jemallocator")]
#[global_allocator] #[global_allocator]
@ -50,9 +49,7 @@ fn main() -> Result<(), MainError> {
for (user_id, user_data) in state.users { for (user_id, user_data) in state.users {
let player_name = user_data.name; let player_name = user_data.name;
let summary = state.player_summaries.get(&user_id); if let Some(s) = state.player_summaries.get(&user_id) {
match summary {
Some(s) => {
let (color_code_start, color_code_end) = if player_name == header.nick { let (color_code_start, color_code_end) = if player_name == header.nick {
// Give the line for the player a green background with white text // Give the line for the player a green background with white text
// ANSI color codes are in hex, since rust doesn't support octal literals in strings // ANSI color codes are in hex, since rust doesn't support octal literals in strings
@ -87,10 +84,6 @@ fn main() -> Result<(), MainError> {
color_code_end, color_code_end,
); );
},
None => {
// No summary for this player - they likely joined at the end of the match, or left before they did anything noteworthy
}
} }
} }
} }

View file

@ -92,9 +92,9 @@ impl<E: Endianness> BitWrite<E> for MaybeUtf8String {
} }
} }
impl Into<String> for MaybeUtf8String { impl From<MaybeUtf8String> for String {
fn into(self) -> String { fn from(str: MaybeUtf8String) -> String {
match self { match str {
MaybeUtf8String::Valid(s) => s, MaybeUtf8String::Valid(s) => s,
MaybeUtf8String::Invalid(_) => "-- Malformed utf8 --".into(), MaybeUtf8String::Invalid(_) => "-- Malformed utf8 --".into(),
} }
@ -150,7 +150,7 @@ pub struct ServerTick(u32);
impl ServerTick { impl ServerTick {
pub fn range_inclusive(&self, till: Self) -> impl Iterator<Item = Self> { pub fn range_inclusive(&self, till: Self) -> impl Iterator<Item = Self> {
(self.0..=till.0).into_iter().map(Self::from) (self.0..=till.0).map(Self::from)
} }
} }
@ -242,7 +242,7 @@ pub struct DemoTick(u32);
impl DemoTick { impl DemoTick {
pub fn range_inclusive(&self, till: Self) -> impl Iterator<Item = Self> { pub fn range_inclusive(&self, till: Self) -> impl Iterator<Item = Self> {
(self.0..=till.0).into_iter().map(Self::from) (self.0..=till.0).map(Self::from)
} }
} }

View file

@ -161,6 +161,7 @@ impl PacketEntity {
if self.update_type == UpdateType::Enter { if self.update_type == UpdateType::Enter {
let mut found_props = HashSet::<SendPropIdentifier>::new(); let mut found_props = HashSet::<SendPropIdentifier>::new();
let props = self.props.iter().cloned(); let props = self.props.iter().cloned();
#[allow(clippy::unnecessary_to_owned)]
let baseline_props = self let baseline_props = self
.get_baseline_props(parser_state) .get_baseline_props(parser_state)
.into_owned() .into_owned()

View file

@ -428,8 +428,8 @@ pub fn parse_string_table_update<'a>(
Ok(entries.into_entries()) Ok(entries.into_entries())
} }
pub fn write_string_table_update<'a>( pub fn write_string_table_update(
entries: &[(u16, StringTableEntry<'a>)], entries: &[(u16, StringTableEntry)],
stream: &mut BitWriteStream<LittleEndian>, stream: &mut BitWriteStream<LittleEndian>,
table_meta: &StringTableMeta, table_meta: &StringTableMeta,
) -> ReadResult<()> { ) -> ReadResult<()> {

View file

@ -41,10 +41,13 @@ impl ChatMessage {
} }
} }
#[derive(Debug, Clone, Serialize, Deserialize, Copy, PartialEq, Eq, Hash, TryFromPrimitive)] #[derive(
Debug, Clone, Serialize, Deserialize, Copy, PartialEq, Eq, Hash, TryFromPrimitive, Default,
)]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
#[repr(u8)] #[repr(u8)]
pub enum Team { pub enum Team {
#[default]
Other = 0, Other = 0,
Spectator = 1, Spectator = 1,
Red = 2, Red = 2,
@ -64,19 +67,14 @@ impl Team {
} }
} }
impl Default for Team {
fn default() -> Self {
Team::Other
}
}
#[derive( #[derive(
Debug, Clone, Serialize, Copy, PartialEq, Eq, Hash, TryFromPrimitive, Display, FromStr, Debug, Clone, Serialize, Copy, PartialEq, Eq, Hash, TryFromPrimitive, Display, FromStr, Default,
)] )]
#[display(style = "lowercase")] #[display(style = "lowercase")]
#[serde(rename_all = "lowercase")] #[serde(rename_all = "lowercase")]
#[repr(u8)] #[repr(u8)]
pub enum Class { pub enum Class {
#[default]
Other = 0, Other = 0,
Scout = 1, Scout = 1,
Sniper = 2, Sniper = 2,
@ -129,12 +127,6 @@ impl Class {
} }
} }
impl Default for Class {
fn default() -> Self {
Class::Other
}
}
#[derive(Default, Debug, Eq, PartialEq, Deserialize, Clone)] #[derive(Default, Debug, Eq, PartialEq, Deserialize, Clone)]
#[serde(from = "HashMap<Class, u8>")] #[serde(from = "HashMap<Class, u8>")]
pub struct ClassList([u8; 10]); pub struct ClassList([u8; 10]);
@ -476,7 +468,7 @@ impl Analyser {
{ {
self.state self.state
.users .users
.entry(user_info.player_info.user_id.into()) .entry(user_info.player_info.user_id)
.and_modify(|info| { .and_modify(|info| {
info.entity_id = user_info.entity_id; info.entity_id = user_info.entity_id;
}) })

View file

@ -21,8 +21,9 @@ use std::str::FromStr;
pub struct CachedEntities {} pub struct CachedEntities {}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq)] #[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Default)]
pub enum PlayerState { pub enum PlayerState {
#[default]
Alive = 0, Alive = 0,
Dying = 1, Dying = 1,
Death = 2, Death = 2,
@ -40,12 +41,6 @@ impl PlayerState {
} }
} }
impl Default for PlayerState {
fn default() -> Self {
PlayerState::Alive
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct Player { pub struct Player {
entity: EntityId, entity: EntityId,
@ -554,8 +549,7 @@ impl GameStateAnalyser {
.state .state
.get_or_create_building(entity.entity_index, BuildingClass::Sentry); .get_or_create_building(entity.entity_index, BuildingClass::Sentry);
match building { if let Building::Sentry(sentry) = building {
Building::Sentry(sentry) => {
for prop in entity.props(parser_state) { for prop in entity.props(parser_state) {
match prop.identifier { match prop.identifier {
ANGLE => sentry.angle = f32::try_from(&prop.value).unwrap_or_default(), ANGLE => sentry.angle = f32::try_from(&prop.value).unwrap_or_default(),
@ -568,9 +562,7 @@ impl GameStateAnalyser {
sentry.auto_aim_target = sentry.auto_aim_target =
UserId::from(i64::try_from(&prop.value).unwrap_or_default() as u16) UserId::from(i64::try_from(&prop.value).unwrap_or_default() as u16)
} }
SHELLS => { SHELLS => sentry.shells = i64::try_from(&prop.value).unwrap_or_default() as u16,
sentry.shells = i64::try_from(&prop.value).unwrap_or_default() as u16
}
ROCKETS => { ROCKETS => {
sentry.rockets = i64::try_from(&prop.value).unwrap_or_default() as u16 sentry.rockets = i64::try_from(&prop.value).unwrap_or_default() as u16
} }
@ -578,8 +570,6 @@ impl GameStateAnalyser {
} }
} }
} }
_ => {}
}
} }
pub fn handle_teleporter_entity(&mut self, entity: &PacketEntity, parser_state: &ParserState) { pub fn handle_teleporter_entity(&mut self, entity: &PacketEntity, parser_state: &ParserState) {
@ -607,13 +597,11 @@ impl GameStateAnalyser {
.state .state
.get_or_create_building(entity.entity_index, BuildingClass::Teleporter); .get_or_create_building(entity.entity_index, BuildingClass::Teleporter);
match building { if let Building::Teleporter(teleporter) = building {
Building::Teleporter(teleporter) => {
for prop in entity.props(parser_state) { for prop in entity.props(parser_state) {
match prop.identifier { match prop.identifier {
RECHARGE_TIME => { RECHARGE_TIME => {
teleporter.recharge_time = teleporter.recharge_time = f32::try_from(&prop.value).unwrap_or_default()
f32::try_from(&prop.value).unwrap_or_default()
} }
RECHARGE_DURATION => { RECHARGE_DURATION => {
teleporter.recharge_duration = teleporter.recharge_duration =
@ -624,23 +612,19 @@ impl GameStateAnalyser {
i64::try_from(&prop.value).unwrap_or_default() as u16 i64::try_from(&prop.value).unwrap_or_default() as u16
} }
OTHER_END => { OTHER_END => {
teleporter.other_end = EntityId::from( teleporter.other_end =
i64::try_from(&prop.value).unwrap_or_default() as u32, EntityId::from(i64::try_from(&prop.value).unwrap_or_default() as u32)
)
} }
YAW_TO_EXIT => { YAW_TO_EXIT => {
teleporter.yaw_to_exit = f32::try_from(&prop.value).unwrap_or_default() teleporter.yaw_to_exit = f32::try_from(&prop.value).unwrap_or_default()
} }
IS_ENTRANCE => { IS_ENTRANCE => {
teleporter.is_entrance = teleporter.is_entrance = i64::try_from(&prop.value).unwrap_or_default() == 0
i64::try_from(&prop.value).unwrap_or_default() == 0
} }
_ => {} _ => {}
} }
} }
} }
_ => {}
}
} }
pub fn handle_dispenser_entity(&mut self, entity: &PacketEntity, parser_state: &ParserState) { pub fn handle_dispenser_entity(&mut self, entity: &PacketEntity, parser_state: &ParserState) {
@ -660,13 +644,10 @@ impl GameStateAnalyser {
.state .state
.get_or_create_building(entity.entity_index, BuildingClass::Dispenser); .get_or_create_building(entity.entity_index, BuildingClass::Dispenser);
match building { if let Building::Dispenser(dispenser) = building {
Building::Dispenser(dispenser) => {
for prop in entity.props(parser_state) { for prop in entity.props(parser_state) {
match prop.identifier { match prop.identifier {
AMMO => { AMMO => dispenser.metal = i64::try_from(&prop.value).unwrap_or_default() as u16,
dispenser.metal = i64::try_from(&prop.value).unwrap_or_default() as u16
}
HEALING => { HEALING => {
let values = match &prop.value { let values = match &prop.value {
SendPropValue::Array(vec) => vec.as_slice(), SendPropValue::Array(vec) => vec.as_slice(),
@ -675,17 +656,13 @@ impl GameStateAnalyser {
dispenser.healing = values dispenser.healing = values
.iter() .iter()
.map(|val| { .map(|val| UserId::from(i64::try_from(val).unwrap_or_default() as u16))
UserId::from(i64::try_from(val).unwrap_or_default() as u16)
})
.collect() .collect()
} }
_ => {} _ => {}
} }
} }
} }
_ => {}
}
} }
fn handle_building( fn handle_building(

View file

@ -189,6 +189,7 @@ impl<'a, A: MessageHandler + BorrowMessageHandler> DemoTicker<'a, A> {
} }
/// Process the next packet /// Process the next packet
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Result<Option<Tick<A::Output>>> { pub fn next(&mut self) -> Result<Option<Tick<A::Output>>> {
Ok( Ok(
if let Some(packet) = self.packets.next(&self.handler.state_handler)? { if let Some(packet) = self.packets.next(&self.handler.state_handler)? {

View file

@ -7,6 +7,7 @@ use crate::demo::packet::stringtable::StringTableEntry;
use crate::demo::parser::analyser::UserInfo; use crate::demo::parser::analyser::UserInfo;
use crate::demo::parser::gamestateanalyser::UserId; use crate::demo::parser::gamestateanalyser::UserId;
use crate::demo::parser::handler::{BorrowMessageHandler, MessageHandler}; use crate::demo::parser::handler::{BorrowMessageHandler, MessageHandler};
use crate::demo::sendprop::SendProp;
use crate::{ParserState, ReadResult, Stream}; use crate::{ParserState, ReadResult, Stream};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::collections::{BTreeMap, HashMap}; use std::collections::{BTreeMap, HashMap};
@ -58,14 +59,11 @@ impl MessageHandler for PlayerSummaryAnalyzer {
} }
fn handle_message(&mut self, message: &Message, _tick: DemoTick, parser_state: &ParserState) { fn handle_message(&mut self, message: &Message, _tick: DemoTick, parser_state: &ParserState) {
match message { if let Message::PacketEntities(message) = message {
Message::PacketEntities(message) => {
for entity in message.entities.iter() { for entity in message.entities.iter() {
self.handle_packet_entity(&entity, parser_state); self.handle_packet_entity(entity, parser_state);
} }
} }
_ => {}
}
} }
fn into_output(self, _parser_state: &ParserState) -> <Self as MessageHandler>::Output { fn into_output(self, _parser_state: &ParserState) -> <Self as MessageHandler>::Output {
@ -111,14 +109,12 @@ fn parse_integer_prop<F>(
{ {
use crate::demo::sendprop::SendPropValue; use crate::demo::sendprop::SendPropValue;
match packet.get_prop_by_name(table, name, parser_state) { if let Some(SendProp {
Some(prop) => { value: SendPropValue::Integer(val),
match prop.value { ..
SendPropValue::Integer(val) => handler(val as u32), }) = packet.get_prop_by_name(table, name, parser_state)
_ => {} // not an integer, ignore {
} handler(val as u32);
}
None => {} // the packet doesn't have this property
} }
} }
@ -139,8 +135,7 @@ impl PlayerSummaryAnalyzer {
// println!("Got a {} data packet: {:?}", class.name, packet); // println!("Got a {} data packet: {:?}", class.name, packet);
match class.name.as_str() { match class.name.as_str() {
"CTFPlayer" => { "CTFPlayer" => {
match self.user_id_map.get(&packet.entity_index) { if let Some(user_id) = self.user_id_map.get(&packet.entity_index) {
Some(user_id) => {
let summaries = &mut self.state.player_summaries; let summaries = &mut self.state.player_summaries;
let player_summary = summaries.entry(*user_id).or_default(); let player_summary = summaries.entry(*user_id).or_default();
@ -358,11 +353,6 @@ impl PlayerSummaryAnalyzer {
}, },
); );
} }
None => {
// Player entity likely spawned before the player was assigned to it?
// This can rarely happen, but doesn't seem to affect the end result
}
}
} }
"CTFPlayerResource" => { "CTFPlayerResource" => {
// Player summaries - including entity IDs! // Player summaries - including entity IDs!
@ -370,25 +360,18 @@ impl PlayerSummaryAnalyzer {
// for example, `m_iUserID.024 = 2523` means entity 24 is user 2523 // for example, `m_iUserID.024 = 2523` means entity 24 is user 2523
for i in 0..33 { for i in 0..33 {
// 0 to 32, inclusive (1..33 might also work, not sure if there's a user 0 or not). Not exhaustive and doesn't work for servers with > 32 players // 0 to 32, inclusive (1..33 might also work, not sure if there's a user 0 or not). Not exhaustive and doesn't work for servers with > 32 players
match packet.get_prop_by_name( if let Some(SendProp {
value: SendPropValue::Integer(x),
..
}) = packet.get_prop_by_name(
"m_iUserID", "m_iUserID",
format!("{:0>3}", i).as_str(), format!("{:0>3}", i).as_str(),
parser_state, parser_state,
) { ) {
Some(prop) => {
match prop.value {
SendPropValue::Integer(x) => {
let entity_id = EntityId::from(i as u32); let entity_id = EntityId::from(i as u32);
let user_id = UserId::from(x as u32); let user_id = UserId::from(x as u32);
self.user_id_map.insert(entity_id, user_id); self.user_id_map.insert(entity_id, user_id);
} }
_ => {
// These properties should all be integers...
}
}
}
None => {} // ignore, no property for this entity was included
}
} }
} }
_other => { _other => {
@ -409,7 +392,7 @@ impl PlayerSummaryAnalyzer {
{ {
self.state self.state
.users .users
.entry(user_info.player_info.user_id.into()) .entry(user_info.player_info.user_id)
.and_modify(|info| { .and_modify(|info| {
info.entity_id = user_info.entity_id; info.entity_id = user_info.entity_id;
}) })

View file

@ -329,7 +329,7 @@ impl Baseline {
self.instances[usize::from(index)] = Some(entity); self.instances[usize::from(index)] = Some(entity);
} }
pub fn keys<'a>(&'a self) -> impl Iterator<Item = EntityId> + 'a { pub fn keys(&self) -> impl Iterator<Item = EntityId> + '_ {
self.instances self.instances
.iter() .iter()
.filter_map(|entity| entity.as_ref().map(|entity| entity.entity_id)) .filter_map(|entity| entity.as_ref().map(|entity| entity.entity_id))

View file

@ -1185,7 +1185,7 @@ impl<'de> Deserialize<'de> for SendPropIdentifier {
Ok(match raw { Ok(match raw {
Options::Num(num) => SendPropIdentifier(num), Options::Num(num) => SendPropIdentifier(num),
Options::Str(s) => { Options::Str(s) => {
let num: u64 = s.parse().map_err(|e| D::Error::custom(e))?; let num: u64 = s.parse().map_err(D::Error::custom)?;
SendPropIdentifier(num) SendPropIdentifier(num)
} }
}) })

View file

@ -65,7 +65,7 @@ fn re_encode_test(input_file: &str) {
} }
let mut re_read = BitReadStream::new(BitReadBuffer::new(&out_buffer, LittleEndian)); let mut re_read = BitReadStream::new(BitReadBuffer::new(&out_buffer, LittleEndian));
let re_decoded = Packet::parse(&mut re_read, &handler.state_handler) let re_decoded = Packet::parse(&mut re_read, &handler.state_handler)
.expect(&format!("while parsing {:?}", packet.packet_type())); .unwrap_or_else(|_| panic!("while parsing {:?}", packet.packet_type()));
assert_eq!(packet.packet_type(), re_decoded.packet_type()); assert_eq!(packet.packet_type(), re_decoded.packet_type());
match (&packet, &re_decoded) { match (&packet, &re_decoded) {
( (