Skip to content

Commit

Permalink
Prevent unauthorized sign edits.
Browse files Browse the repository at this point in the history
Since Minecraft 1.20, players can edit signs by right-clicking on them,
and that poses a problem for the sign-centric portions of the plugin,
such as class selection signs and the various types of arena signs.

This commit refactors the PlayerInteractEvent handler in ArenaListener
in order to break open the possibility of handling non-lobby players as
well. We're a little more strict with lobby players, and we still want
to handle class sign clicks and iron block clicks here. For players who
aren't in the lobby, we're really just blocking the event according to
the regular protection rules (block is inside region, protect is on, and
arena is not in edit mode).

It also blanket cancels events in the HandlesSignClicks event handler,
because there is no meaningful way to edit an arena sign, since their
contents come from the template file and not from what is written on
them by the sign renderer.

Ideally, we'd refactor some of this event handler logic, because it's a
lot easier to take care of the individual responsibilities in separate
event handlers.

Fixes #765
  • Loading branch information
garbagemule committed Oct 23, 2023
1 parent 6579c4b commit e81f3dc
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 11 deletions.
55 changes: 44 additions & 11 deletions src/main/java/com/garbagemule/MobArena/ArenaListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.bukkit.entity.ThrownPotion;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.Event.Result;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockEvent;
Expand Down Expand Up @@ -1089,26 +1090,58 @@ public void onPlayerBucketEmpty(PlayerBucketEmptyEvent event) {
}

public void onPlayerInteract(PlayerInteractEvent event) {
Player p = event.getPlayer();
if (!arena.inLobby(p)) return;
if (arena.inLobby(event.getPlayer())) {
onLobbyPlayerInteract(event);
} else {
onNonLobbyPlayerInteract(event);
}
}

// Prevent placing blocks and using held items
private void onLobbyPlayerInteract(PlayerInteractEvent event) {
if (event.hasItem()) {
event.setUseItemInHand(Result.DENY);
}

// Bail if off-hand or if there's no block involved.
if (event.getHand() == EquipmentSlot.OFF_HAND || !event.hasBlock())
if (event.getHand() == EquipmentSlot.OFF_HAND) {
return;
}

// Iron block
if (event.getClickedBlock().getType() == Material.IRON_BLOCK) {
handleReadyBlock(p);
Block block = event.getClickedBlock();
if (block == null) {
return;
}
// Sign
else if (event.getClickedBlock().getState() instanceof Sign) {

if (block.getType() == Material.IRON_BLOCK) {
handleReadyBlock(event.getPlayer());
} else if (block.getState() instanceof Sign) {
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
event.setCancelled(true);
}
Sign sign = (Sign) event.getClickedBlock().getState();
handleSign(sign, p);
handleSign(sign, event.getPlayer());
}
}

private void onNonLobbyPlayerInteract(PlayerInteractEvent event) {
if (!protect) {
return;
}

Block block = event.getClickedBlock();
if (block == null) {
return;
}
if (!region.contains(block.getLocation())) {
return;
}
if (arena.inEditMode()) {
return;
}

if (block.getState() instanceof Sign) {
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
event.setCancelled(true);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public void on(PlayerInteractEvent event) {

ArenaSign sign = signStore.findByLocation(block.getLocation());
if (sign != null) {
event.setCancelled(true);
purgeAndInvoke(sign, event.getPlayer());
}
}
Expand Down

0 comments on commit e81f3dc

Please sign in to comment.