1use glam::{Quat, Vec3};
2
3use uuid::Uuid;
4
5use crate::packet_types::PacketType;
6
7use super::{
8 header::{Header, PacketFrequency},
9 packet::{Packet, PacketData},
10};
11
12const AGENT_STATE_TYPING: u8 = 0x04; const AGENT_STATE_EDITING: u8 = 0x10; const AGENT_CONTROL_AT_POS: u32 = 0x00000001;
16const AGENT_CONTROL_AT_NEG: u32 = 0x00000002;
17const AGENT_CONTROL_LEFT_POS: u32 = 0x00000004;
18const AGENT_CONTROL_LEFT_NEG: u32 = 0x00000008;
19const AGENT_CONTROL_UP_POS: u32 = 0x00000010;
20const AGENT_CONTROL_UP_NEG: u32 = 0x00000020;
21const AGENT_CONTROL_PITCH_POS: u32 = 0x00000040;
22const AGENT_CONTROL_PITCH_NEG: u32 = 0x00000080;
23const AGENT_CONTROL_YAW_POS: u32 = 0x00000100;
24const AGENT_CONTROL_YAW_NEG: u32 = 0x00000200;
25const AGENT_CONTROL_FAST_AT: u32 = 0x00000400;
26const AGENT_CONTROL_FAST_LEFT: u32 = 0x00000800;
27const AGENT_CONTROL_FAST_UP: u32 = 0x00001000;
28const AGENT_CONTROL_FLY: u32 = 0x00002000;
29const AGENT_CONTROL_STOP: u32 = 0x00004000;
30const AGENT_CONTROL_FINISH_ANIM: u32 = 0x00008000;
31const AGENT_CONTROL_STAND_UP: u32 = 0x00010000;
32const AGENT_CONTROL_SIT_ON_GROUND: u32 = 0x00020000;
33const AGENT_CONTROL_MOUSELOOK: u32 = 0x00040000;
34const AGENT_CONTROL_NUDGE_AT_POS: u32 = 0x00080000;
35const AGENT_CONTROL_NUDGE_AT_NEG: u32 = 0x00100000;
36const AGENT_CONTROL_NUDGE_LEFT_POS: u32 = 0x00200000;
37const AGENT_CONTROL_NUDGE_LEFT_NEG: u32 = 0x00400000;
38const AGENT_CONTROL_NUDGE_UP_POS: u32 = 0x00800000;
39const AGENT_CONTROL_NUDGE_UP_NEG: u32 = 0x01000000;
40const AGENT_CONTROL_TURN_LEFT: u32 = 0x02000000;
41const AGENT_CONTROL_TURN_RIGHT: u32 = 0x04000000;
42const AGENT_CONTROL_AWAY: u32 = 0x08000000;
43const AGENT_CONTROL_LBUTTON_DOWN: u32 = 0x10000000;
44const AGENT_CONTROL_LBUTTON_UP: u32 = 0x20000000;
45const AGENT_CONTROL_ML_LBUTTON_DOWN: u32 = 0x40000000;
46const AGENT_CONTROL_ML_LBUTTON_UP: u32 = 0x80000000;
47
48const AU_FLAGS_NONE: u8 = 0x00;
49const AU_FLAGS_HIDETITLE: u8 = 0x01;
50
51impl Packet {
52 pub fn new_agent_update(agent_update: AgentUpdate) -> Self {
53 Packet {
54 header: Header {
55 id: 4,
56 frequency: PacketFrequency::High,
57 reliable: false,
58 sequence_number: 1,
59 appended_acks: false,
60 zerocoded: false,
61 resent: false,
62 ack_list: None,
63 size: None,
64 },
65 body: PacketType::AgentUpdate(Box::new(agent_update)),
66 }
67 }
68}
69
70#[derive(Debug, Clone)]
71pub struct State {
72 pub typing: bool,
73 pub editing: bool,
74}
75impl State {
76 pub fn from_bytes(bits: u8) -> Self {
77 Self {
78 typing: bits & AGENT_STATE_TYPING != 0,
79 editing: bits & AGENT_STATE_EDITING != 0,
80 }
81 }
82 pub fn to_bytes(&self) -> u8 {
83 let mut bits = 0u8;
84 if self.typing {
85 bits |= AGENT_STATE_TYPING;
86 }
87 if self.editing {
88 bits |= AGENT_STATE_EDITING;
89 }
90 bits
91 }
92}
93
94#[derive(Debug, Clone)]
95pub struct ControlFlags {
96 pub at_pos: bool,
97 pub at_neg: bool,
98 pub left_pos: bool,
99 pub left_neg: bool,
100 pub up_pos: bool,
101 pub up_neg: bool,
102 pub pitch_pos: bool,
103 pub pitch_neg: bool,
104 pub yaw_pos: bool,
105 pub yaw_neg: bool,
106 pub fast_at: bool,
107 pub fast_left: bool,
108 pub fast_up: bool,
109 pub fly: bool,
110 pub stop: bool,
111 pub finish_anim: bool,
112 pub stand_up: bool,
113 pub sit_on_ground: bool,
114 pub mouselook: bool,
115 pub nudge_at_pos: bool,
116 pub nudge_at_neg: bool,
117 pub nudge_left_pos: bool,
118 pub nudge_left_neg: bool,
119 pub nudge_up_pos: bool,
120 pub nudge_up_neg: bool,
121 pub turn_left: bool,
122 pub turn_right: bool,
123 pub away: bool,
124 pub l_button_down: bool,
125 pub l_button_up: bool,
126 pub ml_button_down: bool,
127 pub ml_button_up: bool,
128}
129impl ControlFlags {
130 pub fn from_bytes(bits: u32) -> Self {
131 Self {
132 at_pos: bits & AGENT_CONTROL_AT_POS != 0,
133 at_neg: bits & AGENT_CONTROL_AT_NEG != 0,
134 left_pos: bits & AGENT_CONTROL_LEFT_POS != 0,
135 left_neg: bits & AGENT_CONTROL_LEFT_NEG != 0,
136 up_pos: bits & AGENT_CONTROL_UP_POS != 0,
137 up_neg: bits & AGENT_CONTROL_UP_NEG != 0,
138 pitch_pos: bits & AGENT_CONTROL_PITCH_POS != 0,
139 pitch_neg: bits & AGENT_CONTROL_PITCH_NEG != 0,
140 yaw_pos: bits & AGENT_CONTROL_YAW_POS != 0,
141 yaw_neg: bits & AGENT_CONTROL_YAW_NEG != 0,
142 fast_at: bits & AGENT_CONTROL_FAST_AT != 0,
143 fast_left: bits & AGENT_CONTROL_FAST_LEFT != 0,
144 fast_up: bits & AGENT_CONTROL_FAST_UP != 0,
145 fly: bits & AGENT_CONTROL_FLY != 0,
146 stop: bits & AGENT_CONTROL_STOP != 0,
147 finish_anim: bits & AGENT_CONTROL_FINISH_ANIM != 0,
148 stand_up: bits & AGENT_CONTROL_STAND_UP != 0,
149 sit_on_ground: bits & AGENT_CONTROL_SIT_ON_GROUND != 0,
150 mouselook: bits & AGENT_CONTROL_MOUSELOOK != 0,
151 nudge_at_pos: bits & AGENT_CONTROL_NUDGE_AT_POS != 0,
152 nudge_at_neg: bits & AGENT_CONTROL_NUDGE_AT_NEG != 0,
153 nudge_left_pos: bits & AGENT_CONTROL_NUDGE_LEFT_POS != 0,
154 nudge_left_neg: bits & AGENT_CONTROL_NUDGE_LEFT_NEG != 0,
155 nudge_up_pos: bits & AGENT_CONTROL_NUDGE_UP_POS != 0,
156 nudge_up_neg: bits & AGENT_CONTROL_NUDGE_UP_NEG != 0,
157 turn_left: bits & AGENT_CONTROL_TURN_LEFT != 0,
158 turn_right: bits & AGENT_CONTROL_TURN_RIGHT != 0,
159 away: bits & AGENT_CONTROL_AWAY != 0,
160 l_button_down: bits & AGENT_CONTROL_LBUTTON_DOWN != 0,
161 l_button_up: bits & AGENT_CONTROL_LBUTTON_UP != 0,
162 ml_button_down: bits & AGENT_CONTROL_ML_LBUTTON_DOWN != 0,
163 ml_button_up: bits & AGENT_CONTROL_ML_LBUTTON_UP != 0,
164 }
165 }
166 pub fn to_bytes(&self) -> [u8; 4] {
167 let mut bits = 0u32;
168 if self.at_pos {
169 bits |= AGENT_CONTROL_AT_POS;
170 }
171 if self.at_neg {
172 bits |= AGENT_CONTROL_AT_NEG;
173 }
174 if self.left_pos {
175 bits |= AGENT_CONTROL_LEFT_POS;
176 }
177 if self.left_neg {
178 bits |= AGENT_CONTROL_LEFT_NEG;
179 }
180 if self.up_pos {
181 bits |= AGENT_CONTROL_UP_POS;
182 }
183 if self.up_neg {
184 bits |= AGENT_CONTROL_UP_NEG;
185 }
186 if self.pitch_pos {
187 bits |= AGENT_CONTROL_PITCH_POS;
188 }
189 if self.pitch_neg {
190 bits |= AGENT_CONTROL_PITCH_NEG;
191 }
192 if self.yaw_pos {
193 bits |= AGENT_CONTROL_YAW_POS;
194 }
195 if self.yaw_neg {
196 bits |= AGENT_CONTROL_YAW_NEG;
197 }
198 if self.fast_at {
199 bits |= AGENT_CONTROL_FAST_AT;
200 }
201 if self.fast_left {
202 bits |= AGENT_CONTROL_FAST_LEFT;
203 }
204 if self.fast_up {
205 bits |= AGENT_CONTROL_FAST_UP;
206 }
207 if self.fly {
208 bits |= AGENT_CONTROL_FLY;
209 }
210 if self.stop {
211 bits |= AGENT_CONTROL_STOP;
212 }
213 if self.finish_anim {
214 bits |= AGENT_CONTROL_FINISH_ANIM;
215 }
216 if self.stand_up {
217 bits |= AGENT_CONTROL_STAND_UP;
218 }
219 if self.sit_on_ground {
220 bits |= AGENT_CONTROL_SIT_ON_GROUND;
221 }
222 if self.mouselook {
223 bits |= AGENT_CONTROL_MOUSELOOK;
224 }
225 if self.nudge_at_pos {
226 bits |= AGENT_CONTROL_NUDGE_AT_POS;
227 }
228 if self.nudge_at_neg {
229 bits |= AGENT_CONTROL_NUDGE_AT_NEG;
230 }
231 if self.nudge_left_pos {
232 bits |= AGENT_CONTROL_NUDGE_LEFT_POS;
233 }
234 if self.nudge_left_neg {
235 bits |= AGENT_CONTROL_NUDGE_LEFT_NEG;
236 }
237 if self.nudge_up_pos {
238 bits |= AGENT_CONTROL_NUDGE_UP_POS;
239 }
240 if self.nudge_up_neg {
241 bits |= AGENT_CONTROL_NUDGE_UP_NEG;
242 }
243 if self.turn_left {
244 bits |= AGENT_CONTROL_TURN_LEFT;
245 }
246 if self.turn_right {
247 bits |= AGENT_CONTROL_TURN_RIGHT;
248 }
249 if self.away {
250 bits |= AGENT_CONTROL_AWAY;
251 }
252 if self.l_button_down {
253 bits |= AGENT_CONTROL_LBUTTON_DOWN;
254 }
255 if self.l_button_up {
256 bits |= AGENT_CONTROL_LBUTTON_UP;
257 }
258 if self.ml_button_down {
259 bits |= AGENT_CONTROL_ML_LBUTTON_DOWN;
260 }
261 if self.ml_button_up {
262 bits |= AGENT_CONTROL_ML_LBUTTON_UP;
263 }
264 bits.to_le_bytes()
265 }
266}
267
268#[derive(Debug, Clone)]
269pub struct Flags {
270 pub none: bool,
271 pub hide_title: bool,
272}
273#[allow(clippy::bad_bit_mask)]
274impl Flags {
275 pub fn from_bytes(bits: u8) -> Self {
276 Self {
277 none: bits & AU_FLAGS_NONE != 0,
278 hide_title: bits & AU_FLAGS_HIDETITLE != 0,
279 }
280 }
281 pub fn to_bytes(&self) -> u8 {
282 let mut bits = 0u8;
283 if self.none {
284 bits |= AU_FLAGS_NONE;
285 }
286 if self.hide_title {
287 bits |= AU_FLAGS_HIDETITLE;
288 }
289 bits
290 }
291}
292#[derive(Debug, Clone)]
293pub struct AgentUpdate {
294 pub agent_id: Uuid,
295 pub session_id: Uuid,
296 pub body_rotation: Quat,
297 pub head_rotation: Quat,
298 pub state: State,
299 pub camera_center: Vec3,
300 pub camera_at_axis: Vec3,
301 pub camera_left_axis: Vec3,
302 pub camera_up_axis: Vec3,
303 pub far: f32,
304 pub control_flags: ControlFlags,
305 pub flags: Flags,
306}
307
308pub trait ToFromBytes {
309 fn from_bytes(bytes: &[u8]) -> Self;
310 fn to_bytes(&self) -> [u8; 16];
311}
312
313impl ToFromBytes for Quat {
314 fn from_bytes(bytes: &[u8]) -> Self {
315 let x = f32::from_le_bytes(bytes[0..4].try_into().unwrap());
316 let y = f32::from_le_bytes(bytes[4..8].try_into().unwrap());
317 let z = f32::from_le_bytes(bytes[8..12].try_into().unwrap());
318 let w = f32::from_le_bytes(bytes[12..16].try_into().unwrap());
319 Quat::from_xyzw(x, y, z, w)
320 }
321 fn to_bytes(&self) -> [u8; 16] {
322 let mut bytes = [0u8; 16];
323 bytes[0..4].copy_from_slice(&self.w.to_le_bytes());
324 bytes[4..8].copy_from_slice(&self.x.to_le_bytes());
325 bytes[8..12].copy_from_slice(&self.y.to_le_bytes());
326 bytes[12..16].copy_from_slice(&self.z.to_le_bytes());
327 bytes
328 }
329}
330
331impl PacketData for AgentUpdate {
332 fn from_bytes(bytes: &[u8]) -> std::io::Result<Self> {
333 let agent_id = Uuid::from_slice(&bytes[0..16]).unwrap();
336 let session_id = Uuid::from_slice(&bytes[16..32]).unwrap();
337 let body_rotation = Quat::from_bytes(&bytes[32..48]);
338 let head_rotation = Quat::from_bytes(&bytes[48..64]);
339
340 let state = State::from_bytes(bytes[64]);
341 let camera_center = Vec3 {
342 x: f32::from_le_bytes(bytes[65..69].try_into().unwrap()),
343 y: f32::from_le_bytes(bytes[69..73].try_into().unwrap()),
344 z: f32::from_le_bytes(bytes[73..77].try_into().unwrap()),
345 };
346 let camera_at_axis = Vec3 {
347 x: f32::from_le_bytes(bytes[77..81].try_into().unwrap()),
348 y: f32::from_le_bytes(bytes[81..85].try_into().unwrap()),
349 z: f32::from_le_bytes(bytes[85..89].try_into().unwrap()),
350 };
351 let camera_left_axis = Vec3 {
352 x: f32::from_le_bytes(bytes[89..93].try_into().unwrap()),
353 y: f32::from_le_bytes(bytes[93..97].try_into().unwrap()),
354 z: f32::from_le_bytes(bytes[97..101].try_into().unwrap()),
355 };
356 let camera_up_axis = Vec3 {
357 x: f32::from_le_bytes(bytes[101..105].try_into().unwrap()),
358 y: f32::from_le_bytes(bytes[105..109].try_into().unwrap()),
359 z: f32::from_le_bytes(bytes[109..113].try_into().unwrap()),
360 };
361 let far = f32::from_le_bytes(bytes[113..117].try_into().unwrap());
362 let control_flags =
363 ControlFlags::from_bytes(u32::from_le_bytes(bytes[117..121].try_into().unwrap()));
364 let flags = Flags::from_bytes(bytes[121]);
365 Ok(Self {
366 agent_id,
367 session_id,
368 body_rotation,
369 head_rotation,
370 state,
371 camera_center,
372 camera_at_axis,
373 camera_left_axis,
374 camera_up_axis,
375 far,
376 control_flags,
377 flags,
378 })
379 }
380
381 fn to_bytes(&self) -> Vec<u8> {
382 let mut bytes = Vec::with_capacity(121); bytes.extend_from_slice(self.agent_id.as_bytes());
386 bytes.extend_from_slice(self.session_id.as_bytes());
387
388 bytes.extend_from_slice(&self.body_rotation.to_bytes());
390 bytes.extend_from_slice(&self.head_rotation.to_bytes());
391
392 bytes.push(self.state.to_bytes());
394
395 bytes.extend_from_slice(&self.camera_center.x.to_le_bytes());
397 bytes.extend_from_slice(&self.camera_center.y.to_le_bytes());
398 bytes.extend_from_slice(&self.camera_center.z.to_le_bytes());
399 bytes.extend_from_slice(&self.camera_at_axis.x.to_le_bytes());
400 bytes.extend_from_slice(&self.camera_at_axis.y.to_le_bytes());
401 bytes.extend_from_slice(&self.camera_at_axis.z.to_le_bytes());
402 bytes.extend_from_slice(&self.camera_left_axis.x.to_le_bytes());
403 bytes.extend_from_slice(&self.camera_left_axis.y.to_le_bytes());
404 bytes.extend_from_slice(&self.camera_left_axis.z.to_le_bytes());
405 bytes.extend_from_slice(&self.camera_up_axis.x.to_le_bytes());
406 bytes.extend_from_slice(&self.camera_up_axis.y.to_le_bytes());
407 bytes.extend_from_slice(&self.camera_up_axis.z.to_le_bytes());
408
409 bytes.extend_from_slice(&self.far.to_le_bytes());
410
411 bytes.extend_from_slice(&self.control_flags.to_bytes());
412
413 bytes.push(self.flags.to_bytes());
414
415 bytes
416 }
417}