1use crate::snowflake::Snowflake;
2use lazy_static::lazy_static;
3use parking_lot::{lock_api::Mutex, RawMutex};
4use std::{error::Error, fmt::Display, str::FromStr};
5
6pub type BasePacket = [u8; 1024];
7pub struct PacketMessageContent(pub [u8; 1004]);
8
9pub const PROTOCOL_VERSION: u8 = 1;
10
11lazy_static! {
12 pub static ref SNOWFLAKE: Mutex<RawMutex, Snowflake> = Mutex::new(Default::default());
13}
14
15pub struct Packet {
21 inner: BasePacket,
22}
23
24impl Packet {
25 pub fn new(inner: BasePacket) -> Self {
26 Packet {
27 inner,
28 }
29 }
30
31 pub fn op(&self) -> Opcode {
33 self.inner[1].into()
34 }
35
36 pub fn version(&self) -> u8 {
38 self.inner[0]
39 }
40
41 pub fn snowflake(&self, start: usize) -> [u8; 8] {
43 self.inner[start..start+8].try_into().unwrap()
44 }
45
46 pub fn set_op(&mut self, op: Opcode) {
48 self.inner[1] = op as u8;
49 }
50
51 pub fn set_version(&mut self, version: u8) {
53 self.inner[0] = version;
54 }
55
56 pub fn set_snowflake(&mut self, sf: [u8; 8], start_offset: usize) {
57 self.inner[start_offset..start_offset + 8].copy_from_slice(&sf);
58 }
59
60 pub fn set_content(&mut self, content: PacketMessageContent) -> Result<(), PacketError> {
62 match self.inner[1].into() {
63 Opcode::Message => {
64 let n = &self.inner[..20];
65 self.inner = [n, &content.0].concat().try_into().unwrap();
66
67 Ok(())
68 }
69 t => Err(PacketError::InvaidContent { t }),
70 }
71 }
72}
73
74impl Into<[u8; 1024]> for Packet {
75 fn into(self) -> [u8; 1024] {
76 self.inner
77 }
78}
79
80impl From<u8> for Opcode {
81 fn from(op: u8) -> Self {
82 use self::Opcode::*;
83 match op {
84 0 => Ping,
85 1 => Ok,
86 2 => MemberJoin,
87 3 => MemberLeave,
88 4 => Message,
89 _ => panic!("Opcode `{}` out of range", op),
90 }
91 }
92}
93
94#[repr(u8)]
95#[derive(Debug, Clone, Copy)]
96pub enum Opcode {
97 Ping = 0,
103
104 Ok,
110
111 MemberJoin,
117
118 MemberLeave,
124
125 Message,
133}
134
135#[derive(Debug)]
136pub enum PacketError {
137 InvaidContent { t: Opcode },
141
142 BadContent { t: Opcode },
146}
147
148impl Display for PacketError {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 use self::PacketError::*;
151 match self {
152 InvaidContent { t } => write!(
153 f,
154 "Tried to put content into a packet of type {:?}. Supported types are:
155 - Message",
156 t
157 ),
158 BadContent { t } => write!(f, "Malformed packet of type {:?}.", t),
159 }
160 }
161}
162
163impl Error for PacketError {}
164
165impl FromStr for PacketMessageContent {
166 type Err = PacketError;
167
168 fn from_str(s: &str) -> Result<Self, Self::Err> {
169 let b = s.as_bytes();
173 if b.len() > 1004 {
174 return Err(PacketError::BadContent { t: Opcode::Message });
175 }
176 let re = [0u8].repeat(1004 - b.len());
177 let uuw = re.as_slice();
178
179 let uw: [u8; 1004] = [b, uuw].concat().try_into().unwrap();
180
181 Ok(PacketMessageContent(uw))
182 }
183}
184
185#[cfg(test)]
186pub mod test {
187 use std::time::Duration;
188
189 use super::*;
190
191 #[test]
192 fn packet() {
193 let mut packet = Packet::new([0; 1024]);
194
195 packet.set_op(Opcode::Message);
196 packet.set_content("uwu".parse().unwrap()).unwrap();
197 packet.set_snowflake(SNOWFLAKE.lock().generate_u8_u64(), 3);
198 std::thread::sleep(Duration::from_secs(1));
199
200 packet.set_snowflake(SNOWFLAKE.lock().generate_u8_u64(), 11);
201 std::thread::sleep(Duration::from_secs(1));
202
203 packet.set_snowflake(SNOWFLAKE.lock().generate_u8_u64(), 30);
204 std::thread::sleep(Duration::from_secs(1));
205
206 assert_eq!(packet.inner[0], 0);
207 assert_eq!(packet.inner[1], 4);
208 assert_eq!(&packet.inner[20..23], "uwu".as_bytes());
209
210 println!("{:?}", u64::from_le_bytes(packet.snowflake(3)));
211 println!("{:?}", u64::from_le_bytes(packet.snowflake(11)));
212 println!("{:?}", u64::from_le_bytes(packet.snowflake(30)));
213 }
214}