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