Cactus/net/mod.rs
1//! This module manages the TCP server and how/where the packets are managed/sent.
2pub mod packet;
3pub mod slp;
4
5use crate::config;
6use crate::net::packet::{data_types, utils};
7use bytes::{Buf, BytesMut};
8use log::{debug, error, info, warn};
9use packet::data_types::{CodecError, Encodable};
10use packet::{Packet, PacketError, Response};
11use std::cmp::min;
12use std::io;
13use std::sync::Arc;
14use thiserror::Error;
15use tokio::io::{AsyncReadExt, AsyncWriteExt};
16use tokio::net::TcpListener;
17use tokio::net::TcpStream;
18use tokio::sync::Mutex;
19
20/// Listening address
21/// TODO: Change this. Use config files.
22const ADDRESS: &str = "0.0.0.0";
23
24#[derive(Error, Debug)]
25pub enum NetError {
26 #[error("Connection closed: {0}")]
27 ConnectionClosed(String),
28
29 #[error("Failed to read from socket: {0}")]
30 Reading(String),
31
32 #[error("Failed to write to socket: {0}")]
33 Writing(String),
34
35 #[error("Failed to parse packet: {0}")]
36 Parsing(#[from] PacketError),
37
38 #[error("IO error: {0}")]
39 Io(#[from] io::Error),
40
41 #[error("Codec error: {0}")]
42 Codec(#[from] CodecError),
43
44 #[error("Unknown packet id: {0}")]
45 UnknownPacketId(String),
46}
47
48/// Listens for every incoming TCP connection.
49pub async fn listen() -> Result<(), Box<dyn std::error::Error>> {
50 let config = config::Settings::new();
51 let server_address = format!("{}:{}", ADDRESS, config.server_port);
52 let listener = TcpListener::bind(server_address).await?;
53
54 loop {
55 let (socket, addr) = listener.accept().await?;
56 tokio::spawn(async move {
57 if let Err(e) = handle_connection(socket).await {
58 warn!("Error handling connection from {addr}: {e}");
59 }
60 });
61 }
62}
63
64/// State of each connection. (e.g.: handshake, play, ...)
65#[derive(Debug, Clone, Copy)]
66enum ConnectionState {
67 Handshake,
68 Status,
69 Login,
70 Configuration,
71 Play,
72 Transfer,
73}
74
75impl Default for ConnectionState {
76 fn default() -> Self {
77 Self::Handshake
78 }
79}
80
81/// Object representing a TCP connection.
82struct Connection {
83 state: Arc<Mutex<ConnectionState>>,
84 socket: Arc<Mutex<TcpStream>>,
85 buffer: Mutex<BytesMut>,
86}
87
88impl Connection {
89 /// Base buffer size and the number of bytes we're trying to read from the socket.
90 const BUFFER_SIZE: usize = 512;
91
92 fn new(socket: TcpStream) -> Self {
93 Self {
94 state: Arc::new(Mutex::new(ConnectionState::default())),
95 socket: Arc::new(Mutex::new(socket)),
96 buffer: Mutex::new(BytesMut::with_capacity(Self::BUFFER_SIZE)),
97 }
98 }
99
100 /// Get the current state of the connection
101 async fn get_state(&self) -> ConnectionState {
102 *self.state.lock().await
103 }
104
105 /// Change the state of the current Connection.
106 async fn set_state(&self, new_state: ConnectionState) {
107 debug!(
108 "Connection state: {:?} -> {:?}",
109 self.get_state().await,
110 new_state
111 );
112 *self.state.lock().await = new_state
113 }
114
115 /// Writes either a &[u8] to the socket.
116 ///
117 /// This function can take in `Packet`.
118 async fn write<T: AsRef<[u8]>>(&self, data: T) -> Result<(), NetError> {
119 let mut socket = self.socket.lock().await;
120 Ok(socket.write_all(data.as_ref()).await?)
121 }
122
123 /// Attempts to read a packet size (in bytes, in VarInt).
124 /// If yes, return size. (prepending the conn buffer)
125 /// If no, append bytes to connection buffer.
126 async fn wait_size(&self, bytes: &[u8]) -> Result<(usize, usize), ()> {
127 debug!("INTO WAIT_SIZE");
128 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
129 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
130 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
131 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
132 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
133 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
134 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
135 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
136 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
137 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
138 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
139 let mut buffer = self.buffer.lock().await;
140 let buffer_size: usize = buffer.len();
141 // OLDEST bytes first.
142 let read: Vec<u8> = buffer.iter().chain(bytes).copied().collect();
143 debug!("wait_size() buffer: {}", utils::get_dec_repr(&read));
144
145 match data_types::VarInt::from_bytes(read, ()) {
146 Ok(size) => {
147 debug!("Read VarInt from wait_size(): {}", size.get_value());
148 let s = usize::try_from(size.get_value()).map_err(|e| {
149 error!("Error while converting packet size into usize: {e}");
150 })?;
151 // Left-shift the buffers' items to account for this VarInt.
152 buffer.advance(min(buffer_size, size.size()));
153 Ok((s, size.size()))
154 }
155 Err(_) => {
156 //buffer.extend_from_slice(bytes);
157 Err(())
158 }
159 }
160 }
161 /// Wait for the number of bytes wait_size() spew.
162 /// If yes, return packet. (prepending the conn buffer)
163 /// If no, append bytes to connection buffer.
164 async fn wait_packet(&self, bytes: &[u8], size: usize, size_size: usize) -> Result<Packet, ()> {
165 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
166 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
167 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
168 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
169 // TODO: REWRITE THIS WITH ZERO COPY. INEFFICIENT!
170 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
171 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
172 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
173 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
174 // TODO: ADD CONCRETE ERRORS AND PROPAGATE;
175
176 let mut buffer = self.buffer.lock().await;
177 // Size of connection buffer.
178 let buffer_size: usize = buffer.len();
179
180 // OLDEST bytes first!
181 let read: Vec<u8> = buffer.iter().chain(bytes).copied().collect();
182
183 // Size of only the payload of the frame (ID + Data)
184 //let payload_size: usize = size - size_size;
185 // Size of ALL the frame.
186 let frame_size: usize = size + size_size;
187
188 // The concatenated [CONN BUFF + SOCK READ] is smaller than the frame.
189 if read.len() < frame_size {
190 buffer.extend_from_slice(bytes);
191 warn!("Frame size is bigger than cached data");
192 debug!("Cached data: {}", utils::get_dec_repr(&read));
193 debug!("Frame size: {}", frame_size);
194 Err(())
195 } else {
196 //if (size_size >= size) {
197 if 0 == size {
198 error!("Size is zero");
199 return Err(());
200 }
201
202 let frame = &read[..frame_size];
203 debug!("Cached data b4 advance: {}", utils::get_dec_repr(&buffer));
204 buffer.advance(min(frame_size, buffer_size));
205 debug!(
206 "Cached data after advance: {}",
207 utils::get_dec_repr(&buffer)
208 );
209 debug!("Frame: {frame:?}");
210 match Packet::new(frame) {
211 Ok(p) => {
212 if frame_size < read.len() {
213 debug!("Cached data b4 extend: {}", utils::get_dec_repr(&buffer));
214 buffer.extend_from_slice(&read[frame_size..]);
215 debug!("Cached data after extend: {}", utils::get_dec_repr(&buffer));
216 }
217 Ok(p)
218 }
219 Err(e) => {
220 error!("Error while making packet: {e}");
221 Err(())
222 }
223 }
224 }
225 }
226
227 /// TODO: CHECK & REWRITE
228 /// TODO: CHECK & REWRITE
229 /// TODO: CHECK & REWRITE
230 /// TODO: CHECK & REWRITE
231 /// TODO: CHECK & REWRITE
232 async fn read(&self) -> Result<Packet, NetError> {
233 let mut socket = self.socket.lock().await;
234
235 loop {
236 // Try to parse the VarInt length from the start of the connection buffer.
237 let (len_opt, len_len_opt) = {
238 let recv = self.buffer.lock().await;
239
240 if recv.is_empty() {
241 (None, None)
242 } else {
243 // Parse at most 5 bytes for the VarInt prefix.
244 let to_parse = recv.len().min(5);
245 match data_types::VarInt::from_bytes(recv[..to_parse].to_vec(), ()) {
246 Ok(v) => {
247 let len_usize = usize::try_from(v.get_value()).map_err(|_| {
248 NetError::Reading("Frame length does not fit in usize".to_string())
249 })?;
250 (Some(len_usize), Some(v.size()))
251 }
252 Err(_) => (None, None), // need more bytes for the length
253 }
254 }
255 };
256
257 if let (Some(len), Some(len_len)) = (len_opt, len_len_opt) {
258 if len == 0 {
259 return Err(NetError::Reading("Zero-length frame".to_string()));
260 }
261
262 let total = len_len + len;
263
264 // If we already have the full frame, split and parse.
265 if {
266 let recv = self.buffer.lock().await;
267 recv.len() >= total
268 } {
269 let mut recv = self.buffer.lock().await;
270 let frame = recv.split_to(total);
271 drop(recv);
272
273 return Packet::new(&frame).map_err(NetError::Parsing);
274 }
275 // else: we know the size but need more bytes; fall through to read.
276 }
277
278 // Read more bytes from the socket into the connection buffer.
279 let mut recv = self.buffer.lock().await;
280 let n = socket.read_buf(&mut *recv).await?;
281 if n == 0 {
282 return Err(NetError::ConnectionClosed("read 0 bytes".to_string()));
283 }
284 }
285 }
286 //
287 // /// Reads the socket for a full valid frame (packet).
288 // /// # Behavior
289 // /// - Maintains a per-connection buffer.
290 // ///
291 // /// Zeroth, if connection buffer not empty, read from it.
292 // ///
293 // /// First, wait for reading a **complete** packet length (VarInt).
294 // ///
295 // /// Second, waits for reading the complete frame, so it reads the parsed VarInt.
296 // ///
297 // /// Third, if there is more bytes than what we read as a first frame, we put that inside
298 // /// the connection buffer.
299 // ///
300 // /// Return the frame.
301 // async fn read(&self) -> Result<Packet, NetError> {
302 // // TODO: DROP TRIES AND ADD TIMEOUT!!
303 // // TODO: DROP TRIES AND ADD TIMEOUT!!
304 // // TODO: DROP TRIES AND ADD TIMEOUT!!
305 // // TODO: DROP TRIES AND ADD TIMEOUT!!
306 // // TODO: DROP TRIES AND ADD TIMEOUT!!
307 //
308 // let mut buffer = BytesMut::with_capacity(Self::BUFFER_SIZE);
309 // let mut socket = self.socket.lock().await;
310 //
311 // for try_count in 1..=Self::MAX_PACKET_TRIES {
312 // // 1) Try to parse the length (once).
313 // let size_res = Self::wait_size(self, &buffer).await;
314 // if size_res.is_err() {
315 // let n = socket.read_buf(&mut buffer).await?;
316 // if n == 0 { return Err(NetError::ConnectionClosed("read 0 bytes".into())); }
317 // continue;
318 // }
319 // let (size, size_len) = size_res.unwrap();
320 //
321 // // 2) Try to split the frame.
322 // if let Ok(pkt) = Self::wait_packet(self, &buffer, size, size_len).await {
323 // return Ok(pkt);
324 // }
325 //
326 // // 3) Need more bytes.
327 // let n = socket.read_buf(&mut buffer).await?;
328 // if n == 0 { return Err(NetError::ConnectionClosed("read 0 bytes".into())); }
329 // }
330 //
331 // return Err(NetError::Reading("Failed to delimit".to_string()));
332 //
333 //
334 //
335 // // Try to read a packet, up to MAX_PACKET_TRIES tries (basically socket reads).
336 // for try_count in 1..=Self::MAX_PACKET_TRIES {
337 // let is_conn_buf_empty: bool = { self.buffer.lock().await.is_empty() };
338 //
339 // if Self::wait_size(self, &buffer).await.is_err() {
340 // let n = socket.read_buf(&mut buffer).await?;
341 // if n == 0 { return Err(NetError::ConnectionClosed("read 0 bytes".into())); }
342 // continue;
343 // }
344 //
345 // // unwrap??
346 // let (size, size_len) = Self::wait_size(self, &buffer).await.unwrap();
347 //
348 // // 2) If we don't yet have size_len + size bytes, read more.
349 // if Self::wait_packet(self, &buffer, size, size_len).await.is_err() {
350 // let n = socket.read_buf(&mut buffer).await?;
351 // if n == 0 { return Err(NetError::ConnectionClosed("read 0 bytes".into())); }
352 // continue;
353 // }
354 //
355 // // 3) Now we have a full frame.
356 // let pkt = Self::wait_packet(self, &buffer, size, size_len).await.unwrap();
357 // return Ok(pkt);
358 //
359 // debug!("Try in read() to split a frame from stream");
360 // if is_conn_buf_empty {
361 // let read: usize = socket.read_buf(&mut buffer).await?;
362 // if read == 0 {
363 // warn!("Read zero bytes; connection should be closed.");
364 // return Err(NetError::ConnectionClosed("read 0 bytes".to_string()));
365 // }
366 // }
367 //
368 // debug!(
369 // "TCP buffer received ({}): {}",
370 // buffer.len(),
371 // crate::net::packet::utils::get_dec_repr(&buffer)
372 // );
373 // // VarInt Value / VarInt Size
374 // if let Ok(size_varint) = Self::wait_size(self, &buffer).await {
375 // debug!("Got packet with size: {}", size_varint.0);
376 // if let Ok(packet) =
377 // Self::wait_packet(self, &buffer, size_varint.0, size_varint.1).await
378 // {
379 // debug!("Split a packet: {packet:?}");
380 // return Ok(packet);
381 // } else {
382 // warn!(
383 // "Failed to delimit packet with current read bytes; try #{}/{}",
384 // try_count,
385 // Self::MAX_PACKET_TRIES
386 // );
387 // }
388 // } else {
389 // warn!(
390 // "Failed to delimit packet SIZE with current read bytes; try #{}/{}",
391 // try_count,
392 // Self::MAX_PACKET_TRIES
393 // );
394 // }
395 // }
396 //
397 // Err(NetError::Reading(
398 // "Failed to delimit packet in socket stream".to_string(),
399 // ))
400 // }
401
402 /// Tries to close the connection with the Minecraft client
403 async fn close(&self) -> Result<(), std::io::Error> {
404 info!("Connection closed: {}", self);
405 self.socket.lock().await.shutdown().await
406 }
407}
408
409use std::fmt;
410
411impl fmt::Display for Connection {
412 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
413 // Snapshot addresses without awaiting
414 let (local, peer) = match self.socket.try_lock() {
415 Ok(sock) => (sock.local_addr().ok(), sock.peer_addr().ok()),
416 Err(_) => (None, None), // couldn't lock right now
417 };
418
419 // Snapshot buffer length without awaiting
420 let buf_str = match self.buffer.try_lock() {
421 Ok(buf) => human_bytes(buf.len()),
422 Err(_) => "<locked>".to_string(),
423 };
424
425 write!(
426 f,
427 "conn({} -> {}, buf={})",
428 local.map(|a| a.to_string()).unwrap_or_else(|| "?".into()),
429 peer.map(|a| a.to_string()).unwrap_or_else(|| "?".into()),
430 buf_str
431 )
432 }
433}
434
435fn human_bytes(n: usize) -> String {
436 const KB: usize = 1024;
437 const MB: usize = KB * 1024;
438 const GB: usize = MB * 1024;
439 if n >= GB {
440 format!("{:.1}GiB", n as f64 / GB as f64)
441 } else if n >= MB {
442 format!("{:.1}MiB", n as f64 / MB as f64)
443 } else if n >= KB {
444 format!("{:.1}KiB", n as f64 / KB as f64)
445 } else {
446 format!("{n}B")
447 }
448}
449
450const IS_CRUEL: bool = true;
451
452/// Handles each connection. Receives every packet.
453async fn handle_connection(socket: TcpStream) -> Result<(), NetError> {
454 debug!("Handling new connection: {socket:?}");
455
456 let connection = Connection::new(socket);
457
458 #[cfg(debug_assertions)]
459 let mut packet_count: usize = 0;
460
461 loop {
462 debug!("handle_connection() loop");
463 // Read the socket and wait for a packet
464 let res = connection.read().await;
465 if res.is_err() && IS_CRUEL {
466 connection.close().await?;
467 }
468 let packet: Packet = res?;
469
470 #[cfg(debug_assertions)]
471 {
472 packet_count += 1;
473 debug!("Got packet #{}: {:?}", packet_count, packet);
474 }
475
476 let response: Response = handle_packet(&connection, packet).await?;
477
478 if let Some(packet) = response.get_packet() {
479 // TODO: Make sure that sent packets are big endians (data types).
480 connection.write(packet).await?;
481 debug!("Sent a packet: {packet}");
482
483 if response.does_close_conn() {
484 info!("Connection closed.");
485 connection.close().await?;
486 return Ok(());
487 }
488 } else {
489 // Temp warn
490 error!("THIS MUST BE FIXED/MORE INFO!!! PLEASE PAY ATTENTION TO ME~~~!");
491 warn!("Got response None. Not sending any packet to the MC client");
492 //connection.close().await?;
493 }
494 }
495}
496
497//async fn socket_transmitter
498
499/// This function returns an appropriate response given the input `buffer` packet data.
500async fn handle_packet(conn: &Connection, packet: Packet) -> Result<Response, NetError> {
501 debug!("{packet:?} / Conn. state: {:?}", conn.get_state().await);
502
503 // Dispatch packet depending on the current State.
504 match conn.get_state().await {
505 ConnectionState::Handshake => dispatch::handshaking(packet, conn).await,
506 ConnectionState::Status => dispatch::status(packet, conn).await,
507 ConnectionState::Login => dispatch::login(conn, packet).await,
508 ConnectionState::Configuration => dispatch::configuration(conn, packet).await,
509 ConnectionState::Play => dispatch::play(conn, packet).await,
510 ConnectionState::Transfer => dispatch::transfer(conn, packet).await,
511 }
512}
513
514/// The `dispatch` module contains functions that will change the state of the active `Connection`.
515/// Each function in `dispatch` corresponds not to a specific packet, but to a whole state.
516/// Each state has different packets, and a packet can be named the name but have different intent
517/// based on state.
518///
519/// # Example of state switch
520/// (Initial state: 'Handshake')
521/// We receive a Handshake packet, ID=0x00 with next_state(VarInt Enum) set to:
522/// 1: we switch the connection state to 'Status'.
523/// 2: we switch the connection state to 'Login'.
524/// 3: we switch the connection state to 'Transfer'.
525mod dispatch {
526 use super::*;
527 use crate::net::slp::ip_logger::ClientIpLoggerInfo;
528 use packet::packet_types::configuration::*;
529 use packet::packet_types::handshake::*;
530 use packet::packet_types::login::*;
531 use packet::packet_types::ClientboundPacket;
532 use packet::packet_types::EmptyPayloadPacket;
533 use packet::packet_types::GenericPacket;
534 use packet::{
535 data_types::{Encodable, VarInt},
536 Response,
537 };
538
539 /// https://minecraft.wiki/w/Java_Edition_protocol/Packets#Handshaking
540 pub async fn handshaking(packet: Packet, conn: &Connection) -> Result<Response, NetError> {
541 // Set state to Status
542 debug!("Handshake packet: {:?}", packet.get_full_packet());
543 conn.set_state(ConnectionState::Status).await;
544
545 debug!("Trying to create handshake packet...");
546 let handshake_packet: Handshake = packet.try_into()?;
547
548 match handshake_packet.next_state {
549 packet::packet_types::NextState::Status(_) => {
550 conn.set_state(ConnectionState::Status).await
551 }
552 packet::packet_types::NextState::Login(_) => {
553 conn.set_state(ConnectionState::Login).await
554 }
555 packet::packet_types::NextState::Transfer(_) => {
556 conn.set_state(ConnectionState::Transfer).await
557 }
558 packet::packet_types::NextState::Handshake(_) => {
559 return Err(NetError::Codec(CodecError::Decoding(
560 packet::data_types::DataType::Other("Handshake packet"),
561 packet::data_types::ErrorReason::UnknownValue(
562 "Got handshake next_state.".to_string(),
563 ),
564 )));
565 }
566 }
567
568 Ok(Response::new(None))
569 }
570
571 /// https://minecraft.wiki/w/Java_Edition_protocol/Packets#Status
572 pub async fn status(packet: Packet, conn: &Connection) -> Result<Response, NetError> {
573 match packet.get_id().get_value() {
574 0x00 => {
575 // Log IP if enabled.
576 if crate::consts::cactus::DO_LOG_IPS_SLP {
577 let info = ClientIpLoggerInfo {
578 ip: conn.socket.lock().await.peer_addr()?.to_string(),
579 };
580 slp::ip_logger::log_ip(info);
581 }
582
583 // Got Status Request
584 let status_resp_packet = slp::status_response()?;
585 let response = Response::new(Some(status_resp_packet));
586
587 Ok(response)
588 }
589 0x01 => {
590 // Got Ping Request (status)
591 let ping_request_packet = slp::ping_response(packet)?;
592 let response = Response::new(Some(ping_request_packet)).close_conn();
593
594 // We should close the connection after sending this packet.
595 // See the 7th step:
596 // https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol_FAQ#What_does_the_normal_status_ping_sequence_look_like?
597
598 Ok(response)
599 }
600 _ => {
601 warn!("Unknown packet ID, State: Status");
602 Err(NetError::UnknownPacketId(format!(
603 "unknown packet ID, State: Status, PacketId: {}",
604 packet.get_id().get_value()
605 )))
606 }
607 }
608 }
609
610 /// https://minecraft.wiki/w/Java_Edition_protocol/Packets#Login
611 pub async fn login(conn: &Connection, packet: Packet) -> Result<Response, NetError> {
612 match packet.get_id().get_value() {
613 0x00 => {
614 let login_start: LoginStart = packet.try_into()?;
615
616 debug!("Got login Start packet: {login_start:#?}");
617
618 let args = (
619 login_start.player_uuid,
620 login_start.name,
621 VarInt::from_value(0)?, // No packs
622 Vec::new(),
623 );
624
625 let login_success: LoginSuccess = LoginSuccess::from_values(args)?;
626 Ok(Response::new(Some(login_success.get_packet().clone())))
627 }
628 0x03 => {
629 // Parse it just to be sure it's the Login Acknowledged packet.
630 let _login_success: LoginAcknowledged = packet.try_into()?;
631
632 // Switch the connection state to Configuration
633 conn.set_state(ConnectionState::Configuration).await;
634
635 // Don't respond anything
636 //Ok(Response::new(None))
637 //
638 // Respond with a Clientbound Known Packs packet
639 let args = (VarInt::from_value(0)?, Vec::new());
640 let clientbound_known_packs: Packet = ClientboundKnownPacks::from_values(args)?
641 .get_packet()
642 .clone();
643
644 Ok(Response::new(Some(clientbound_known_packs)))
645 }
646 _ => {
647 warn!("Unknown packet ID, State: Status");
648 Err(NetError::UnknownPacketId(format!(
649 "unknown packet ID, State: Status, PacketId: {}",
650 packet.get_id().get_value()
651 )))
652 }
653 }
654 }
655
656 /// https://minecraft.wiki/w/Java_Edition_protocol/Packets#Transfer
657 /// I don't really know which packets should be handled here.
658 pub async fn transfer(conn: &Connection, packet: Packet) -> Result<Response, NetError> {
659 todo!()
660 }
661
662 /// https://minecraft.wiki/w/Java_Edition_protocol/Packets#Configuration
663 pub async fn configuration(conn: &Connection, packet: Packet) -> Result<Response, NetError> {
664 match packet.get_id().get_value() {
665 0x00 => {
666 // TODO: Cookie Request packet
667 Ok(Response::new(None))
668 }
669 0x01 => {
670 // TODO: Clientbound Plugin Message packet
671 Ok(Response::new(None))
672 }
673 0x02 => {
674 // TODO: Disconnect packet
675 Ok(Response::new(None))
676 }
677 0x03 => {
678 let acknowledge_finish_configuration: FinishConfiguration = packet.try_into()?;
679 debug!(
680 "Got Acknowledge Finish Configuration: {acknowledge_finish_configuration:?}"
681 );
682
683 info!("{}", *crate::consts::messages::PLAY_PACKET_NOTIFIER);
684
685 conn.set_state(ConnectionState::Play).await;
686
687 // TODO: Send a 'Login (play)' packet
688 // TODO: Send a 'Login (play)' packet
689 // TODO: Send a 'Login (play)' packet
690 // TODO: Send a 'Login (play)' packet
691 // TODO: Send a 'Login (play)' packet
692 // TODO: Send a 'Login (play)' packet
693 // TODO: Send a 'Login (play)' packet
694 // TODO: Send a 'Login (play)' packet
695 // TODO: Send a 'Login (play)' packet
696 // TODO: Send a 'Login (play)' packet
697 // TODO: Send a 'Login (play)' packet
698 // TODO: Send a 'Login (play)' packet
699 // TODO: Send a 'Login (play)' packet
700 // TODO: Send a 'Login (play)' packet
701 //
702 // TO IMPLEMENT (for the 'Login (play)' packet):
703
704 // https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol#Type:Identifier
705
706 // https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol#Type:Long
707
708 // https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol#Type:Unsigned_Byte
709
710 // OK - https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol#Type:Byte
711
712 // https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol#Type:Position
713
714 // https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol#Type:Int
715
716 Ok(Response::new(None))
717 }
718 0x04 => {
719 // TODO: Clientbound Keep Alive packet
720 // TODO: Clientbound Keep Alive packet
721 // TODO: Clientbound Keep Alive packet
722 Ok(Response::new(None))
723 }
724 0x05 => {
725 // TODO: Ping packet
726 Ok(Response::new(None))
727 }
728 0x07 => {
729 let serverbound_known_packs: ServerboundKnownPacks = packet.try_into()?;
730 debug!("Got Serverbound Known Packs packet: {serverbound_known_packs:?}");
731
732 // Switch connection state to Play.
733 // NO! Why? We wait for the client to send an Ack first, fool!
734 //conn.set_state(ConnectionState::Play).await;
735
736 let finish_configuration = FinishConfiguration::new();
737 let finish_config_packet =
738 EmptyPayloadPacket::get_packet(&finish_configuration).clone();
739 Ok(Response::new(Some(finish_config_packet)))
740 }
741 // TODO: And a lot, lot more to follow
742
743 // 0x10 = 16. Last and sixteenth Configuration packet.
744 0x10 => {
745 // TODO: Server Links
746 Ok(Response::new(None))
747 }
748 _ => {
749 warn!("Unknown packet ID, State: Configuration");
750 Err(NetError::UnknownPacketId(format!(
751 "unknown packet ID, State: Configuration, PacketId: {}",
752 packet.get_id().get_value()
753 )))
754 }
755 }
756 }
757
758 /// https://minecraft.wiki/w/Java_Edition_protocol/Packets#Play
759 /// The largest state with over 60 different types of packets, the last one being 0x41 (65).
760 pub async fn play(conn: &Connection, packet: Packet) -> Result<Response, NetError> {
761 debug!("Inside play state");
762
763 match packet.get_id().get_value() {
764 _ => {
765 warn!("Unknown packet ID, State: Play");
766 Err(NetError::UnknownPacketId(format!(
767 "unknown packet ID, State: Play, PacketId: {}",
768 packet.get_id().get_value()
769 )))
770 }
771 }
772 }
773}