diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 930c173ea..72af8cf37 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -1286,8 +1286,18 @@ public class Player extends LivingEntity implements CommandSender, Localizable, * Changes the player {@link GameMode} * * @param gameMode the new player GameMode + * @return true if the gamemode was changed successfully, false otherwise (cancelled by event) */ - public void setGameMode(@NotNull GameMode gameMode) { + public boolean setGameMode(@NotNull GameMode gameMode) { + PlayerGameModeChangeEvent playerGameModeChangeEvent = new PlayerGameModeChangeEvent(this, gameMode); + EventDispatcher.call(playerGameModeChangeEvent); + if (playerGameModeChangeEvent.isCancelled()) { + // Abort + return false; + } + + gameMode = playerGameModeChangeEvent.getNewGameMode(); + this.gameMode = gameMode; // Condition to prevent sending the packets before spawning the player if (isActive()) { @@ -1320,6 +1330,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable, if (isActive()) { refreshAbilities(); } + + return true; } /** diff --git a/src/main/java/net/minestom/server/event/player/PlayerGameModeChangeEvent.java b/src/main/java/net/minestom/server/event/player/PlayerGameModeChangeEvent.java new file mode 100644 index 000000000..467766ce6 --- /dev/null +++ b/src/main/java/net/minestom/server/event/player/PlayerGameModeChangeEvent.java @@ -0,0 +1,56 @@ +package net.minestom.server.event.player; + +import net.minestom.server.entity.GameMode; +import net.minestom.server.entity.Player; +import net.minestom.server.event.trait.CancellableEvent; +import net.minestom.server.event.trait.PlayerInstanceEvent; +import org.jetbrains.annotations.NotNull; + +/** + * Called when the gamemode of a player is being modified. + */ +public class PlayerGameModeChangeEvent implements PlayerInstanceEvent, CancellableEvent { + + private final Player player; + private GameMode newGameMode; + + private boolean cancelled; + + public PlayerGameModeChangeEvent(@NotNull Player player, @NotNull GameMode newGameMode) { + this.player = player; + this.newGameMode = newGameMode; + } + + /** + * Gets the target gamemode. + * + * @return the target gamemode + */ + public @NotNull GameMode getNewGameMode() { + return newGameMode; + } + + /** + * Changes the target gamemode. + * + * @param newGameMode the new target gamemode + */ + public void setNewGameMode(@NotNull GameMode newGameMode) { + this.newGameMode = newGameMode; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Override + public @NotNull Player getPlayer() { + return player; + } +}