use std::{ io::{Read as _, Write as _}, net::TcpStream, }; use varint_rs::{VarintReader, VarintWriter as _}; use crate::{ Connected, Server, error::Result, readers::{read_packet, read_string}, text::Message, }; pub enum Packet { KeepAlive([u8; 4]), Chat(Vec), Disconnect, Other(usize, Vec), } impl Server { pub fn run(self) -> Result<()> { let Self { mut stream, lang, state: Connected { .. }, .. } = self; loop { let packet = read_packet(&mut stream, parse_packet)?; match packet { Packet::KeepAlive(id) => handle_keepalive(&mut stream, id)?, Packet::Chat(m) => { for m in m { println!("{}", m.format(&lang)) } } Packet::Disconnect => break, Packet::Other(_, _) => {} } } Ok(()) } } fn parse_packet(packet: &mut &[u8]) -> Result { let id = packet.read_usize_varint()?; match id { 0x00 => { let mut id = [0u8; 4]; packet.read_exact(&mut id)?; Ok(Packet::KeepAlive(id)) } 0x02 => { let msg = read_string(packet)?; let msg = Message::from_string(msg).unwrap(); Ok(Packet::Chat(msg)) } 0x40 => Ok(Packet::Disconnect), i => Ok(Packet::Other(i, packet.to_vec())), } } fn handle_keepalive(stream: &mut TcpStream, id: [u8; 4]) -> Result<()> { let mut buf: Vec = Vec::new(); buf.write_u8_varint(0)?; buf.write_all(&id)?; stream.write_usize_varint(buf.len())?; stream.write_all(&buf)?; Ok(()) }