diff --git a/src/connect.rs b/src/connect.rs index d715198..4781e39 100644 --- a/src/connect.rs +++ b/src/connect.rs @@ -7,9 +7,8 @@ use varint_rs::{VarintReader, VarintWriter}; use crate::{ Connected, Server, Status, - error::ChatError, - error::Result, - readers::{read_packet, read_plugin_msg, read_string}, + error::{ChatError, Result}, + readers::{read_packet, read_plugin_msg, read_string, try_read_plugin_msg}, status::ServerType, writers::{write_packet, write_plugin_msg, write_string}, }; @@ -200,27 +199,19 @@ impl Server { Ok(()) })?; - // Serrver FluidIdmap - read_plugin_msg(&mut stream, "FORGE", |packet| { - let discriminant = VarintReader::read(packet)?; - assert_eq!(discriminant, 2); - Ok(()) - })?; - - // HandshakeAck pendingcomplete - write_plugin_msg(&mut stream, "FML|HS", |body| { - body.write_all(&[0xFF, 0x04])?; - Ok(()) - })?; - - // Server HandshakeAck complete - read_plugin_msg(&mut stream, "FML|HS", |packet| { - let discriminant = VarintReader::read(packet)?; - assert_eq!(discriminant, 255); - let phrase = VarintReader::read(packet)?; - assert_eq!(phrase, 3); - Ok(()) - })?; + // Server Mod registried + while try_read_plugin_msg(&mut stream, |channel, packet| { + dbg!(channel); + if channel != "FML|HS" { + Ok(true) + } else { + let discriminant = VarintReader::read(packet)?; + assert_eq!(discriminant, 255); + let phrase = VarintReader::read(packet)?; + assert_eq!(phrase, 3); + Ok(false) + } + })? {} // HandshakeAck complete write_plugin_msg(&mut stream, "FML|HS", |body| { diff --git a/src/error.rs b/src/error.rs index 5ca51ea..05ff535 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,11 +1,15 @@ use serde_json::Value; -use std::{io, result::Result as StdResult, string::FromUtf8Error}; +use std::{ + env::VarError, io, num::ParseIntError, result::Result as StdResult, string::FromUtf8Error, +}; #[derive(Debug)] pub enum ChatError { IoError(io::Error), FromUtf8Error(FromUtf8Error), + ParseIntError(ParseIntError), JsonError(JsonError), + VarError(VarError), } #[derive(Debug)] @@ -35,6 +39,18 @@ impl From for ChatError { } } +impl From for ChatError { + fn from(value: VarError) -> Self { + Self::VarError(value) + } +} + +impl From for ChatError { + fn from(value: ParseIntError) -> Self { + Self::ParseIntError(value) + } +} + impl From for JsonError { fn from(value: serde_json::Error) -> Self { Self::SerdeError(value) diff --git a/src/main.rs b/src/main.rs index 2fb2dd9..adbad5b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,14 +57,7 @@ impl Server { } fn main() -> Result<()> { - let server = Server::new("localhost".to_string(), 25565)?; - dbg!(&server); - - let server = server.status()?; - dbg!(&server); - - let server = server.connect()?; - dbg!(&server); - - server.run() + let addr = std::env::var("ADDR")?; + let port: u16 = std::env::var("PORT")?.parse()?; + Server::new(addr, port)?.status()?.connect()?.run() } diff --git a/src/readers.rs b/src/readers.rs index ddb3f8a..407ee44 100644 --- a/src/readers.rs +++ b/src/readers.rs @@ -45,3 +45,23 @@ pub fn read_plugin_msg Result>( read_body(&mut packet) }) } + +pub fn try_read_plugin_msg Result>( + stream: &mut TcpStream, + read_body: F, +) -> Result { + read_packet(stream, |packet| { + let id = packet.read_usize_varint()?; + assert!(id == 63); + + let channel_read = read_string(packet)?; + let mut buf = [0u8; 2]; + packet.read_exact(&mut buf)?; + let len = u16::from_be_bytes(buf); + let mut buf = vec![0u8; len as usize]; + packet.read_exact(&mut buf)?; + + let mut packet = &buf[..]; + read_body(&channel_read, &mut packet) + }) +} diff --git a/src/run.rs b/src/run.rs index 43a2f1a..515a1a7 100644 --- a/src/run.rs +++ b/src/run.rs @@ -1,15 +1,17 @@ use std::{ - io::{Read as _, Write as _}, - net::TcpStream, + io::{Read as _, Write as _, stdin, stdout}, + net::{Shutdown, TcpStream}, }; -use varint_rs::{VarintReader, VarintWriter as _}; +use serde_json::json; +use varint_rs::{VarintReader, VarintWriter}; use crate::{ Connected, Server, error::Result, readers::{read_packet, read_string}, text::Message, + writers::{write_packet, write_string}, }; pub enum Packet { @@ -24,22 +26,36 @@ impl Server { let Self { mut stream, lang, - state: Connected { .. }, + state: Connected { username, .. }, .. } = 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)) + let mut recv_stream = stream.try_clone().unwrap(); + std::thread::spawn(move || -> Result<()> { + loop { + let packet = read_packet(&mut recv_stream, parse_packet)?; + match packet { + Packet::KeepAlive(id) => handle_keepalive(&mut recv_stream, id)?, + Packet::Chat(m) => { + for m in m { + println!("{}", m.format(&lang)) + } } + Packet::Disconnect => break, + Packet::Other(_, _) => {} } - Packet::Disconnect => break, - Packet::Other(_, _) => {} } + Ok(()) + }); + for line in stdin().lines() { + print!("\x1b[1F\x1b[0K"); + let line = &line?; + write_packet(&mut stream, move |buf| { + buf.write_usize_varint(0x01)?; + write_string(buf, line)?; + Ok(()) + })?; } + stream.shutdown(Shutdown::Both)?; Ok(()) } }