Skip to content

GH-221 Add EventPriority to config for player quit event, add whitelist reasons for kick ex. "Server restart" and untagall command#221

Merged
vLuckyyy merged 18 commits intoEternalCodeTeam:masterfrom
MassiveLag:master
May 19, 2025
Merged

GH-221 Add EventPriority to config for player quit event, add whitelist reasons for kick ex. "Server restart" and untagall command#221
vLuckyyy merged 18 commits intoEternalCodeTeam:masterfrom
MassiveLag:master

Conversation

@MassiveLag
Copy link
Copy Markdown
Contributor

Please describe the changes made by this PR and why they need to be merged:

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 29, 2025

Walkthrough

This update adds new options to control how the plugin handles players who quit or get kicked during combat. It introduces a setting to pick the event priority for quit punishments and a list of kick reasons that prevent punishment if matched. The code now listens for player kicks and tracks those who shouldn’t be punished when they quit. Quit event handling is split into multiple priority-based handlers, all calling a shared method that respects these new settings. Also, a new admin message was added for when many players are removed from combat at once, and a new command lets admins untag all players from combat with a message sent to the command sender. Additionally, permission checks were added to skip combat tagging for certain players, and player death handling was expanded to support all event priorities with new options for dropping player heads on death. The event system was refactored to use a new centralized event manager, replacing the old event caller, and dynamic listeners were introduced for more flexible event handling. Finally, a new restriction prevents Elytra gliding during combat when enabled.

Tip

⚡️ Faster reviews with caching
  • CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.

Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2382aa7 and 8cdea75.

