steamkit/base/
packet_base.rs1use crate::base::generated::steam_language::EMsg;
6use crate::base::generated::steam_language_internal::{
7 ExtendedClientMsgHdr, MsgHdr, MsgHdrProtoBuf, SteamSerializableDeserialize,
8};
9use crate::base::msg_base::Reader;
10use crate::error::SteamError;
11use crate::types::job_id::JobID;
12
13pub trait IPacketMsg: Send + Sync {
18 fn is_proto(&self) -> bool;
20
21 fn msg_type(&self) -> EMsg;
23
24 fn target_job_id(&self) -> JobID;
26
27 fn source_job_id(&self) -> JobID;
29
30 fn get_data(&self) -> &[u8];
32}
33
34pub fn get_msg_type_with_null_check(
37 msg: Option<&dyn IPacketMsg>,
38 name: &str,
39) -> Result<EMsg, SteamError> {
40 match msg {
41 Some(msg) => Ok(msg.msg_type()),
42 None => Err(SteamError::InvalidArgument(format!(
43 "{name} must not be null"
44 ))),
45 }
46}
47
48pub struct PacketClientMsgProtobuf {
50 msg_type: EMsg,
51 pub(crate) header: MsgHdrProtoBuf,
53 pub(crate) body_offset: u64,
55 payload: Vec<u8>,
56}
57
58impl PacketClientMsgProtobuf {
59 pub fn new(e_msg: EMsg, data: Vec<u8>) -> Result<Self, SteamError> {
62 let mut reader = Reader::new(&data);
63 let header = MsgHdrProtoBuf::read(&mut reader)?;
64 Ok(PacketClientMsgProtobuf {
65 msg_type: e_msg,
66 header,
67 body_offset: reader.position() as u64,
68 payload: data,
69 })
70 }
71
72 pub fn header(&self) -> &MsgHdrProtoBuf {
74 &self.header
75 }
76
77 pub fn body_offset(&self) -> u64 {
79 self.body_offset
80 }
81}
82
83impl IPacketMsg for PacketClientMsgProtobuf {
84 fn is_proto(&self) -> bool {
85 true
86 }
87
88 fn msg_type(&self) -> EMsg {
89 self.msg_type
90 }
91
92 fn target_job_id(&self) -> JobID {
93 JobID::from_value(self.header.proto.jobid_target.unwrap_or(u64::MAX))
94 }
95
96 fn source_job_id(&self) -> JobID {
97 JobID::from_value(self.header.proto.jobid_source.unwrap_or(u64::MAX))
98 }
99
100 fn get_data(&self) -> &[u8] {
101 &self.payload
102 }
103}
104
105pub struct PacketClientMsg {
107 msg_type: EMsg,
108 pub(crate) header: ExtendedClientMsgHdr,
110 pub(crate) body_offset: u64,
112 payload: Vec<u8>,
113}
114
115impl PacketClientMsg {
116 pub fn new(e_msg: EMsg, data: Vec<u8>) -> Result<Self, SteamError> {
119 let mut reader = Reader::new(&data);
120 let header = ExtendedClientMsgHdr::read(&mut reader)?;
121 Ok(PacketClientMsg {
122 msg_type: e_msg,
123 header,
124 body_offset: reader.position() as u64,
125 payload: data,
126 })
127 }
128
129 pub fn header(&self) -> &ExtendedClientMsgHdr {
131 &self.header
132 }
133
134 pub fn body_offset(&self) -> u64 {
136 self.body_offset
137 }
138}
139
140impl IPacketMsg for PacketClientMsg {
141 fn is_proto(&self) -> bool {
142 false
143 }
144
145 fn msg_type(&self) -> EMsg {
146 self.msg_type
147 }
148
149 fn target_job_id(&self) -> JobID {
150 JobID::from_value(self.header.target_job_id)
151 }
152
153 fn source_job_id(&self) -> JobID {
154 JobID::from_value(self.header.source_job_id)
155 }
156
157 fn get_data(&self) -> &[u8] {
158 &self.payload
159 }
160}
161
162pub struct PacketMsg {
164 msg_type: EMsg,
165 pub(crate) header: MsgHdr,
167 pub(crate) body_offset: u64,
169 payload: Vec<u8>,
170}
171
172impl PacketMsg {
173 pub fn new(e_msg: EMsg, data: Vec<u8>) -> Result<Self, SteamError> {
176 let mut reader = Reader::new(&data);
177 let header = MsgHdr::read(&mut reader)?;
178 Ok(PacketMsg {
179 msg_type: e_msg,
180 header,
181 body_offset: reader.position() as u64,
182 payload: data,
183 })
184 }
185
186 pub fn header(&self) -> &MsgHdr {
188 &self.header
189 }
190
191 pub fn body_offset(&self) -> u64 {
193 self.body_offset
194 }
195}
196
197impl IPacketMsg for PacketMsg {
198 fn is_proto(&self) -> bool {
199 false
200 }
201
202 fn msg_type(&self) -> EMsg {
203 self.msg_type
204 }
205
206 fn target_job_id(&self) -> JobID {
207 JobID::from_value(self.header.target_job_id)
208 }
209
210 fn source_job_id(&self) -> JobID {
211 JobID::from_value(self.header.source_job_id)
212 }
213
214 fn get_data(&self) -> &[u8] {
215 &self.payload
216 }
217}