From cd9068bd17ca16e4941fe0cf8e82b4787e611a64 Mon Sep 17 00:00:00 2001 From: Laptop59 <90901102+Laptop59@users.noreply.github.com> Date: Sun, 5 Apr 2026 15:27:16 +0530 Subject: [PATCH] feat(command): reimplement `/setidletimeout` (#1967) * reimplemented `/setidletimeout` and fixed swappage of format args in error type helper method * switched to use `register_permission_or_panic` --- .../src/command/argument_types/core/mod.rs | 4 +- pumpkin/src/command/commands/mod.rs | 13 +-- .../src/command/commands/setidletimeout.rs | 83 ++++++++++--------- 3 files changed, 47 insertions(+), 53 deletions(-) diff --git a/pumpkin/src/command/argument_types/core/mod.rs b/pumpkin/src/command/argument_types/core/mod.rs index e3c24e09b..4e39b6fec 100644 --- a/pumpkin/src/command/argument_types/core/mod.rs +++ b/pumpkin/src/command/argument_types/core/mod.rs @@ -30,15 +30,15 @@ where reader.set_cursor(reader_start); Err(too_low_error_type.create( reader, - TextComponent::text(value.to_string()), TextComponent::text(min.to_string()), + TextComponent::text(value.to_string()), )) } else if value > max { reader.set_cursor(reader_start); Err(too_high_error_type.create( reader, - TextComponent::text(value.to_string()), TextComponent::text(max.to_string()), + TextComponent::text(value.to_string()), )) } else { Ok(value) diff --git a/pumpkin/src/command/commands/mod.rs b/pumpkin/src/command/commands/mod.rs index 9f095da61..4b5a148b0 100644 --- a/pumpkin/src/command/commands/mod.rs +++ b/pumpkin/src/command/commands/mod.rs @@ -146,10 +146,6 @@ pub async fn default_dispatcher( "minecraft:command.whitelist", ); dispatcher.register(transfer::init_command_tree(), "minecraft:command.transfer"); - dispatcher.register( - setidletimeout::init_command_tree(), - "minecraft:command.setidletimeout", - ); let mut dispatcher = { let mut wrapper_dispatcher = CommandDispatcher::new(); @@ -160,6 +156,7 @@ pub async fn default_dispatcher( difficulty::register(&mut dispatcher, registry); help::register(&mut dispatcher, registry); seed::register(&mut dispatcher, registry); + setidletimeout::register(&mut dispatcher, registry); stop::register(&mut dispatcher, registry); dispatcher @@ -418,7 +415,6 @@ fn register_level_2_permissions(registry: &mut PermissionRegistry) { .unwrap(); } -#[expect(clippy::too_many_lines)] fn register_level_3_permissions(registry: &mut PermissionRegistry) { // Register permissions for commands with PermissionLvl::Three registry @@ -519,11 +515,4 @@ fn register_level_3_permissions(registry: &mut PermissionRegistry) { PermissionDefault::Op(PermissionLvl::Three), )) .unwrap(); - registry - .register_permission(Permission::new( - "minecraft:command.setidletimeout", - "Sets the time before idle players are kicked", - PermissionDefault::Op(PermissionLvl::Three), - )) - .unwrap(); } diff --git a/pumpkin/src/command/commands/setidletimeout.rs b/pumpkin/src/command/commands/setidletimeout.rs index db5581ad2..b3e9ab340 100644 --- a/pumpkin/src/command/commands/setidletimeout.rs +++ b/pumpkin/src/command/commands/setidletimeout.rs @@ -1,55 +1,49 @@ use std::sync::atomic::Ordering; -use pumpkin_util::text::TextComponent; +use pumpkin_util::{ + PermissionLvl, + permission::{Permission, PermissionDefault, PermissionRegistry}, + text::TextComponent, +}; -use crate::command::args::bounded_num::BoundedNumArgumentConsumer; -use crate::command::args::{Arg, GetCloned}; -use crate::command::dispatcher::CommandError; -use crate::command::tree::CommandTree; -use crate::command::tree::builder::argument; -use crate::command::{CommandExecutor, CommandResult, CommandSender, args::ConsumedArgs}; - -const NAMES: [&str; 1] = ["setidletimeout"]; +use crate::command::{ + argument_builder::{ArgumentBuilder, argument, command}, + argument_types::core::integer::IntegerArgumentType, + context::command_context::CommandContext, + node::{CommandExecutor, CommandExecutorResult, dispatcher::CommandDispatcher}, +}; const DESCRIPTION: &str = "Sets the time before idle players are kicked from the server."; +const PERMISSION: &str = "minecraft:command.setidletimeout"; const ARG_MINUTES: &str = "minutes"; -const fn minutes_consumer() -> BoundedNumArgumentConsumer { - BoundedNumArgumentConsumer::new().min(0).name(ARG_MINUTES) -} - struct SetIdleTimeoutExecutor; impl CommandExecutor for SetIdleTimeoutExecutor { - fn execute<'a>( - &'a self, - sender: &'a CommandSender, - server: &'a crate::server::Server, - args: &'a ConsumedArgs<'a>, - ) -> CommandResult<'a> { + fn execute<'a>(&'a self, context: &'a CommandContext) -> CommandExecutorResult<'a> { Box::pin(async move { - let Some(Arg::Num(Ok(minutes))) = args.get_cloned(&ARG_MINUTES) else { - return Err(CommandError::InvalidConsumption(Some(ARG_MINUTES.into()))); - }; + let minutes: i32 = *context.get_argument(ARG_MINUTES)?; - let crate::command::args::bounded_num::Number::I32(minutes) = minutes else { - return Err(CommandError::InvalidConsumption(Some(ARG_MINUTES.into()))); - }; - - server.player_idle_timeout.store(minutes, Ordering::Relaxed); + context + .server() + .player_idle_timeout + .store(minutes, Ordering::Relaxed); { if minutes == 0 { - sender.send_message(TextComponent::translate( - "commands.setidletimeout.success.disabled", - [], - )) + context.source.send_feedback( + TextComponent::translate("commands.setidletimeout.success.disabled", []), + true, + ) } else { - sender.send_message(TextComponent::translate( - "commands.setidletimeout.success", - [TextComponent::text(minutes.to_string())], - )) + context.source.send_feedback( + TextComponent::translate( + "commands.setidletimeout.success", + [TextComponent::text(minutes.to_string())], + ), + true, + ) } } .await; @@ -59,8 +53,19 @@ impl CommandExecutor for SetIdleTimeoutExecutor { } } -#[must_use] -pub fn init_command_tree() -> CommandTree { - CommandTree::new(NAMES, DESCRIPTION) - .then(argument(ARG_MINUTES, minutes_consumer()).execute(SetIdleTimeoutExecutor)) +pub fn register(dispatcher: &mut CommandDispatcher, registry: &mut PermissionRegistry) { + registry.register_permission_or_panic(Permission::new( + PERMISSION, + DESCRIPTION, + PermissionDefault::Op(PermissionLvl::Three), + )); + + dispatcher.register( + command("setidletimeout", DESCRIPTION) + .requires(PERMISSION) + .then( + argument(ARG_MINUTES, IntegerArgumentType::with_min(0)) + .executes(SetIdleTimeoutExecutor), + ), + ); }