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