From 5b7b947804ef22afd8b986ace079e95d485c026a Mon Sep 17 00:00:00 2001 From: Zoey Date: Mon, 22 Apr 2024 22:40:34 -0700 Subject: [PATCH] implement kick command --- src/command.rs | 11 ++++++++++ src/player.rs | 2 ++ src/server/network.rs | 47 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/command.rs b/src/command.rs index 40345ae..7650892 100644 --- a/src/command.rs +++ b/src/command.rs @@ -3,6 +3,7 @@ use crate::player::PlayerType; const CMD_ME: &str = "me"; const CMD_SAY: &str = "say"; const CMD_SET_PERM: &str = "set-perm"; +const CMD_KICK: &str = "kick"; /// enum for possible commands #[derive(Debug, Clone)] @@ -18,6 +19,10 @@ pub enum Command<'m> { player_username: &'m str, permissions: PlayerType, }, + Kick { + username: &'m str, + message: Option<&'m str>, + }, } impl<'m> Command<'m> { @@ -34,6 +39,12 @@ impl<'m> Command<'m> { player_username: Self::next_string(&mut arguments)?, permissions: arguments.trim().try_into()?, }, + CMD_KICK => { + let username = Self::next_string(&mut arguments)?; + let message = arguments.trim(); + let message = (!message.is_empty()).then_some(message); + Self::Kick { username, message } + } _ => return Err(format!("Unknown command: {command_name}")), }) } diff --git a/src/player.rs b/src/player.rs index d056884..9ef777f 100644 --- a/src/player.rs +++ b/src/player.rs @@ -29,6 +29,8 @@ pub struct Player { pub _addr: SocketAddr, /// queue of packets to be sent to this player pub packets_to_send: Vec, + /// whether this player should be kicked and the message to give + pub should_be_kicked: Option, } /// enum describing types of players diff --git a/src/server/network.rs b/src/server/network.rs index ecf6820..765a627 100644 --- a/src/server/network.rs +++ b/src/server/network.rs @@ -48,6 +48,7 @@ pub(super) async fn handle_stream( let mut data = data.write().await; if let Some(index) = data.players.iter().position(|p| p.id == own_id) { let player = data.players.remove(index); + data.free_player_ids.push(player.id); let despawn_packet = ServerPacket::DespawnPlayer { player_id: own_id }; let message_packet = ServerPacket::Message { @@ -92,6 +93,12 @@ async fn handle_stream_inner( } loop { + if let Some(player) = data.read().await.players.iter().find(|p| p.id == *own_id) { + if let Some(msg) = &player.should_be_kicked { + return Ok(Some(format!("Kicked: {msg}"))); + } + } + let ready = stream .ready(Interest::READABLE | Interest::WRITABLE) .await?; @@ -179,6 +186,7 @@ async fn handle_stream_inner( pitch: 0, player_type, packets_to_send: Vec::new(), + should_be_kicked: None, }; reply_queue.push_back(ServerPacket::ServerIdentification { @@ -335,7 +343,7 @@ async fn handle_stream_inner( .expect("missing player"); if cmd.perms_required() > player.player_type { - msg!("Permissions do not allow you to use this command".to_string()); + msg!("&cPermissions do not allow you to use this command".to_string()); continue; } @@ -374,10 +382,10 @@ async fn handle_stream_inner( } => { let player_perms = player.player_type; if player_username == player.username { - msg!("Cannot change your own permissions".to_string()); + msg!("&cCannot change your own permissions".to_string()); continue; } else if permissions >= player_perms { - msg!("Cannot set permissions higher or equal to your own".to_string()); + msg!("&cCannot set permissions higher or equal to your own".to_string()); continue; } @@ -391,7 +399,7 @@ async fn handle_stream_inner( .entry(player_username.to_string()) .or_default(); if *current >= player_perms { - msg!("This player outranks you" + msg!("&cThis player outranks or is the same rank as you" .to_string()); continue; } @@ -415,6 +423,37 @@ async fn handle_stream_inner( } msg!(format!("Set permissions for {player_username} to {perm_string}")); } + Command::Kick { username, message } => { + let player_perms = player.player_type; + + if let Some(other_player) = data + .players + .iter_mut() + .find(|p| p.username == username) + { + if player_perms + <= other_player.player_type + { + msg!("&cThis player outranks or is the same rank as you".to_string()); + continue; + } + + other_player.should_be_kicked = Some( + message + .unwrap_or("") + .to_string(), + ); + msg!(format!( + "{} has been kicked", + other_player.username + )); + } else { + msg!( + "&cPlayer not connected to server!" + .to_string() + ); + } + } } } Err(msg) => {