You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
1.8 KiB

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<Message>),
Disconnect,
Other(usize, Vec<u8>),
}
impl Server<Connected> {
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<Packet> {
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<u8> = Vec::new();
buf.write_u8_varint(0)?;
buf.write_all(&id)?;
stream.write_usize_varint(buf.len())?;
stream.write_all(&buf)?;
Ok(())
}