diff --git a/bukkit/src/main/java/dev/kitteh/factions/command/defaults/admin/set/CmdSetTag.java b/bukkit/src/main/java/dev/kitteh/factions/command/defaults/admin/set/CmdSetTag.java index 126367ad9..b22d99999 100644 --- a/bukkit/src/main/java/dev/kitteh/factions/command/defaults/admin/set/CmdSetTag.java +++ b/bukkit/src/main/java/dev/kitteh/factions/command/defaults/admin/set/CmdSetTag.java @@ -61,7 +61,7 @@ private void handle(CommandContext context) { } // trigger the faction rename event (cancellable) - FactionRenameEvent renameEvent = new FactionRenameEvent(sender, tag); + FactionRenameEvent renameEvent = new FactionRenameEvent(faction, sender, tag); Bukkit.getServer().getPluginManager().callEvent(renameEvent); if (renameEvent.isCancelled()) { return; diff --git a/bukkit/src/main/java/dev/kitteh/factions/command/defaults/set/CmdSetTag.java b/bukkit/src/main/java/dev/kitteh/factions/command/defaults/set/CmdSetTag.java index fc3d55409..52a05c022 100644 --- a/bukkit/src/main/java/dev/kitteh/factions/command/defaults/set/CmdSetTag.java +++ b/bukkit/src/main/java/dev/kitteh/factions/command/defaults/set/CmdSetTag.java @@ -68,7 +68,7 @@ private void handle(CommandContext context) { return; } - FactionRenameEvent renameEvent = new FactionRenameEvent(sender, tag); + FactionRenameEvent renameEvent = new FactionRenameEvent(faction, sender, tag); Bukkit.getServer().getPluginManager().callEvent(renameEvent); if (renameEvent.isCancelled()) { return; diff --git a/bukkit/src/main/java/dev/kitteh/factions/event/FactionRenameEvent.java b/bukkit/src/main/java/dev/kitteh/factions/event/FactionRenameEvent.java index 7be588ac9..febb4c7eb 100644 --- a/bukkit/src/main/java/dev/kitteh/factions/event/FactionRenameEvent.java +++ b/bukkit/src/main/java/dev/kitteh/factions/event/FactionRenameEvent.java @@ -1,6 +1,7 @@ package dev.kitteh.factions.event; import dev.kitteh.factions.FPlayer; +import dev.kitteh.factions.Faction; import org.bukkit.event.Cancellable; import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; @@ -12,7 +13,13 @@ public class FactionRenameEvent extends FactionPlayerEvent implements Cancellabl private final String tag; public FactionRenameEvent(FPlayer sender, String newTag) { - super(sender.faction(), sender); + this(sender.faction(), sender, newTag); + } + + // Administrative renames must identify the target, not the sender's faction. + // Upstream: https://github.com/FactionsU/UID/issues/57 + public FactionRenameEvent(Faction faction, FPlayer sender, String newTag) { + super(faction, sender); tag = newTag; } diff --git a/bukkit/src/test/java/dev/kitteh/factions/event/FactionRenameEventTest.java b/bukkit/src/test/java/dev/kitteh/factions/event/FactionRenameEventTest.java new file mode 100644 index 000000000..f9ab14b30 --- /dev/null +++ b/bukkit/src/test/java/dev/kitteh/factions/event/FactionRenameEventTest.java @@ -0,0 +1,54 @@ +package dev.kitteh.factions.event; + +import dev.kitteh.factions.FPlayer; +import dev.kitteh.factions.Faction; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Proxy; + +import static org.junit.jupiter.api.Assertions.*; + +class FactionRenameEventTest { + @Test + void administrativeRenameKeepsTargetSeparateFromSenderFaction() { + Faction own = faction(); + Faction target = faction(); + FPlayer sender = player(own); + FactionRenameEvent event = new FactionRenameEvent(target, sender, "North"); + + assertSame(target, event.getFaction()); + assertNotSame(own, event.getFaction()); + assertSame(sender, event.getFPlayer()); + assertEquals("North", event.getFactionTag()); + assertFalse(event.isCancelled()); + event.setCancelled(true); + assertTrue(event.isCancelled()); + } + + @Test + void existingConstructorPreservesOwnFactionBehavior() { + Faction own = faction(); + FPlayer sender = player(own); + FactionRenameEvent event = new FactionRenameEvent(sender, "North"); + assertSame(own, event.getFaction()); + assertSame(sender, event.getFPlayer()); + assertEquals("North", event.getFactionTag()); + } + + private static Faction faction() { + return (Faction) Proxy.newProxyInstance(Faction.class.getClassLoader(), + new Class[]{Faction.class}, (proxy, method, args) -> { + throw new AssertionError("Unexpected faction access: " + method.getName()); + }); + } + + private static FPlayer player(Faction own) { + return (FPlayer) Proxy.newProxyInstance(FPlayer.class.getClassLoader(), + new Class[]{FPlayer.class}, (proxy, method, args) -> { + if (method.getName().equals("faction") && method.getParameterCount() == 0) { + return own; + } + throw new AssertionError("Unexpected player access: " + method.getName()); + }); + } +}