Skip to content

Command Warmups #6332

Open
robertsmrek wants to merge 22 commits into
EssentialsX:2.xfrom
robertsmrek:feature/command-warmups-1320
Open

Command Warmups #6332
robertsmrek wants to merge 22 commits into
EssentialsX:2.xfrom
robertsmrek:feature/command-warmups-1320

Conversation

@robertsmrek

@robertsmrek robertsmrek commented Oct 19, 2025

Copy link
Copy Markdown

This PR implements command warmups for EssentialsX, adding a configurable delay before commands are executed. During the warmup period, players must stand still and avoid taking damage, or the command will be cancelled.

This feature works similarly to the existing teleport warmup system but can be applied to any command, providing server administrators with better control over command execution timing.

Closes #1320

Configuration

# Command warmups: Set a delay (in seconds) before a command is executed.
# During the warmup period, the player must stand still (unless they have essentials.commandwarmups.move permission).
# If the player moves or takes damage during this period, the command is cancelled.
command-warmups:
  #home: 5 # 5-second warmup on /home command
  #back: 3 # 3-second warmup on /back command
  #afk: 3 # 3-second warmup on /afk command
  # Wildcards and regex patterns are supported (same as command cooldowns)

# Whether command warmups should persist across server shutdowns.
command-warmup-persistence: true

Features

  • Configurable delay before command execution
  • Movement cancellation (can be bypassed with essentials.commandwarmups.move permission)
  • Damage cancellation (cannot be bypassed)
  • Persistence across server restarts
  • Support for wildcards and regex patterns (e.g., tp*, /^home-.*/)
  • Customizable messages for warmup start, cancel, and completion
  • Permission-based warmup bypass: essentials.commandwarmups.bypass.<command>

Breaking Changes

None. This is a fully opt-in feature with no default warmups configured.

Test Coverage

The unit tests verify:

  • CommandWarmup entity creation and validation
  • Pattern matching (exact, wildcard, regex patterns)
  • Incomplete warmup detection and handling
  • Various warmup duration configurations
  • Pattern equality and string representation
  • Edge cases (null pattern, null value, complete warmup)

Production Validation

  • All warmup functionality (delays, cancellation on movement/damage, permissions, messages) operates as expected
  • No issues reported during real-world testing

@robertsmrek robertsmrek changed the title Command Warmups Resolves #1320 Command Warmups Oct 19, 2025
Copilot AI review requested due to automatic review settings December 3, 2025 12:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a command warmup system for EssentialsX, allowing server administrators to configure delays before commands execute. The feature mirrors the existing teleport warmup functionality but applies to any command, with cancellation triggers for player movement and damage.

Key Changes:

  • Command warmup configuration with pattern matching support (wildcards and regex)
  • Asynchronous timer implementation (AsyncTimedCommand) to handle warmup delays and cancellation
  • Persistence system for warmups across server restarts
  • Permission-based bypass and movement allowance controls

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
CommandWarmupTest.java Unit tests for CommandWarmup entity validation and pattern matching
messages_en.properties Added three new message keys for warmup notifications (start, complete, cancelled)
config.yml Configuration documentation and examples for command warmup settings
CommandWarmupSerializer.java Serialization logic for persisting warmup data
UserConfigHolder.java Added warmup list storage to user timestamps
CommandWarmup.java Entity class defining warmup pattern and expiry value
EssentialsConfiguration.java Registered CommandWarmupSerializer for configuration handling
UserData.java CRUD operations for managing user warmup data
Settings.java Configuration parsing and warmup entry lookup with optimized List-based storage
IUser.java Interface additions for warmup management methods
ISettings.java Interface additions for warmup configuration queries
EssentialsPlayerListener.java Event handler integration for triggering warmups on command execution
AsyncTimedCommand.java Core warmup timer implementation with movement/damage detection and async command execution

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Essentials/src/main/java/com/earth2me/essentials/AsyncTimedCommand.java Outdated
Comment thread Essentials/src/main/resources/messages_en.properties Outdated

// Execute the command by dispatching it to the server
Bukkit.getScheduler().runTask(ess, () -> {
// Execute as server command to bypass the warmup check

Copilot AI Dec 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment mentions "Execute as server command" but the code executes it as the player using Bukkit.dispatchCommand(user.getBase(), ...). This doesn't bypass permission checks as the comment suggests - the command is still executed as the player. If the intent is to bypass warmup checks, this is handled by clearing the warmup first, but the comment is misleading.

Suggested change
// Execute as server command to bypass the warmup check
// Execute the command as the player (not as server); warmup check is bypassed because it was cleared above

Copilot uses AI. Check for mistakes.
Comment thread Essentials/src/main/java/com/earth2me/essentials/AsyncTimedCommand.java Outdated
Comment thread Essentials/src/main/java/com/earth2me/essentials/AsyncTimedCommand.java Outdated
Comment thread Essentials/src/main/java/com/earth2me/essentials/AsyncTimedCommand.java Outdated
Comment on lines +882 to +885
final int argStartIndex = effectiveCommand.indexOf(" ");
final String args = argStartIndex == -1 ? ""
: " " + effectiveCommand.substring(argStartIndex);
final String fullCommand = pluginCommand == null ? effectiveCommand : pluginCommand.getName() + args;

Copilot AI Dec 3, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] This code block for calculating args and fullCommand is duplicated from the command cooldowns section above (lines 836-839). Consider extracting this logic to avoid duplication and ensure consistency if the logic needs to change.

Copilot uses AI. Check for mistakes.
Comment thread Essentials/src/main/java/com/earth2me/essentials/EssentialsPlayerListener.java Outdated
Comment thread Essentials/src/main/java/com/earth2me/essentials/Settings.java Outdated
@robertsmrek

Copy link
Copy Markdown
Author

@copilot open a new pull request to apply changes based on the comments in this thread

robertsmrek and others added 8 commits June 26, 2026 20:54
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…yerListener.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…mand.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…mand.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…mand.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…mand.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Request: Command warmups

2 participants