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