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..2c97ad84b8b7 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); }); } @@ -1953,6 +1962,15 @@ } } break; +@@ -1904,7 +_,7 @@ + } + + private void sendGameRuleValues() { +- 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 request game rule values without required permissions", this.player.getGameProfile().name()); + } else { + GameRules gameRules = this.player.level().getGameRules(); @@ -1920,16 +_,27 @@ @Override 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 0d6da5c05bc7..b96c0781ce0e 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; @@ -88,6 +87,7 @@ import org.bukkit.Difficulty; import org.bukkit.Effect; import org.bukkit.FluidCollisionMode; +import org.bukkit.GameRules; import org.bukkit.Location; import org.bukkit.NamespacedKey; import org.bukkit.Particle; @@ -1245,7 +1245,7 @@ public boolean getPVP() { @Override public void setPVP(boolean pvp) { - this.world.getGameRules().set(GameRules.PVP, pvp, this.world); + this.setGameRule(GameRules.PVP, pvp); } @Override