Skip to main content

steamkit/util/
msg_util.rs

1//! The protobuf flag on message numbers.
2
3use crate::base::generated::steam_language::EMsg;
4
5/// The bit that marks a message as protobuf-backed.
6const PROTO_MASK: u32 = 0x8000_0000;
7
8/// Removes the protobuf flag from a message number.
9const EMSG_MASK: u32 = !PROTO_MASK;
10
11/// Strips the protobuf flag and returns the `EMsg`. Same as [`MsgUtil::get_msg`].
12pub fn get_msg(msg: u32) -> Option<EMsg> {
13    MsgUtil::get_msg(msg)
14}
15
16/// Strips the protobuf flag and returns the message number. Same as
17/// [`MsgUtil::get_gc_msg`].
18pub fn get_gc_msg(msg: u32) -> u32 {
19    MsgUtil::get_gc_msg(msg)
20}
21
22/// Whether the message number has the protobuf flag. Same as
23/// [`MsgUtil::is_proto_buf`].
24pub fn is_proto_buf(msg: u32) -> bool {
25    MsgUtil::is_proto_buf(msg)
26}
27
28/// Builds a message number, with the protobuf flag if asked. Same as
29/// [`MsgUtil::make_msg`].
30pub fn make_msg(msg: EMsg, protobuf: bool) -> u32 {
31    MsgUtil::make_msg(msg, protobuf)
32}
33
34/// Builds a game coordinator message number, with the protobuf flag if asked.
35/// Same as [`MsgUtil::make_gc_msg`].
36pub fn make_gc_msg(msg: u32, protobuf: bool) -> u32 {
37    MsgUtil::make_gc_msg(msg, protobuf)
38}
39
40/// Helpers for message numbers and their protobuf flag.
41#[derive(Debug)]
42pub struct MsgUtil;
43
44impl MsgUtil {
45    /// Strips the protobuf flag and returns the `EMsg`, or `None` if the number
46    /// isn't a known message.
47    pub fn get_msg(msg: u32) -> Option<EMsg> {
48        EMsg::from_value((msg & EMSG_MASK) as i32)
49    }
50
51    /// Strips the protobuf flag from an `EMsg`.
52    pub fn get_msg_from(msg: EMsg) -> Option<EMsg> {
53        EMsg::from_value((msg.value() as u32 & EMSG_MASK) as i32)
54    }
55
56    /// Strips the protobuf flag and returns the number. Use this for game
57    /// coordinator messages, whose numbers aren't in `EMsg`.
58    pub fn get_gc_msg(msg: u32) -> u32 {
59        msg & EMSG_MASK
60    }
61
62    /// Whether the message number has the protobuf flag.
63    pub fn is_proto_buf(msg: u32) -> bool {
64        (msg & PROTO_MASK) > 0
65    }
66
67    /// Always `false`: an `EMsg` can't carry the flag. Use
68    /// [`MsgUtil::is_proto_buf`] with the raw number instead.
69    pub fn is_proto_buf_from(msg: EMsg) -> bool {
70        (msg.value() as u32 & PROTO_MASK) > 0
71    }
72
73    /// Builds a message number, with the protobuf flag if asked. Returns the
74    /// raw number since a flagged value isn't a valid `EMsg`.
75    pub fn make_msg(msg: EMsg, protobuf: bool) -> u32 {
76        let raw = msg.value() as u32;
77
78        if protobuf {
79            raw | PROTO_MASK
80        } else {
81            raw
82        }
83    }
84
85    /// Builds a game coordinator message number, with the protobuf flag if asked.
86    pub fn make_gc_msg(msg: u32, protobuf: bool) -> u32 {
87        if protobuf {
88            msg | PROTO_MASK
89        } else {
90            msg
91        }
92    }
93}