diff --git a/paper-api/src/main/java/io/papermc/paper/event/world/WorldGameRuleChangeEvent.java b/paper-api/src/main/java/io/papermc/paper/event/world/WorldGameRuleChangeEvent.java index c44006faf327..73569979b732 100644 --- a/paper-api/src/main/java/io/papermc/paper/event/world/WorldGameRuleChangeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/event/world/WorldGameRuleChangeEvent.java @@ -11,7 +11,8 @@ import org.jspecify.annotations.Nullable; /** - * Called when a world's gamerule is changed, either by command or by api. + * Called when a world's gamerule is changed, either by command, world options menu, or by api. + * @see Modifying game rules - Minecraft wiki */ @NullMarked public class WorldGameRuleChangeEvent extends WorldEvent implements Cancellable { diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 8b15ba7efdaf..0e5d4d933257 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -584,12 +584,21 @@ } } +@@ -790,7 +_,7 @@ + @Override + public void handleSetGameRule(final ServerboundSetGameRulePacket packet) { + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); +- if (!this.player.permissions().hasPermission(Permissions.COMMANDS_GAMEMASTER)) { ++ if (!this.player.permissions().hasPermission(Permissions.COMMANDS_GAMEMASTER) && !this.player.getBukkitEntity().hasPermission("minecraft.command.gamerule")) { // Paper - add permission check + LOGGER.warn("Player {} tried to set game rule values without required permissions", this.player.getGameProfile().name()); + } else { + GameRules gameRules = this.player.level().getGameRules(); @@ -808,7 +_,7 @@ private void setGameRuleValue(final GameRules gameRules, final GameRule rule, final String value) { rule.deserialize(value).result().ifPresent(parsedValue -> { - gameRules.set(rule, (T)parsedValue, this.server); -+ gameRules.set(rule, (T)parsedValue, this.player.level()); // Paper - per-world game rules ++ parsedValue = org.bukkit.craftbukkit.event.CraftEventFactory.handleGameRuleSet(rule, parsedValue, this.player.level(), this.player.getBukkitEntity()).value(); // Paper - per-world game rules and event this.broadcastGameRuleChangeToOperators(rule, (T)parsedValue); }); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java index 2081802580f1..f9627f06336b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -95,7 +95,6 @@ import net.minecraft.world.item.crafting.RecipeType; import net.minecraft.world.item.crafting.RepairItemRecipe; import net.minecraft.world.level.CustomSpawner; -import net.minecraft.world.level.gamerules.GameRules; import net.minecraft.world.level.GameType; import net.minecraft.world.level.LevelSettings; import net.minecraft.world.level.biome.BiomeManager; diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 8bb0c229b41b..6e1bac760ee0 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -73,7 +73,6 @@ import net.minecraft.world.level.chunk.LevelChunk; import net.minecraft.world.level.chunk.status.ChunkStatus; import net.minecraft.world.level.gamerules.GameRule; -import net.minecraft.world.level.gamerules.GameRules; import net.minecraft.world.level.levelgen.structure.StructureStart; import net.minecraft.world.level.storage.LevelData; import net.minecraft.world.level.storage.LevelResource; @@ -1245,7 +1244,7 @@ public boolean getPVP() { @Override public void setPVP(boolean pvp) { - this.world.getGameRules().set(GameRules.PVP, pvp, this.world); + this.setGameRule(org.bukkit.GameRules.PVP, pvp); } @Override