metaverse_messages/
agent_update.rs

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; // 00000100 in binary
13const AGENT_STATE_EDITING: u8 = 0x10; // 00010000 in binary
14
15const 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        // THIS DOES NOT WORK AT ALL
334        // THIS WILL CRASH AND BREAK YOUR SHIT
335        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); // Total byte length
383
384        // Serialize UUIDs
385        bytes.extend_from_slice(self.agent_id.as_bytes());
386        bytes.extend_from_slice(self.session_id.as_bytes());
387
388        // Serialize Quaternions
389        bytes.extend_from_slice(&self.body_rotation.to_bytes());
390        bytes.extend_from_slice(&self.head_rotation.to_bytes());
391
392        // Serialize State
393        bytes.push(self.state.to_bytes());
394
395        // Serialize Vector3s
396        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}