1#![feature(error_generic_member_access)]
14
15use std::{fmt::Display, net::SocketAddr, str::FromStr};
16
17pub mod common;
18#[cfg(feature = "connecting")]
19pub mod connect;
20#[cfg(feature = "packets")]
21pub mod packets;
22pub mod read;
23pub mod resolver;
24pub mod write;
25
26#[derive(Debug, Clone)]
39pub struct ServerAddress {
40 pub host: String,
41 pub port: u16,
42}
43
44impl TryFrom<&str> for ServerAddress {
45 type Error = String;
46
47 fn try_from(string: &str) -> Result<Self, Self::Error> {
50 if string.is_empty() {
51 return Err("Empty string".to_string());
52 }
53 let mut parts = string.split(':');
54 let host = parts.next().ok_or("No host specified")?.to_string();
55 let port = parts.next().unwrap_or("25565");
57 let port = u16::from_str(port).map_err(|_| "Invalid port specified")?;
58 Ok(ServerAddress { host, port })
59 }
60}
61impl TryFrom<String> for ServerAddress {
62 type Error = String;
63
64 fn try_from(string: String) -> Result<Self, Self::Error> {
65 ServerAddress::try_from(string.as_str())
66 }
67}
68
69impl From<SocketAddr> for ServerAddress {
70 fn from(addr: SocketAddr) -> Self {
74 ServerAddress {
75 host: addr.ip().to_string(),
76 port: addr.port(),
77 }
78 }
79}
80
81impl Display for ServerAddress {
82 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
83 write!(f, "{}:{}", self.host, self.port)
84 }
85}
86
87impl<'de> serde::Deserialize<'de> for ServerAddress {
90 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
91 where
92 D: serde::Deserializer<'de>,
93 {
94 let string = String::deserialize(deserializer)?;
95 ServerAddress::try_from(string.as_str()).map_err(serde::de::Error::custom)
96 }
97}
98
99impl serde::Serialize for ServerAddress {
102 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
103 where
104 S: serde::Serializer,
105 {
106 serializer.serialize_str(&self.to_string())
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use std::io::Cursor;
113
114 use uuid::Uuid;
115
116 use crate::{
117 packets::{
118 game::s_chat::{LastSeenMessagesUpdate, ServerboundChat},
119 login::{s_hello::ServerboundHello, ServerboundLoginPacket},
120 Packet,
121 },
122 read::{compression_decoder, read_packet},
123 write::{compression_encoder, serialize_packet, write_packet},
124 };
125
126 #[tokio::test]
127 async fn test_hello_packet() {
128 let packet = ServerboundHello {
129 name: "test".to_string(),
130 profile_id: Uuid::nil(),
131 };
132 let mut stream = Vec::new();
133 write_packet(&packet.into_variant(), &mut stream, None, &mut None)
134 .await
135 .unwrap();
136
137 assert_eq!(
138 stream,
139 [22, 0, 4, 116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
140 );
141
142 let mut stream = Cursor::new(stream);
143
144 let _ = read_packet::<ServerboundLoginPacket, _>(
145 &mut stream,
146 &mut Cursor::new(Vec::new()),
147 None,
148 &mut None,
149 )
150 .await
151 .unwrap();
152 }
153
154 #[tokio::test]
155 async fn test_double_hello_packet() {
156 let packet = ServerboundHello {
157 name: "test".to_string(),
158 profile_id: Uuid::nil(),
159 }
160 .into_variant();
161 let mut stream = Vec::new();
162 write_packet(&packet, &mut stream, None, &mut None)
163 .await
164 .unwrap();
165 write_packet(&packet, &mut stream, None, &mut None)
166 .await
167 .unwrap();
168 let mut stream = Cursor::new(stream);
169
170 let mut buffer = Cursor::new(Vec::new());
171
172 let _ = read_packet::<ServerboundLoginPacket, _>(&mut stream, &mut buffer, None, &mut None)
173 .await
174 .unwrap();
175 let _ = read_packet::<ServerboundLoginPacket, _>(&mut stream, &mut buffer, None, &mut None)
176 .await
177 .unwrap();
178 }
179
180 #[tokio::test]
181 async fn test_read_long_compressed_chat() {
182 let compression_threshold = 256;
183
184 let buf = serialize_packet(
185 &ServerboundChat {
186 message: "a".repeat(256),
187 timestamp: 0,
188 salt: 0,
189 signature: None,
190 last_seen_messages: LastSeenMessagesUpdate::default(),
191 }
192 .into_variant(),
193 )
194 .unwrap();
195
196 let buf = compression_encoder(&buf, compression_threshold).unwrap();
197
198 println!("{:?}", buf);
199
200 compression_decoder(&mut Cursor::new(&buf), compression_threshold).unwrap();
201 }
202}