packet_inspector/
packet_registry.rs

1use std::hash::{Hash, Hasher};
2use std::sync::RwLock;
3
4use bytes::Bytes;
5use time::OffsetDateTime;
6use valence_protocol::decode::PacketFrame;
7use valence_protocol::{CompressionThreshold, PacketSide, PacketState};
8
9pub struct PacketRegistry {
10    packets: RwLock<Vec<Packet>>,
11    receiver: flume::Receiver<Packet>,
12    sender: flume::Sender<Packet>,
13}
14
15#[allow(unused)]
16impl PacketRegistry {
17    pub fn new() -> Self {
18        let (sender, receiver) = flume::unbounded::<Packet>();
19
20        Self {
21            packets: RwLock::new(Vec::new()),
22            receiver,
23            sender,
24        }
25    }
26
27    pub fn subscribe(&self) -> flume::Receiver<Packet> {
28        self.receiver.clone()
29    }
30
31    pub fn register(&self, packet: Packet) {
32        self.packets.write().unwrap().push(packet);
33    }
34
35    // register_all(takes an array of packets)
36    pub fn register_all(&self, packets: &[Packet]) {
37        self.packets.write().unwrap().extend_from_slice(packets);
38    }
39
40    fn get_specific_packet(&self, side: PacketSide, state: PacketState, packet_id: i32) -> Packet {
41        let time = match OffsetDateTime::now_local() {
42            Ok(time) => time,
43            Err(_) => OffsetDateTime::now_utc(),
44        };
45
46        self.packets
47            .read()
48            .unwrap()
49            .iter()
50            .find(|packet| packet.id == packet_id && packet.side == side && packet.state == state)
51            .unwrap_or(&Packet {
52                side,
53                state,
54                id: packet_id,
55                timestamp: Some(time),
56                name: "Unknown Packet",
57                data: None,
58            })
59            .clone()
60    }
61
62    pub async fn process(
63        &self,
64        side: PacketSide,
65        state: PacketState,
66        threshold: CompressionThreshold,
67        packet: &PacketFrame,
68    ) -> anyhow::Result<()> {
69        let mut p = self.get_specific_packet(side, state, packet.id);
70        let time = match OffsetDateTime::now_local() {
71            Ok(time) => time,
72            Err(_) => OffsetDateTime::now_utc(),
73        };
74
75        p.data = Some(packet.body.clone().freeze());
76        p.timestamp = Some(time);
77
78        // store in received_packets
79        self.sender.send_async(p).await?;
80
81        Ok(())
82    }
83}
84
85impl Default for PacketRegistry {
86    fn default() -> Self {
87        Self::new()
88    }
89}
90
91#[derive(Clone, Debug, Eq, serde::Serialize, serde::Deserialize)]
92pub struct Packet {
93    pub side: PacketSide,
94    pub state: PacketState,
95    pub id: i32,
96    #[serde(skip)]
97    pub timestamp: Option<OffsetDateTime>,
98    #[serde(skip)]
99    pub name: &'static str,
100    /// Uncompressed packet data
101    #[serde(skip)]
102    pub data: Option<Bytes>,
103}
104
105impl PartialEq for Packet {
106    fn eq(&self, other: &Self) -> bool {
107        self.side == other.side
108            && self.state == other.state
109            && self.id == other.id
110            && self.data == other.data
111    }
112}
113
114impl Hash for Packet {
115    fn hash<H: Hasher>(&self, state: &mut H) {
116        self.id.hash(state);
117        self.side.hash(state);
118        self.state.hash(state);
119    }
120}