d2_stampede/
lib.rs

1#![doc = include_str!("../README.md")]
2mod class;
3mod combat_log;
4mod decoder;
5mod entity;
6mod field;
7mod field_reader;
8mod field_value;
9mod parser;
10mod reader;
11mod serializer;
12mod string_table;
13
14/// Macro for getting property from [`Entity`].
15///
16/// # Examples
17/// ```no_compile
18/// let x: i32 = property!(entity, "property_name");
19/// let y = property!(entity, i32, "property_name");
20/// ```
21#[macro_export]
22macro_rules! property {
23    ($ent:expr, $ty:ty, $fmt:literal, $($arg:tt)*) => {
24        {
25            let x: $ty = $ent.get_property_by_name(&format!($fmt, $($arg)*))?.try_into()?;
26            x
27        }
28    };
29    ($ent:expr, $ty:ty, $fmt:literal) => {
30        {
31            let x: $ty = $ent.get_property_by_name(&format!($fmt))?.try_into()?;
32            x
33        }
34    };
35    ($ent:expr, $fmt:expr, $($arg:tt)*) => {
36        $ent.get_property_by_name(&format!($fmt, $($arg)*))?.try_into()?
37    };
38    ($ent:expr, $fmt:expr) => {{
39        $ent.get_property_by_name(&format!($fmt))?.try_into()?
40    }};
41}
42
43/// Same as [`property`] but returns `None` if property doesn't exist for given
44/// [`Entity`] or cannot be converted into given type.
45///
46/// # Examples
47/// ```no_compile
48/// let x: i32 = try_property!(entity, "property_name").unwrap_or_default();
49/// let y = try_property!(entity, i32, "property_name").unwrap_or_default();
50/// ```
51#[macro_export]
52macro_rules! try_property {
53    ($ent:expr, $ty:ty, $fmt:expr, $($arg:tt)*) => {
54        {
55            let x: Option<$ty> = $ent
56                .get_property_by_name(&format!($fmt, $($arg)*))
57                .ok()
58                .and_then(|x| {
59                    x.try_into().ok()
60                });
61            x
62        }
63    };
64
65    ($ent:expr, $ty:ty, $fmt:expr) => {
66        {
67            let x: Option<$ty> = $ent
68                .get_property_by_name(&format!($fmt))
69                .ok()
70                .and_then(|x| {
71                    x.try_into().ok()
72                });
73            x
74        }
75    };
76
77    ($ent:expr, $fmt:expr, $($arg:tt)*) => {
78        $ent
79            .get_property_by_name(&format!($fmt, $($arg)*))
80            .ok()
81            .and_then(|x| {
82                x.try_into().ok()
83            })
84    };
85
86    ($ent:expr, $fmt:expr) => {{
87        $ent
88            .get_property_by_name(&format!($fmt))
89            .ok()
90            .and_then(|x| {
91                x.try_into().ok()
92            })
93    }};
94}
95
96pub mod prelude {
97    pub use crate::combat_log::CombatLogEntry;
98    pub use crate::entity::{Entity, EntityEvents};
99    pub use crate::field_value::FieldValue;
100    pub use crate::parser::{Context, Observer, Parser};
101    pub use crate::ObserverResult;
102    pub use crate::{property, try_property};
103
104    pub use d2_stampede_macros::*;
105
106    pub use d2_stampede_protobufs::prost::Message;
107    pub use d2_stampede_protobufs::EBaseGameEvents;
108    pub use d2_stampede_protobufs::EBaseUserMessages;
109    pub use d2_stampede_protobufs::EDemoCommands;
110    pub use d2_stampede_protobufs::EDotaUserMessages;
111    pub use d2_stampede_protobufs::NetMessages;
112    pub use d2_stampede_protobufs::SvcMessages;
113}
114
115pub use crate::class::{Class, Classes};
116pub use crate::combat_log::CombatLogEntry;
117pub use crate::entity::{Entities, Entity, EntityEvents};
118pub use crate::field_value::FieldValue;
119pub use crate::parser::{Context, Observer, Parser};
120pub use crate::string_table::{StringTable, StringTableRow, StringTables};
121pub use d2_stampede_macros::*;
122
123pub mod error {
124    pub use crate::class::ClassError;
125    pub use crate::combat_log::CombatLogError;
126    pub use crate::entity::EntityError;
127    pub use crate::field_value::FieldValueError;
128    pub use crate::parser::ParserError;
129    pub use crate::serializer::SerializerError;
130    pub use crate::string_table::StringTableError;
131}
132
133pub mod proto {
134    pub use d2_stampede_protobufs::prost::Message;
135    pub use d2_stampede_protobufs::*;
136}
137
138/// Result type for observers ([`anyhow::Result`])
139pub type ObserverResult = anyhow::Result<()>;
140
141#[cfg(feature = "mimalloc")]
142use mimalloc::MiMalloc;
143#[cfg(feature = "mimalloc")]
144#[global_allocator]
145static GLOBAL: MiMalloc = MiMalloc;