From 2d136b1c246453bfea0a2cd209b11e6592b12407 Mon Sep 17 00:00:00 2001 From: smuu <18609909+smuu@users.noreply.github.com> Date: Sun, 29 Dec 2024 16:43:25 +0100 Subject: [PATCH] fix: command permission message (#428) * fix: command permission handling Signed-off-by: Smuu <18609909+Smuu@users.noreply.github.com> * fix: formatting Signed-off-by: Smuu <18609909+Smuu@users.noreply.github.com> --------- Signed-off-by: Smuu <18609909+Smuu@users.noreply.github.com> --- pumpkin/src/command/client_cmd_suggestions.rs | 8 +++ pumpkin/src/command/commands/cmd_fill.rs | 26 +++---- pumpkin/src/command/commands/cmd_gamemode.rs | 13 ++-- pumpkin/src/command/commands/cmd_give.rs | 13 ++-- pumpkin/src/command/commands/cmd_op.rs | 9 +-- pumpkin/src/command/commands/cmd_say.rs | 9 +-- pumpkin/src/command/commands/cmd_seed.rs | 8 +-- pumpkin/src/command/commands/cmd_setblock.rs | 20 +++--- pumpkin/src/command/commands/cmd_stop.rs | 6 +- pumpkin/src/command/commands/cmd_teleport.rs | 71 +++++++++---------- pumpkin/src/command/commands/cmd_time.rs | 32 ++++----- pumpkin/src/command/commands/cmd_transfer.rs | 25 +++---- pumpkin/src/command/dispatcher.rs | 34 +++++++-- pumpkin/src/command/mod.rs | 38 +++++----- pumpkin/src/command/tree_builder.rs | 5 +- 15 files changed, 155 insertions(+), 162 deletions(-) diff --git a/pumpkin/src/command/client_cmd_suggestions.rs b/pumpkin/src/command/client_cmd_suggestions.rs index 707dfcf5..39da02ea 100644 --- a/pumpkin/src/command/client_cmd_suggestions.rs +++ b/pumpkin/src/command/client_cmd_suggestions.rs @@ -20,6 +20,14 @@ pub async fn send_c_commands_packet(player: &Arc, dispatcher: &RwLock CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Two) && sender.world().is_some()) - .with_child( - argument(ARG_FROM, BlockPosArgumentConsumer).with_child( - argument(ARG_TO, BlockPosArgumentConsumer).with_child( - argument(ARG_BLOCK, BlockArgumentConsumer) - .with_child(literal("destroy").execute(SetblockExecutor(Mode::Destroy))) - .with_child(literal("hollow").execute(SetblockExecutor(Mode::Hollow))) - .with_child(literal("keep").execute(SetblockExecutor(Mode::Keep))) - .with_child(literal("outline").execute(SetblockExecutor(Mode::Outline))) - .with_child(literal("replace").execute(SetblockExecutor(Mode::Replace))) - .execute(SetblockExecutor(Mode::Replace)), - ), - ), + argument(ARG_FROM, BlockPosArgumentConsumer).with_child( + argument(ARG_TO, BlockPosArgumentConsumer).with_child( + argument(ARG_BLOCK, BlockArgumentConsumer) + .with_child(literal("destroy").execute(SetblockExecutor(Mode::Destroy))) + .with_child(literal("hollow").execute(SetblockExecutor(Mode::Hollow))) + .with_child(literal("keep").execute(SetblockExecutor(Mode::Keep))) + .with_child(literal("outline").execute(SetblockExecutor(Mode::Outline))) + .with_child(literal("replace").execute(SetblockExecutor(Mode::Replace))) + .execute(SetblockExecutor(Mode::Replace)), ), + ), ) } diff --git a/pumpkin/src/command/commands/cmd_gamemode.rs b/pumpkin/src/command/commands/cmd_gamemode.rs index 1b586130..14f16911 100644 --- a/pumpkin/src/command/commands/cmd_gamemode.rs +++ b/pumpkin/src/command/commands/cmd_gamemode.rs @@ -4,7 +4,6 @@ use crate::command::args::arg_gamemode::GamemodeArgumentConsumer; use crate::command::args::GetCloned; use crate::TextComponent; -use pumpkin_core::permission::PermissionLvl; use crate::command::args::arg_players::PlayersArgumentConsumer; @@ -109,12 +108,10 @@ impl CommandExecutor for GamemodeTargetPlayer { #[allow(clippy::redundant_closure_for_method_calls)] pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Two)).with_child( - argument(ARG_GAMEMODE, GamemodeArgumentConsumer) - .with_child(require(|sender| sender.is_player()).execute(GamemodeTargetSelf)) - .with_child( - argument(ARG_TARGET, PlayersArgumentConsumer).execute(GamemodeTargetPlayer), - ), - ), + argument(ARG_GAMEMODE, GamemodeArgumentConsumer) + .with_child(require(|sender| sender.is_player()).execute(GamemodeTargetSelf)) + .with_child( + argument(ARG_TARGET, PlayersArgumentConsumer).execute(GamemodeTargetPlayer), + ), ) } diff --git a/pumpkin/src/command/commands/cmd_give.rs b/pumpkin/src/command/commands/cmd_give.rs index d3f91baf..6b9b3f07 100644 --- a/pumpkin/src/command/commands/cmd_give.rs +++ b/pumpkin/src/command/commands/cmd_give.rs @@ -7,9 +7,8 @@ use crate::command::args::arg_item::ItemArgumentConsumer; use crate::command::args::arg_players::PlayersArgumentConsumer; use crate::command::args::{ConsumedArgs, FindArg, FindArgDefaultName}; use crate::command::tree::CommandTree; -use crate::command::tree_builder::{argument, argument_default_name, require}; +use crate::command::tree_builder::{argument, argument_default_name}; use crate::command::{CommandError, CommandExecutor, CommandSender}; -use pumpkin_core::permission::PermissionLvl; const NAMES: [&str; 1] = ["give"]; @@ -76,12 +75,10 @@ impl CommandExecutor for GiveExecutor { pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Two)).with_child( - argument_default_name(PlayersArgumentConsumer).with_child( - argument(ARG_ITEM, ItemArgumentConsumer) - .execute(GiveExecutor) - .with_child(argument_default_name(item_count_consumer()).execute(GiveExecutor)), - ), + argument_default_name(PlayersArgumentConsumer).with_child( + argument(ARG_ITEM, ItemArgumentConsumer) + .execute(GiveExecutor) + .with_child(argument_default_name(item_count_consumer()).execute(GiveExecutor)), ), ) } diff --git a/pumpkin/src/command/commands/cmd_op.rs b/pumpkin/src/command/commands/cmd_op.rs index 614ffcc7..41206fcb 100644 --- a/pumpkin/src/command/commands/cmd_op.rs +++ b/pumpkin/src/command/commands/cmd_op.rs @@ -2,14 +2,13 @@ use crate::{ command::{ args::{arg_players::PlayersArgumentConsumer, Arg, ConsumedArgs}, tree::CommandTree, - tree_builder::{argument, require}, + tree_builder::argument, CommandError, CommandExecutor, CommandSender, }, data::{op_data::OPERATOR_CONFIG, SaveJSONConfiguration}, }; use async_trait::async_trait; use pumpkin_config::{op::Op, BASIC_CONFIG}; -use pumpkin_core::permission::PermissionLvl; use pumpkin_core::text::TextComponent; use CommandError::InvalidConsumption; @@ -73,8 +72,6 @@ impl CommandExecutor for OpExecutor { } pub fn init_command_tree() -> CommandTree { - CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Three)) - .with_child(argument(ARG_TARGET, PlayersArgumentConsumer).execute(OpExecutor)), - ) + CommandTree::new(NAMES, DESCRIPTION) + .with_child(argument(ARG_TARGET, PlayersArgumentConsumer).execute(OpExecutor)) } diff --git a/pumpkin/src/command/commands/cmd_say.rs b/pumpkin/src/command/commands/cmd_say.rs index ffeb9c88..9ee8874d 100644 --- a/pumpkin/src/command/commands/cmd_say.rs +++ b/pumpkin/src/command/commands/cmd_say.rs @@ -5,10 +5,9 @@ use pumpkin_protocol::client::play::CSystemChatMessage; use crate::command::{ args::{arg_message::MsgArgConsumer, Arg, ConsumedArgs}, tree::CommandTree, - tree_builder::{argument, require}, + tree_builder::argument, CommandError, CommandExecutor, CommandSender, }; -use pumpkin_core::permission::PermissionLvl; use CommandError::InvalidConsumption; const NAMES: [&str; 1] = ["say"]; @@ -42,8 +41,6 @@ impl CommandExecutor for SayExecutor { } pub fn init_command_tree() -> CommandTree { - CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Two)) - .with_child(argument(ARG_MESSAGE, MsgArgConsumer).execute(SayExecutor)), - ) + CommandTree::new(NAMES, DESCRIPTION) + .with_child(argument(ARG_MESSAGE, MsgArgConsumer).execute(SayExecutor)) } diff --git a/pumpkin/src/command/commands/cmd_seed.rs b/pumpkin/src/command/commands/cmd_seed.rs index 50fe6ecd..a3094193 100644 --- a/pumpkin/src/command/commands/cmd_seed.rs +++ b/pumpkin/src/command/commands/cmd_seed.rs @@ -1,9 +1,7 @@ -use crate::command::tree_builder::require; use crate::command::{ args::ConsumedArgs, tree::CommandTree, CommandError, CommandExecutor, CommandSender, }; use async_trait::async_trait; -use pumpkin_core::permission::PermissionLvl; use pumpkin_core::text::click::ClickEvent; use pumpkin_core::text::hover::HoverEvent; use pumpkin_core::text::{color::NamedColor, TextComponent}; @@ -55,9 +53,5 @@ impl CommandExecutor for PumpkinExecutor { } pub fn init_command_tree() -> CommandTree { - CommandTree::new(NAMES, DESCRIPTION) - .with_child(require(|sender| { - sender.has_permission_lvl(PermissionLvl::Two) - })) - .execute(PumpkinExecutor) + CommandTree::new(NAMES, DESCRIPTION).execute(PumpkinExecutor) } diff --git a/pumpkin/src/command/commands/cmd_setblock.rs b/pumpkin/src/command/commands/cmd_setblock.rs index 82e81392..ee8310d0 100644 --- a/pumpkin/src/command/commands/cmd_setblock.rs +++ b/pumpkin/src/command/commands/cmd_setblock.rs @@ -6,9 +6,8 @@ use crate::command::args::arg_block::BlockArgumentConsumer; use crate::command::args::arg_position_block::BlockPosArgumentConsumer; use crate::command::args::{ConsumedArgs, FindArg}; use crate::command::tree::CommandTree; -use crate::command::tree_builder::{argument, literal, require}; +use crate::command::tree_builder::{argument, literal}; use crate::command::{CommandError, CommandExecutor, CommandSender}; -use pumpkin_core::permission::PermissionLvl; const NAMES: [&str; 1] = ["setblock"]; @@ -81,15 +80,12 @@ impl CommandExecutor for SetblockExecutor { pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Two) && sender.world().is_some()) - .with_child( - argument(ARG_BLOCK_POS, BlockPosArgumentConsumer).with_child( - argument(ARG_BLOCK, BlockArgumentConsumer) - .with_child(literal("replace").execute(SetblockExecutor(Mode::Replace))) - .with_child(literal("destroy").execute(SetblockExecutor(Mode::Destroy))) - .with_child(literal("keep").execute(SetblockExecutor(Mode::Keep))) - .execute(SetblockExecutor(Mode::Replace)), - ), - ), + argument(ARG_BLOCK_POS, BlockPosArgumentConsumer).with_child( + argument(ARG_BLOCK, BlockArgumentConsumer) + .with_child(literal("replace").execute(SetblockExecutor(Mode::Replace))) + .with_child(literal("destroy").execute(SetblockExecutor(Mode::Destroy))) + .with_child(literal("keep").execute(SetblockExecutor(Mode::Keep))) + .execute(SetblockExecutor(Mode::Replace)), + ), ) } diff --git a/pumpkin/src/command/commands/cmd_stop.rs b/pumpkin/src/command/commands/cmd_stop.rs index 6368988c..c1f3f4f3 100644 --- a/pumpkin/src/command/commands/cmd_stop.rs +++ b/pumpkin/src/command/commands/cmd_stop.rs @@ -4,9 +4,7 @@ use pumpkin_core::text::TextComponent; use crate::command::args::ConsumedArgs; use crate::command::tree::CommandTree; -use crate::command::tree_builder::require; use crate::command::{CommandError, CommandExecutor, CommandSender}; -use pumpkin_core::permission::PermissionLvl; const NAMES: [&str; 1] = ["stop"]; @@ -38,7 +36,5 @@ impl CommandExecutor for StopExecutor { } pub fn init_command_tree() -> CommandTree { - CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Four)).execute(StopExecutor), - ) + CommandTree::new(NAMES, DESCRIPTION).execute(StopExecutor) } diff --git a/pumpkin/src/command/commands/cmd_teleport.rs b/pumpkin/src/command/commands/cmd_teleport.rs index 59ccc960..d5f535f1 100644 --- a/pumpkin/src/command/commands/cmd_teleport.rs +++ b/pumpkin/src/command/commands/cmd_teleport.rs @@ -9,10 +9,9 @@ use crate::command::args::arg_rotation::RotationArgumentConsumer; use crate::command::args::ConsumedArgs; use crate::command::args::FindArg; use crate::command::tree::CommandTree; -use crate::command::tree_builder::{argument, literal, require}; +use crate::command::tree_builder::{argument, literal}; use crate::command::CommandError; use crate::command::{CommandExecutor, CommandSender}; -use pumpkin_core::permission::PermissionLvl; const NAMES: [&str; 2] = ["teleport", "tp"]; const DESCRIPTION: &str = "Teleports entities, including players."; // todo @@ -238,41 +237,37 @@ impl CommandExecutor for TpSelfToPosExecutor { } pub fn init_command_tree() -> CommandTree { - CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Two)) - .with_child( - argument(ARG_LOCATION, Position3DArgumentConsumer).execute(TpSelfToPosExecutor), - ) - .with_child( - argument(ARG_DESTINATION, EntityArgumentConsumer).execute(TpSelfToEntityExecutor), - ) - .with_child( - argument(ARG_TARGETS, EntitiesArgumentConsumer) - .with_child( - argument(ARG_LOCATION, Position3DArgumentConsumer) - .execute(TpEntitiesToPosExecutor) - .with_child( - argument(ARG_ROTATION, RotationArgumentConsumer) - .execute(TpEntitiesToPosWithRotationExecutor), - ) - .with_child( - literal("facing") - .with_child( - literal("entity").with_child( - argument(ARG_FACING_ENTITY, EntityArgumentConsumer) - .execute(TpEntitiesToPosFacingEntityExecutor), - ), - ) - .with_child( - argument(ARG_FACING_LOCATION, Position3DArgumentConsumer) - .execute(TpEntitiesToPosFacingPosExecutor), + CommandTree::new(NAMES, DESCRIPTION) + .with_child(argument(ARG_LOCATION, Position3DArgumentConsumer).execute(TpSelfToPosExecutor)) + .with_child( + argument(ARG_DESTINATION, EntityArgumentConsumer).execute(TpSelfToEntityExecutor), + ) + .with_child( + argument(ARG_TARGETS, EntitiesArgumentConsumer) + .with_child( + argument(ARG_LOCATION, Position3DArgumentConsumer) + .execute(TpEntitiesToPosExecutor) + .with_child( + argument(ARG_ROTATION, RotationArgumentConsumer) + .execute(TpEntitiesToPosWithRotationExecutor), + ) + .with_child( + literal("facing") + .with_child( + literal("entity").with_child( + argument(ARG_FACING_ENTITY, EntityArgumentConsumer) + .execute(TpEntitiesToPosFacingEntityExecutor), ), - ), - ) - .with_child( - argument(ARG_DESTINATION, EntityArgumentConsumer) - .execute(TpEntitiesToEntityExecutor), - ), - ), - ) + ) + .with_child( + argument(ARG_FACING_LOCATION, Position3DArgumentConsumer) + .execute(TpEntitiesToPosFacingPosExecutor), + ), + ), + ) + .with_child( + argument(ARG_DESTINATION, EntityArgumentConsumer) + .execute(TpEntitiesToEntityExecutor), + ), + ) } diff --git a/pumpkin/src/command/commands/cmd_time.rs b/pumpkin/src/command/commands/cmd_time.rs index 9cc45ec6..c28f712a 100644 --- a/pumpkin/src/command/commands/cmd_time.rs +++ b/pumpkin/src/command/commands/cmd_time.rs @@ -6,10 +6,8 @@ use crate::command::args::arg_bounded_num::BoundedNumArgumentConsumer; use crate::command::args::FindArgDefaultName; use crate::command::tree_builder::{argument_default_name, literal}; use crate::command::{ - tree::CommandTree, tree_builder::require, CommandError, CommandExecutor, CommandSender, - ConsumedArgs, + tree::CommandTree, CommandError, CommandExecutor, CommandSender, ConsumedArgs, }; -use pumpkin_core::permission::PermissionLvl; const NAMES: [&str; 1] = ["time"]; @@ -125,19 +123,21 @@ impl CommandExecutor for TimeChangeExecutor { } pub fn init_command_tree() -> CommandTree { - CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Two)) - .with_child(literal("add").with_child( + CommandTree::new(NAMES, DESCRIPTION) + .with_child( + literal("add").with_child( argument_default_name(arg_number()).execute(TimeChangeExecutor(Mode::Add)), - )) - .with_child( - literal("query") - .with_child(literal("daytime").execute(TimeQueryExecutor(QueryMode::DayTime))) - .with_child(literal("gametime").execute(TimeQueryExecutor(QueryMode::GameTime))) - .with_child(literal("day").execute(TimeQueryExecutor(QueryMode::Day))), - ) - .with_child(literal("set").with_child( + ), + ) + .with_child( + literal("query") + .with_child(literal("daytime").execute(TimeQueryExecutor(QueryMode::DayTime))) + .with_child(literal("gametime").execute(TimeQueryExecutor(QueryMode::GameTime))) + .with_child(literal("day").execute(TimeQueryExecutor(QueryMode::Day))), + ) + .with_child( + literal("set").with_child( argument_default_name(arg_number()).execute(TimeChangeExecutor(Mode::Set)), - )), - ) + ), + ) } diff --git a/pumpkin/src/command/commands/cmd_transfer.rs b/pumpkin/src/command/commands/cmd_transfer.rs index 8aa41251..50473920 100644 --- a/pumpkin/src/command/commands/cmd_transfer.rs +++ b/pumpkin/src/command/commands/cmd_transfer.rs @@ -13,7 +13,6 @@ use crate::command::tree_builder::{argument, argument_default_name, require}; use crate::command::{ args::ConsumedArgs, tree::CommandTree, CommandError, CommandExecutor, CommandSender, }; -use pumpkin_core::permission::PermissionLvl; const NAMES: [&str; 1] = ["transfer"]; @@ -121,19 +120,15 @@ impl CommandExecutor for TransferTargetPlayer { #[allow(clippy::redundant_closure_for_method_calls)] pub fn init_command_tree() -> CommandTree { CommandTree::new(NAMES, DESCRIPTION).with_child( - require(|sender| sender.has_permission_lvl(PermissionLvl::Three)).with_child( - argument(ARG_HOSTNAME, SimpleArgConsumer) - .with_child(require(|sender| sender.is_player()).execute(TransferTargetSelf)) - .with_child( - argument_default_name(port_consumer()) - .with_child( - require(|sender| sender.is_player()).execute(TransferTargetSelf), - ) - .with_child( - argument(ARG_PLAYERS, PlayersArgumentConsumer) - .execute(TransferTargetPlayer), - ), - ), - ), + argument(ARG_HOSTNAME, SimpleArgConsumer) + .with_child(require(|sender| sender.is_player()).execute(TransferTargetSelf)) + .with_child( + argument_default_name(port_consumer()) + .with_child(require(|sender| sender.is_player()).execute(TransferTargetSelf)) + .with_child( + argument(ARG_PLAYERS, PlayersArgumentConsumer) + .execute(TransferTargetPlayer), + ), + ), ) } diff --git a/pumpkin/src/command/dispatcher.rs b/pumpkin/src/command/dispatcher.rs index 4d1bb943..b59b0680 100644 --- a/pumpkin/src/command/dispatcher.rs +++ b/pumpkin/src/command/dispatcher.rs @@ -1,10 +1,11 @@ +use pumpkin_core::permission::PermissionLvl; use pumpkin_core::text::TextComponent; use pumpkin_protocol::client::play::CommandSuggestion; use super::args::ConsumedArgs; use crate::command::dispatcher::CommandError::{ - GeneralCommandIssue, InvalidConsumption, InvalidRequirement, OtherPumpkin, + GeneralCommandIssue, InvalidConsumption, InvalidRequirement, OtherPumpkin, PermissionDenied, }; use crate::command::tree::{Command, CommandTree, NodeType, RawArgs}; use crate::command::CommandSender; @@ -23,6 +24,8 @@ pub(crate) enum CommandError { /// Return this if a condition that a [`Node::Require`] should ensure is met is not met. InvalidRequirement, + PermissionDenied, + OtherPumpkin(Box), GeneralCommandIssue(String), @@ -39,6 +42,10 @@ impl CommandError { log::error!("Error while parsing command \"{cmd}\": a requirement that was expected was not met."); Ok("Internal Error (See logs for details)".into()) } + PermissionDenied => { + log::warn!("Permission denied for command \"{cmd}\""); + Ok("I'm sorry, but you do not have permission to perform this command. Please contact the server administrator if you believe this is an error.".into()) + } GeneralCommandIssue(s) => Ok(s), OtherPumpkin(e) => Err(e), } @@ -48,6 +55,7 @@ impl CommandError { #[derive(Default)] pub struct CommandDispatcher { pub(crate) commands: HashMap, + pub(crate) permissions: HashMap, } /// Stores registered [`CommandTree`]s and dispatches commands to them. @@ -113,6 +121,10 @@ impl CommandDispatcher { log::error!("Error while parsing command \"{cmd}\": a requirement that was expected was not met."); return Vec::new(); } + Err(PermissionDenied) => { + log::warn!("Permission denied for command \"{cmd}\""); + return Vec::new(); + } Err(GeneralCommandIssue(issue)) => { log::error!("Error while parsing command \"{cmd}\": {issue}"); return Vec::new(); @@ -147,6 +159,14 @@ impl CommandDispatcher { .ok_or(GeneralCommandIssue("Empty Command".to_string()))?; let raw_args: Vec<&str> = parts.rev().collect(); + let Some(permission) = self.permissions.get(key) else { + return Err(GeneralCommandIssue("Command not found".to_string())); + }; + + if !src.has_permission_lvl(*permission) { + return Err(PermissionDenied); + } + let tree = self.get_tree(key)?; // try paths until fitting path is found @@ -180,6 +200,10 @@ impl CommandDispatcher { } } + pub(crate) fn get_permission_lvl(&self, key: &str) -> Option { + self.permissions.get(key).copied() + } + async fn try_is_fitting_path<'a>( src: &mut CommandSender<'a>, server: &'a Server, @@ -270,7 +294,7 @@ impl CommandDispatcher { } /// Register a command with the dispatcher. - pub(crate) fn register(&mut self, tree: CommandTree) { + pub(crate) fn register(&mut self, tree: CommandTree, permission: PermissionLvl) { let mut names = tree.names.iter(); let primary_name = names.next().expect("at least one name must be provided"); @@ -280,6 +304,8 @@ impl CommandDispatcher { .insert(name.to_string(), Command::Alias(primary_name.to_string())); } + self.permissions + .insert(primary_name.to_string(), permission); self.commands .insert(primary_name.to_string(), Command::Tree(tree)); } @@ -288,11 +314,11 @@ impl CommandDispatcher { #[cfg(test)] mod test { use crate::command::{default_dispatcher, tree::CommandTree}; - + use pumpkin_core::permission::PermissionLvl; #[test] fn test_dynamic_command() { let mut dispatcher = default_dispatcher(); let tree = CommandTree::new(["test"], "test_desc"); - dispatcher.register(tree); + dispatcher.register(tree, PermissionLvl::Zero); } } diff --git a/pumpkin/src/command/mod.rs b/pumpkin/src/command/mod.rs index c05017ed..4e922579 100644 --- a/pumpkin/src/command/mod.rs +++ b/pumpkin/src/command/mod.rs @@ -112,25 +112,25 @@ impl<'a> CommandSender<'a> { pub fn default_dispatcher() -> CommandDispatcher { let mut dispatcher = CommandDispatcher::default(); - dispatcher.register(cmd_pumpkin::init_command_tree()); - dispatcher.register(cmd_bossbar::init_command_tree()); - dispatcher.register(cmd_say::init_command_tree()); - dispatcher.register(cmd_gamemode::init_command_tree()); - dispatcher.register(cmd_stop::init_command_tree()); - dispatcher.register(cmd_help::init_command_tree()); - dispatcher.register(cmd_kill::init_command_tree()); - dispatcher.register(cmd_kick::init_command_tree()); - dispatcher.register(cmd_worldborder::init_command_tree()); - dispatcher.register(cmd_teleport::init_command_tree()); - dispatcher.register(cmd_time::init_command_tree()); - dispatcher.register(cmd_give::init_command_tree()); - dispatcher.register(cmd_list::init_command_tree()); - dispatcher.register(cmd_clear::init_command_tree()); - dispatcher.register(cmd_setblock::init_command_tree()); - dispatcher.register(cmd_seed::init_command_tree()); - dispatcher.register(cmd_transfer::init_command_tree()); - dispatcher.register(cmd_fill::init_command_tree()); - dispatcher.register(cmd_op::init_command_tree()); + dispatcher.register(cmd_pumpkin::init_command_tree(), PermissionLvl::Zero); + dispatcher.register(cmd_bossbar::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_say::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_gamemode::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_stop::init_command_tree(), PermissionLvl::Four); + dispatcher.register(cmd_help::init_command_tree(), PermissionLvl::Zero); + dispatcher.register(cmd_kill::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_kick::init_command_tree(), PermissionLvl::Three); + dispatcher.register(cmd_worldborder::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_teleport::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_time::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_give::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_list::init_command_tree(), PermissionLvl::Zero); + dispatcher.register(cmd_clear::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_setblock::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_seed::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_transfer::init_command_tree(), PermissionLvl::Zero); + dispatcher.register(cmd_fill::init_command_tree(), PermissionLvl::Two); + dispatcher.register(cmd_op::init_command_tree(), PermissionLvl::Three); dispatcher } diff --git a/pumpkin/src/command/tree_builder.rs b/pumpkin/src/command/tree_builder.rs index 92f65d9e..f9d5bff9 100644 --- a/pumpkin/src/command/tree_builder.rs +++ b/pumpkin/src/command/tree_builder.rs @@ -1,12 +1,11 @@ use std::sync::Arc; +use super::args::DefaultNameArgConsumer; +use super::CommandExecutor; use crate::command::args::ArgumentConsumer; use crate::command::tree::{CommandTree, Node, NodeType}; use crate::command::CommandSender; -use super::args::DefaultNameArgConsumer; -use super::CommandExecutor; - impl CommandTree { /// Add a child [Node] to the root of this [`CommandTree`]. pub fn with_child(mut self, child: impl NodeBuilder) -> Self {