diff --git a/src/packet.rs b/src/packet.rs index e1de20b..a82276a 100644 --- a/src/packet.rs +++ b/src/packet.rs @@ -200,6 +200,9 @@ impl ExtBitmask { // this isn't actually used by the server at all, but it technically sort of implements it Self::HeldBlock => ExtInfo::new("HeldBlock".to_string(), 1, Self::HeldBlock), Self::EmoteFix => ExtInfo::new("EmoteFix".to_string(), 1, Self::EmoteFix), + Self::LongerMessages => { + ExtInfo::new("LongerMessages".to_string(), 1, Self::LongerMessages) + } // TODO: render CP437 properly in server output Self::FullCP437 => ExtInfo::new("FullCP437".to_string(), 1, Self::FullCP437), Self::EnvWeatherType => { diff --git a/src/server.rs b/src/server.rs index 4817da2..80442c2 100644 --- a/src/server.rs +++ b/src/server.rs @@ -58,6 +58,15 @@ impl ServerData { player.packets_to_send.push(packet.clone()); } } + + /// spreads multiple packets to all players + pub fn spread_packets(&mut self, packets: &[ServerPacket]) { + for player in &mut self.players { + for packet in packets { + player.packets_to_send.push(packet.clone()); + } + } + } } impl Server { diff --git a/src/server/network.rs b/src/server/network.rs index e2e94eb..7094986 100644 --- a/src/server/network.rs +++ b/src/server/network.rs @@ -17,7 +17,7 @@ use crate::{ level::{block::BLOCK_INFO, BlockUpdate, Level}, packet::{ client::ClientPacket, server::ServerPacket, ExtBitmask, PacketWriter, ARRAY_LENGTH, - EXTENSION_MAGIC_NUMBER, + EXTENSION_MAGIC_NUMBER, STRING_LENGTH, }, player::{Player, PlayerType}, server::config::ServerProtectionMode, @@ -132,6 +132,7 @@ async fn handle_stream_inner( own_id: &mut i8, ) -> Result<(), GeneralError> { let mut reply_queue: Vec = Vec::new(); + let mut incoming_message: Vec = Vec::new(); macro_rules! msg { ($message:expr) => { @@ -411,6 +412,22 @@ async fn handle_stream_inner( ClientPacket::Message { player_id, message } => { let mut data = data.write().await; + let player = data + .players + .iter() + .find(|p| p.id == *own_id) + .expect("missing player"); + let message = if player.extensions.contains(ExtBitmask::LongerMessages) { + incoming_message.push(message); + if player_id == 0 { + incoming_message.drain(..).collect() + } else { + continue; + } + } else { + message + }; + if let Some(message) = message.strip_prefix(Command::PREFIX) { match Command::parse(message) { Ok(cmd) => { @@ -424,7 +441,8 @@ async fn handle_stream_inner( } } else { println!("{message}"); - let message = format!( + let mut messages = Vec::new(); + let mut message = format!( "&f<{}> {message}", data.players .iter() @@ -432,7 +450,16 @@ async fn handle_stream_inner( .expect("should never fail") .username ); - data.spread_packet(ServerPacket::Message { player_id, message }); + while message.len() > STRING_LENGTH { + // TODO: split on whitespace if possible + let new_message = message.split_off(STRING_LENGTH); + // TODO: this will overwrite color codes and it shouldn't + messages.push(ServerPacket::Message { player_id, message }); + message = format!("&f{new_message}"); + } + messages.push(ServerPacket::Message { player_id, message }); + println!("{messages:#?}"); + data.spread_packets(&messages); } }