Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import com.eternalcode.combat.fight.drop.impl.PercentDropModifier;
import com.eternalcode.combat.fight.drop.impl.PlayersHealthDropModifier;
import com.eternalcode.combat.fight.blocker.PlaceBlockBlocker;
import com.eternalcode.combat.fight.blocker.SignEditingBlocker;
import com.eternalcode.combat.fight.effect.FightEffectController;
import com.eternalcode.combat.fight.effect.FightEffectService;
import com.eternalcode.combat.fight.effect.FightEffectServiceImpl;
Expand Down Expand Up @@ -128,7 +129,7 @@
this.dropService = new DropServiceImpl();
this.dropKeepInventoryService = new DropKeepInventoryServiceImpl();

UpdaterService updaterService = new UpdaterService(this.getDescription());

Check warning on line 132 in eternalcombat-plugin/src/main/java/com/eternalcode/combat/CombatPlugin.java

View workflow job for this annotation

GitHub Actions / build

[deprecation] getDescription() in JavaPlugin has been deprecated

MiniMessage miniMessage = MiniMessage.builder()
.postProcessor(new AdventureLegacyColorPostProcessor())
Expand Down Expand Up @@ -205,6 +206,7 @@
new RespawnAnchorListener(this, this.fightManager, pluginConfig),
new FireworkController(this.fightManager, pluginConfig, noticeService),
new InventoryContainersBlocker(this.fightManager, pluginConfig, noticeService),
new SignEditingBlocker(this.fightManager, pluginConfig),
new CommandsBlocker(this.fightManager, noticeService, pluginConfig),
new ElytraBlocker(this.fightManager, pluginConfig),
new ElytraEquipBlocker(this.fightManager, noticeService, pluginConfig, server),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ public class PluginConfig extends OkaeriConfig {
})
public InventorySettings inventory = new InventorySettings();

@Comment({
" ",
"# Settings related to sign editing during combat.",
"# Created for sign traps where opening the sign editor can block ender pearl throws."
})
public SignEditingSettings signEditing = new SignEditingSettings();

@Comment({
" ",
"# Settings related to placeholders used in the plugin.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.eternalcode.combat.config.implementation;

import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment;

public class SignEditingSettings extends OkaeriConfig {

@Comment({
"# Prevent players from editing signs during combat.",
"# Disabled by default; created for sign traps where sign editing blocks ender pearl throws."
})
public boolean disableSignEditingDuringCombat = false;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.eternalcode.combat.fight.blocker;

import com.eternalcode.combat.config.implementation.PluginConfig;
import com.eternalcode.combat.fight.FightManager;
import java.util.UUID;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Event.Result;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;

public class SignEditingBlocker implements Listener {

private final FightManager fightManager;
private final PluginConfig config;

public SignEditingBlocker(FightManager fightManager, PluginConfig config) {
this.fightManager = fightManager;
this.config = config;
}

@EventHandler(ignoreCancelled = true)
void onInteract(PlayerInteractEvent event) {
if (!this.config.signEditing.disableSignEditingDuringCombat) {
return;
}

if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}

Block clickedBlock = event.getClickedBlock();
if (clickedBlock == null || !isSign(clickedBlock.getType())) {
return;
}

Player player = event.getPlayer();
UUID uniqueId = player.getUniqueId();

if (!this.fightManager.isInCombat(uniqueId)) {
return;
}

event.setUseInteractedBlock(Result.DENY);

ItemStack item = event.getItem();
if (item != null && isEnderPearl(item.getType()) && event.useItemInHand() != Result.DENY) {
event.setUseItemInHand(Result.ALLOW);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve prior item-use denials when allowing pearls

When this blocker runs for a combat player holding an ender pearl, it unconditionally changes the item result to ALLOW. PlayerInteractEvent can already have an item-use DENY from an earlier listener (for example a protected region or item blacklist), and this line overrides that denial on sign clicks, letting the pearl launch where another plugin intentionally blocked it. Only force ALLOW if the current item result is not DENY, or otherwise preserve existing cancellation state.

Useful? React with 👍 / 👎.

}
}

static boolean isSign(Material material) {
return material.name().endsWith("_SIGN");
}

static boolean isEnderPearl(Material material) {
return material == Material.ENDER_PEARL;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.eternalcode.combat.config.implementation;

import static org.junit.jupiter.api.Assertions.assertFalse;

import org.junit.jupiter.api.Test;

class SignEditingSettingsTest {

@Test
void shouldDisableSignEditingBlockerByDefault() {
SignEditingSettings signEditingSettings = new SignEditingSettings();

assertFalse(signEditingSettings.disableSignEditingDuringCombat);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.eternalcode.combat.fight.blocker;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.bukkit.Material;
import org.junit.jupiter.api.Test;

class SignEditingBlockerTest {

@Test
void shouldRecognizeStandingSignMaterials() {
assertTrue(SignEditingBlocker.isSign(Material.OAK_SIGN));
assertTrue(SignEditingBlocker.isSign(Material.CRIMSON_SIGN));
}

@Test
void shouldRecognizeWallSignMaterials() {
assertTrue(SignEditingBlocker.isSign(Material.OAK_WALL_SIGN));
assertTrue(SignEditingBlocker.isSign(Material.WARPED_WALL_SIGN));
}

@Test
void shouldIgnoreNonSignMaterials() {
assertFalse(SignEditingBlocker.isSign(Material.CHEST));
assertFalse(SignEditingBlocker.isSign(Material.ENDER_PEARL));
}

@Test
void shouldRecognizeEnderPearlMaterial() {
assertTrue(SignEditingBlocker.isEnderPearl(Material.ENDER_PEARL));
assertFalse(SignEditingBlocker.isEnderPearl(Material.OAK_SIGN));
}
}
Loading