📒 Files selected for processing (8)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/CombatPlugin.java (6 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/border/BorderServiceImpl.java (4 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/event/DynamicListener.java (1 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/event/EventCaller.java (0 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/event/EventManager.java (1 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/FightManagerImpl.java (4 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/drop/DropController.java (3 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/logout/LogoutController.java (2 hunks)
💤 Files with no reviewable changes (1)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/event/EventCaller.java
✅ Files skipped from review due to trivial changes (3)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/event/DynamicListener.java
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/FightManagerImpl.java
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/border/BorderServiceImpl.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/logout/LogoutController.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/CombatPlugin.java (1)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/event/EventManager.java (1)
  • EventManager (8-37)
🔇 Additional comments (17)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/CombatPlugin.java (8)

31-31: New import for EventManager replaces old event handling system.

The codebase is shifting from a direct Bukkit event system to a custom EventManager wrapper.


64-65: Added specific event imports for new priority-based handling.

These imports support the new event priority setup for player quit and death events.


110-110: New EventManager implementation.

Creating a central event manager improves event handling organization.


117-117: Updated FightManager to use EventManager.

The FightManager now uses the centralized event system.


136-136: Updated BorderService to use EventManager.

BorderService now uses the centralized event system.


171-184: Centralized listener registration.

All standard event listeners are now registered through the EventManager in one place.


186-190: Configurable priority for player death events.

Drop controller now uses a configurable event priority from settings, giving admins more control over event execution order.


192-196: Configurable priority for player quit events.

Logout controller now uses a configurable event priority from settings, which helps with the whitelist kick reasons mentioned in the PR title.

eternalcombat-plugin/src/main/java/com/eternalcode/combat/event/EventManager.java (1)

8-37: Good implementation of the EventManager class.

This class centralizes event handling and provides:

  1. Simple event publishing
  2. Standard listener registration
  3. Type-safe dynamic listener registration with custom priorities

The design is clean and follows good patterns for wrapping the Bukkit event system.

eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/drop/DropController.java (8)

3-3: Added DynamicListener import for new event system.

This import supports the new event handling approach.


5-5: Added imports for head drop feature.

These imports support the new player head drop functionality.

Also applies to: 12-12, 16-16


18-18: Updated class to implement DynamicListener.

Changed from standard Bukkit Listener to the new dynamic listener interface.


32-38: Updated event handling method signature.

Changed from Bukkit's annotation-based handler to the DynamicListener interface method, with improved variable caching.


39-42: Added player head drop feature.

New code checks if a head should drop and adds it to death drops when appropriate.


72-82: Well-structured head drop chance calculation.

This method cleanly handles:

  • Combat-only restriction check
  • Feature toggle check
  • Random chance calculation

84-107: Comprehensive head drop creation method.

The method creates a player head item with:

  • Owner set to the dead player
  • Customizable display name
  • Optional lore with placeholders

All aspects are configurable through settings.


110-110: Changed respawn handler visibility to public.

Made the method public to match expected visibility for event handlers.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@igoyek igoyek added 🆕 feature New feature or request 💾 code-only This is just a code-only problem; it doesn't affect the plugin behavior labels Apr 29, 2025
Copy link
Copy Markdown
Contributor

@igoyek igoyek left a comment

Choose a reason for hiding this comment

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

Minor comments, just our code-style.
Nice pull request, thank you :)

Copy link
Copy Markdown
Member

@CitralFlo CitralFlo left a comment

Choose a reason for hiding this comment

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

Again minor changes

MassiveLag and others added 8 commits April 29, 2025 21:19
…t/logout/LogoutController.java

Co-authored-by: Michał Wojtas <80779749+CitralFlo@users.noreply.github.com>
…t/logout/LogoutController.java

Co-authored-by: Michał Wojtas <80779749+CitralFlo@users.noreply.github.com>
…t/logout/LogoutController.java

Co-authored-by: Michał Wojtas <80779749+CitralFlo@users.noreply.github.com>
…t/logout/LogoutController.java

Co-authored-by: Michał Wojtas <80779749+CitralFlo@users.noreply.github.com>
…t/logout/LogoutController.java

Co-authored-by: Michał Wojtas <80779749+CitralFlo@users.noreply.github.com>
…t/logout/LogoutController.java

Co-authored-by: Michał Wojtas <80779749+CitralFlo@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/logout/LogoutController.java (1)

35-57: Good implementation of kick reason checks

This new handler properly checks if kicked players should be exempt from combat punishment based on the whitelist.

Two small suggestions:

  1. Consider making this method package-private instead of private so the event system can access it
  2. The string matching might be too broad since it uses contains - this could match partial words
-    private void onKick(PlayerKickEvent event) {
+    void onKick(PlayerKickEvent event) {

Consider using more precise matching for kick reasons:

-            if (reason.toLowerCase().contains(whitelisted.toLowerCase())) {
+            if (reason.toLowerCase().equals(whitelisted.toLowerCase()) 
+                || reason.toLowerCase().matches(".*\\b" + whitelisted.toLowerCase() + "\\b.*")) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bffd3d6 and 01cad15.

📒 Files selected for processing (2)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/CombatSettings.java (2 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/logout/LogoutController.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/CombatSettings.java
🔇 Additional comments (3)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/logout/LogoutController.java (3)

26-26: Nice addition of a thread-safe set for tracking exempt players

The use of a ConcurrentHashMap-backed set is a good choice for tracking players who shouldn't be punished when quitting.


59-99: Handlers for different event priorities look good

The implementation correctly checks the configured priority before handling the event.


101-110: Smart way to skip punishment for whitelisted kick reasons

The check for exempt players works well by removing them from the set after checking.

- Added untagall command to untag all tagged players at once. useful in cases when you want to do something related to events.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/MessagesSettings.java (1)

131-136: Update the comment to match the feature.

The current comment says it's for when an admin removes "a player" but this message is used when removing multiple players at once.

@Comment({
-    "# Message displayed to an admin when they remove a player from combat.",
-    "# The {PLAYER} placeholder is replaced with the player's name."
+    "# Message displayed to an admin when they remove all players from combat.",
+    "# The {COUNT} placeholder is replaced with the number of players removed."
})
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01cad15 and 4b97b93.

📒 Files selected for processing (3)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/CombatSettings.java (2 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/MessagesSettings.java (1 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/FightTagCommand.java (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/config/implementation/CombatSettings.java
🔇 Additional comments (1)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/FightTagCommand.java (1)

127-127: Good change to support more command senders.

Changing from Player to CommandSender allows both players and console to use this command.

Copy link
Copy Markdown
Member

@CitralFlo CitralFlo left a comment

Choose a reason for hiding this comment

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

Everything looks good to me
Nice work!

@CitralFlo CitralFlo changed the title - Added Event priority to config. Add EventPriority to config for player quit event, add whitelist reasons for kick ex. "Server restart" and untagall command Apr 29, 2025
@CitralFlo CitralFlo changed the title Add EventPriority to config for player quit event, add whitelist reasons for kick ex. "Server restart" and untagall command GH-221 Add EventPriority to config for player quit event, add whitelist reasons for kick ex. "Server restart" and untagall command Apr 29, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/drop/DropController.java (2)

75-139: Consider breaking down the handleDeath method.

The method is quite long with multiple responsibilities. Consider splitting it into smaller methods like processHeadDrop() and processItemDrops() for better readability.

 private void handleDeath(PlayerDeathEvent event) {
     Player player = event.getEntity();
     UUID uuid = player.getUniqueId();
     DropType dropType = this.dropSettings.dropType;
     boolean inCombat = this.fightManager.isInCombat(uuid);

+    processHeadDrop(event, player, inCombat);
+    processItemDrops(event, player, dropType, inCombat);
+ }
+
+ private void processHeadDrop(PlayerDeathEvent event, Player player, boolean inCombat) {
     if (this.dropSettings.headDropEnabled && this.dropSettings.headDropChance > 0.0) {
         boolean shouldDrop = (!this.dropSettings.headDropOnlyInCombat || inCombat)
             && ThreadLocalRandom.current().nextDouble(0, 100) <= this.dropSettings.headDropChance;

         if (shouldDrop) {
             ItemStack head = new ItemStack(Material.PLAYER_HEAD);
             SkullMeta meta = (SkullMeta) head.getItemMeta();

             if (meta != null) {
                 meta.setOwningPlayer(player);
                 String killerName = player.getKiller() != null ? player.getKiller().getName() : "Unknown";

                 String displayName = this.dropSettings.headDropDisplayName
                     .replace("{PLAYER}", player.getName())
                     .replace("{KILLER}", killerName);
                 meta.setDisplayName(displayName);

                 if (!this.dropSettings.headDropLore.isEmpty()) {
                     List<String> lore = this.dropSettings.headDropLore.stream()
                         .map(line -> line.replace("{PLAYER}", player.getName()).replace("{KILLER}", killerName))
                         .toList();
                     meta.setLore(lore);
                 }

                 head.setItemMeta(meta);
             }

             event.getDrops().add(head);
         }
     }
+ }
+
+ private void processItemDrops(PlayerDeathEvent event, Player player, DropType dropType, boolean inCombat) {
     if (dropType == DropType.UNCHANGED || !inCombat) {
         return;
     }

     List<ItemStack> drops = event.getDrops();

     Drop drop = Drop.builder()
         .player(player)
         .killer(player.getKiller())
         .droppedItems(drops)
         .droppedExp(player.getTotalExperience())
         .build();

     DropResult result = this.dropService.modify(dropType, drop);

     if (result == null) {
         return;
     }

     drops.clear();
     drops.addAll(result.droppedItems());

     this.keepInventoryManager.addItems(player.getUniqueId(), result.removedItems());

     if (this.dropSettings.affectExperience) {
         event.setDroppedExp(drop.getDroppedExp());
     }
 }

93-103: Extract placeholder replacement to a helper method.

The placeholder replacement logic is duplicated for display name and lore. Consider creating a helper method to reduce duplication.

+ private String replacePlaceholders(String text, Player player) {
+     String killerName = player.getKiller() != null ? player.getKiller().getName() : "Unknown";
+     return text
+         .replace("{PLAYER}", player.getName())
+         .replace("{KILLER}", killerName);
+ }

 String displayName = this.dropSettings.headDropDisplayName
-    .replace("{PLAYER}", player.getName())
-    .replace("{KILLER}", killerName);
+    replacePlaceholders(this.dropSettings.headDropDisplayName, player);
 meta.setDisplayName(displayName);

 if (!this.dropSettings.headDropLore.isEmpty()) {
     List<String> lore = this.dropSettings.headDropLore.stream()
-        .map(line -> line.replace("{PLAYER}", player.getName()).replace("{KILLER}", killerName))
+        .map(line -> replacePlaceholders(line, player))
         .toList();
     meta.setLore(lore);
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 21f0f9f and 40a6a2c.

📒 Files selected for processing (3)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/controller/FightTagController.java (4 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/drop/DropController.java (4 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/drop/DropSettings.java (2 hunks)
🔇 Additional comments (11)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/controller/FightTagController.java (4)

59-64: Good addition of permission checks

Simple permission checks to let certain players bypass combat tagging. Makes the plugin more flexible for server admins.


86-96: Nice implementation of conditional tagging

The code now checks permissions before tagging players, and extracts UUIDs into variables for better readability. This makes the system more flexible while keeping the code clean.


118-121: Added general bypass permission

Good addition of a general bypass check that complements the more specific permissions added earlier.


123-123: Consistent timer retrieval

This matches the same pattern used in the other event handler, maintaining consistency.

eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/drop/DropSettings.java (5)

12-18: Good use of comments for explaining EventPriority settings.

Clear and detailed comments help users understand what each priority level means and when they'd want to use them.


36-40: Nice addition of head drop feature toggle.

The comment clearly explains what this setting does, making it easy for server admins to understand.


42-47: Well-documented chance setting.

Good explanation of how the drop chance works, with clear examples and boundary values.


54-60: Good use of placeholder documentation.

The comment clearly shows what placeholders are available and provides a helpful example.


61-69: Well-structured default lore configuration.

Good default values that make sense for the feature, with clear comments about placeholder usage.

eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/drop/DropController.java (2)

33-73: Good implementation of priority-based event handling.

The code correctly handles all event priorities by creating separate handlers that check against the configured priority. This gives users fine control over when drop processing happens.


81-110: Well-implemented player head drop feature.

The code correctly implements the configurable head drop feature with:

  • Proper chance calculation
  • Combat status check
  • Player and killer name placeholders
  • Custom display name and lore

MassiveLag added 2 commits May 8, 2025 10:33
…re is a bug where you can still can fly if you are already flying when getting tagged.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/controller/FightActionBlockerController.java (1)

131-132: Remove extra empty lines

These empty lines aren't needed and can be removed to keep the code cleaner.

    }
}

-

-

@EventHandler
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 40a6a2c and 2382aa7.

📒 Files selected for processing (2)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/controller/FightActionBlockerController.java (2 hunks)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/controller/FightTagController.java (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/controller/FightTagController.java
🔇 Additional comments (2)
eternalcombat-plugin/src/main/java/com/eternalcode/combat/fight/controller/FightActionBlockerController.java (2)

21-21: Good addition of the necessary import

The import for PlayerMoveEvent is correctly added to support the new functionality.


113-129: Good implementation of Elytra restriction during movement

This handler nicely complements the existing onToggleGlide method by actively checking and disabling gliding during player movement. The code follows the same pattern as other event handlers in this class with proper early returns and clear logic.

@CitralFlo CitralFlo requested review from CitralFlo and igoyek May 11, 2025 13:45
Copy link
Copy Markdown
Member

@Rollczi Rollczi left a comment

Choose a reason for hiding this comment

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

Hi thanks for your PR! Checkout my "request changes" and commit with event related changes.

@vLuckyyy vLuckyyy removed the 💾 code-only This is just a code-only problem; it doesn't affect the plugin behavior label May 19, 2025
@vLuckyyy vLuckyyy linked an issue May 19, 2025 that may be closed by this pull request
@vLuckyyy vLuckyyy merged commit 7ce6d8b into EternalCodeTeam:master May 19, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🆕 feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drop player head after death

5 participants