implement kick command

This commit is contained in:
Zoey 2024-04-22 22:40:34 -07:00
parent 98ffb28eb2
commit 5b7b947804
No known key found for this signature in database
GPG key ID: 8611B896D1AAFAF2
3 changed files with 56 additions and 4 deletions

View file

@ -3,6 +3,7 @@ use crate::player::PlayerType;
const CMD_ME: &str = "me"; const CMD_ME: &str = "me";
const CMD_SAY: &str = "say"; const CMD_SAY: &str = "say";
const CMD_SET_PERM: &str = "set-perm"; const CMD_SET_PERM: &str = "set-perm";
const CMD_KICK: &str = "kick";
/// enum for possible commands /// enum for possible commands
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -18,6 +19,10 @@ pub enum Command<'m> {
player_username: &'m str, player_username: &'m str,
permissions: PlayerType, permissions: PlayerType,
}, },
Kick {
username: &'m str,
message: Option<&'m str>,
},
} }
impl<'m> Command<'m> { impl<'m> Command<'m> {
@ -34,6 +39,12 @@ impl<'m> Command<'m> {
player_username: Self::next_string(&mut arguments)?, player_username: Self::next_string(&mut arguments)?,
permissions: arguments.trim().try_into()?, 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}")), _ => return Err(format!("Unknown command: {command_name}")),
}) })
} }

View file

@ -29,6 +29,8 @@ pub struct Player {
pub _addr: SocketAddr, pub _addr: SocketAddr,
/// queue of packets to be sent to this player /// queue of packets to be sent to this player
pub packets_to_send: Vec<ServerPacket>, pub packets_to_send: Vec<ServerPacket>,
/// whether this player should be kicked and the message to give
pub should_be_kicked: Option<String>,
} }
/// enum describing types of players /// enum describing types of players

View file

@ -48,6 +48,7 @@ pub(super) async fn handle_stream(
let mut data = data.write().await; let mut data = data.write().await;
if let Some(index) = data.players.iter().position(|p| p.id == own_id) { if let Some(index) = data.players.iter().position(|p| p.id == own_id) {
let player = data.players.remove(index); let player = data.players.remove(index);
data.free_player_ids.push(player.id);
let despawn_packet = ServerPacket::DespawnPlayer { player_id: own_id }; let despawn_packet = ServerPacket::DespawnPlayer { player_id: own_id };
let message_packet = ServerPacket::Message { let message_packet = ServerPacket::Message {
@ -92,6 +93,12 @@ async fn handle_stream_inner(
} }
loop { 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 let ready = stream
.ready(Interest::READABLE | Interest::WRITABLE) .ready(Interest::READABLE | Interest::WRITABLE)
.await?; .await?;
@ -179,6 +186,7 @@ async fn handle_stream_inner(
pitch: 0, pitch: 0,
player_type, player_type,
packets_to_send: Vec::new(), packets_to_send: Vec::new(),
should_be_kicked: None,
}; };
reply_queue.push_back(ServerPacket::ServerIdentification { reply_queue.push_back(ServerPacket::ServerIdentification {
@ -335,7 +343,7 @@ async fn handle_stream_inner(
.expect("missing player"); .expect("missing player");
if cmd.perms_required() > player.player_type { 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; continue;
} }
@ -374,10 +382,10 @@ async fn handle_stream_inner(
} => { } => {
let player_perms = player.player_type; let player_perms = player.player_type;
if player_username == player.username { if player_username == player.username {
msg!("Cannot change your own permissions".to_string()); msg!("&cCannot change your own permissions".to_string());
continue; continue;
} else if permissions >= player_perms { } 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; continue;
} }
@ -391,7 +399,7 @@ async fn handle_stream_inner(
.entry(player_username.to_string()) .entry(player_username.to_string())
.or_default(); .or_default();
if *current >= player_perms { if *current >= player_perms {
msg!("This player outranks you" msg!("&cThis player outranks or is the same rank as you"
.to_string()); .to_string());
continue; continue;
} }
@ -415,6 +423,37 @@ async fn handle_stream_inner(
} }
msg!(format!("Set permissions for {player_username} to {perm_string}")); 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("<no message>")
.to_string(),
);
msg!(format!(
"{} has been kicked",
other_player.username
));
} else {
msg!(
"&cPlayer not connected to server!"
.to_string()
);
}
}
} }
} }
Err(msg) => { Err(msg) => {