steel_protocol/packets/game/
s_interact.rs1use glam::DVec3;
2use steel_macros::ServerPacket;
3use steel_utils::codec::{LpVec3, VarInt};
4use steel_utils::serial::ReadFrom;
5use steel_utils::types::InteractionHand;
6
7#[derive(ServerPacket, Clone, Debug)]
9pub struct SInteract {
10 pub entity_id: i32,
11 pub hand: InteractionHand,
12 pub location: DVec3,
13 pub using_secondary_action: bool,
14}
15
16impl ReadFrom for SInteract {
17 fn read(data: &mut std::io::Cursor<&[u8]>) -> std::io::Result<Self> {
18 Ok(Self {
19 entity_id: VarInt::read(data)?.0,
20 hand: InteractionHand::read(data)?,
21 location: LpVec3::read(data)?.0,
22 using_secondary_action: bool::read(data)?,
23 })
24 }
25}
26
27#[cfg(test)]
28mod tests {
29 use std::io::Cursor;
30
31 use steel_utils::serial::WriteTo as _;
32
33 use super::*;
34
35 #[test]
36 fn interact_packet_reads_vanilla_field_order() {
37 let mut bytes = Vec::new();
38 bytes.push(42);
39 bytes.push(1);
40 LpVec3(DVec3::new(0.25, 0.5, 0.75))
41 .write(&mut bytes)
42 .unwrap();
43 bytes.push(1);
44
45 let packet = SInteract::read(&mut Cursor::new(&bytes))
46 .unwrap_or_else(|error| panic!("interact packet should parse: {error}"));
47
48 assert_eq!(packet.entity_id, 42);
49 assert_eq!(packet.hand, InteractionHand::OffHand);
50 assert!((packet.location.x - 0.25).abs() < 0.0001);
51 assert!((packet.location.y - 0.5).abs() < 0.0001);
52 assert!((packet.location.z - 0.75).abs() < 0.0001);
53 assert!(packet.using_secondary_action);
54 }
55}