Skip to content
Open
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,33 @@
this.getCommands().performPrefixedCommand(input.source, input.msg);
}
}
@@ -509,6 +_,7 @@
this.settings.update(p -> p.spawnProtection.update(this.registryAccess(), spawnProtectionRadius));
}

+ // Paper start - add a bypass permission node
@Override
public boolean isUnderSpawnProtection(final ServerLevel level, final BlockPos pos, final Player player) {
LevelData.RespawnData respawnData = level.getRespawnData();
@@ -524,6 +_,10 @@
return false;
}

+ if (player.getBukkitEntity().hasPermission("minecraft.spawn-protection.bypass")) {
+ return false;
+ }
+
if (this.spawnProtectionRadius() <= 0) {
return false;
}
@@ -534,6 +_,7 @@
int dist = Math.max(xd, zd);
return dist <= this.spawnProtectionRadius();
}
+ // Paper - end

@Override
public boolean repliesToStatus() {
@@ -592,12 +_,15 @@

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
if (this.isSleeping()) {
this.stopSleeping();
}
@@ -405,12 +_,26 @@
@@ -405,12 +_,44 @@
this.respawnConfig = input.read("respawn", ServerPlayer.RespawnConfig.CODEC).orElse(null);
this.spawnExtraParticlesOnFall = input.getBooleanOr("spawn_extra_particles_on_fall", false);
this.raidOmenPosition = input.read("raid_omen_position", BlockPos.CODEC).orElse(null);
Expand All @@ -138,16 +138,34 @@

+ // Paper start - Expand PlayerGameModeChangeEvent
+ private void loadGameTypes(ValueInput input) {
+ if (this.server.getForcedGameType() != null && this.server.getForcedGameType() != readPlayerMode(input, "playerGameType")) {
+ if (new org.bukkit.event.player.PlayerGameModeChangeEvent(this.getBukkitEntity(), org.bukkit.GameMode.getByValue(this.server.getDefaultGameType().getId()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null).callEvent()) {
+ GameType playerGameType = readPlayerMode(input, "playerGameType");
+ GameType previousPlayerGameType = readPlayerMode(input, "previousPlayerGameType");
+
+ if (this.server.getForcedGameType() != null && this.server.getForcedGameType() != playerGameType) {
+ if (this.getBukkitEntity().hasPermission("minecraft.force-gamemode.bypass")) { // Paper - add bypass permission
+ this.gameMode.setGameModeForPlayer(
+ playerGameType != null ? playerGameType : this.calculateGameModeForNewPlayer(null),
+ previousPlayerGameType
+ );
+ return;
+ }
+
+ org.bukkit.GameMode forcedBukkitGameMode = org.bukkit.GameMode.getByValue(this.server.getDefaultGameType().getId());
+ if (forcedBukkitGameMode == null) {
+ forcedBukkitGameMode = org.bukkit.GameMode.SURVIVAL;
+ }
+
+ if (new org.bukkit.event.player.PlayerGameModeChangeEvent(this.getBukkitEntity(), forcedBukkitGameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null).callEvent()) {
+ this.gameMode.setGameModeForPlayer(this.server.getForcedGameType(), GameType.DEFAULT_MODE);
+ } else {
+ this.gameMode.setGameModeForPlayer(readPlayerMode(input, "playerGameType"), readPlayerMode(input, "previousPlayerGameType"));
+ this.gameMode.setGameModeForPlayer(
+ playerGameType != null ? playerGameType : this.calculateGameModeForNewPlayer(null),
+ previousPlayerGameType
+ );
+ }
+ return;
+ }
+ this.gameMode
+ .setGameModeForPlayer(this.calculateGameModeForNewPlayer(readPlayerMode(input, "playerGameType")), readPlayerMode(input, "previousPlayerGameType"));
+ this.gameMode.setGameModeForPlayer(this.calculateGameModeForNewPlayer(playerGameType), previousPlayerGameType);
+ }
+ // Paper end - Expand PlayerGameModeChangeEvent
+
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
+ return;
+ }
+ // Paper end - Prevent moving into unloaded chunks
+ if (movedDist - expectedDist > Math.max(100.0, Mth.square(org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed)) && !this.isSingleplayerOwner()) {
+ if (movedDist - expectedDist > Math.max(100.0, Mth.square(org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) i * speed)) && !this.isSingleplayerOwner() && !this.player.getBukkitEntity().hasPermission("minecraft.movement.bypass.vehicle.quickly")) { // Paper - add bypass permission
+ // CraftBukkit end
LOGGER.warn(
"{} (vehicle of {}) moved too quickly! {},{},{}", vehicle.getPlainTextName(), this.player.getPlainTextName(), xDist, yDist, zDist
Expand All @@ -293,7 +293,7 @@
movedDist = xDist * xDist + yDist * yDist + zDist * zDist;
boolean fail = false;
- if (movedDist > 0.0625) {
+ if (movedDist > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot
+ if (movedDist > org.spigotmc.SpigotConfig.movedWronglyThreshold && !this.player.getBukkitEntity().hasPermission("minecraft.movement.bypass.vehicle.wrongly")) { // Spigot
fail = true;
LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", vehicle.getPlainTextName(), this.player.getPlainTextName(), Math.sqrt(movedDist));
}
Expand Down Expand Up @@ -355,6 +355,16 @@
this.player.level().getChunkSource().move(this.player);
Vec3 clientDeltaMovement = new Vec3(vehicle.getX() - oldX, vehicle.getY() - oldY, vehicle.getZ() - oldZ);
this.handlePlayerKnownMovement(clientDeltaMovement);
@@ -513,7 +_,8 @@
&& !this.server.allowFlight()
&& !vehicle.isFlyingVehicle()
&& !vehicle.isNoGravity()
- && this.noBlocksAround(vehicle);
+ && this.noBlocksAround(vehicle)
+ && !this.getCraftPlayer().hasPermission("minecraft.flight.bypass.vehicle"); // Paper - add bypass permission
this.vehicleLastGoodX = vehicle.getX();
this.vehicleLastGoodY = vehicle.getY();
this.vehicleLastGoodZ = vehicle.getZ();
@@ -532,7 +_,7 @@
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
if (packet.getId() == this.awaitingTeleport) {
Expand Down Expand Up @@ -388,7 +398,7 @@
this.player.getRecipeBook().setBookSetting(packet.getBookType(), packet.isOpen(), packet.isFiltering());
}

@@ -591,25 +_,112 @@
@@ -591,25 +_,113 @@
}
}

Expand All @@ -402,7 +412,7 @@
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); // Paper - AsyncTabCompleteEvent; run this async
+ // CraftBukkit start
+ if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.nameAndId()) && !this.server.isSingleplayerOwner(this.player.nameAndId())) { // Paper - configurable tab spam limits
+ if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.player.getBukkitEntity().hasPermission("minecraft.spam.bypass.command-suggestions.frequency") && !this.server.getPlayerList().isOp(this.player.nameAndId()) && !this.server.isSingleplayerOwner(this.player.nameAndId())) { // Paper - configurable tab spam limits and a bypass permission node
+ this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect
+ return;
+ }
Expand All @@ -414,7 +424,7 @@
+ // Paper end - Don't suggest if tab-complete is disabled
+ // Paper start
+ final int index;
+ if (packet.getCommand().length() > 64 && ((index = packet.getCommand().indexOf(' ')) == -1 || index >= 64)) {
+ if (!this.player.getBukkitEntity().hasPermission("minecraft.spam.bypass.command-suggestions.length") && packet.getCommand().length() > 64 && ((index = packet.getCommand().indexOf(' ')) == -1 || index >= 64)) { // Paper - add bypass permission node
+ this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - add proper async disconnect
+ return;
+ }
Expand Down Expand Up @@ -473,7 +483,8 @@
+ // Paper end - AsyncTabCompleteEvent
ParseResults<CommandSourceStack> parse = this.server.getCommands().getDispatcher().parse(command, this.player.createCommandSourceStack());
+ // Paper start - Handle non-recoverable exceptions
+ if (!parse.getExceptions().isEmpty()
+ if (!this.player.getBukkitEntity().hasPermission("minecraft.spam.bypass.server-suggestions") // Paper - add a bypass permission node
+ && !parse.getExceptions().isEmpty()
+ && parse.getExceptions().values().stream().anyMatch(e -> e instanceof io.papermc.paper.brigadier.TagParseCommandSyntaxException)) {
+ this.disconnect(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM);
+ return;
Expand Down Expand Up @@ -785,7 +796,8 @@
+ }
+ // Paper end - Prevent moving into unloaded chunks

if (this.shouldCheckPlayerMovement(isFallFlying)) {
- if (this.shouldCheckPlayerMovement(isFallFlying)) {
+ if (this.shouldCheckPlayerMovement(isFallFlying) && !this.player.getBukkitEntity().hasPermission("minecraft.movement.bypass.player.quickly")) { // Paper - add bypass permission
float metersPerTick = isFallFlying ? 300.0F : 100.0F;
- if (movedDist - expectedDist > metersPerTick * deltaPackets) {
+ if (movedDist - expectedDist > Math.max(metersPerTick, Mth.square(org.spigotmc.SpigotConfig.movedTooQuicklyMultiplier * (float) deltaPackets * speed))) {
Expand Down Expand Up @@ -849,7 +861,7 @@
double oyDist = yDist;
xDist = targetX - this.player.getX();
yDist = targetY - this.player.getY();
@@ -1143,21 +_,88 @@
@@ -1143,27 +_,96 @@

zDist = targetZ - this.player.getZ();
movedDist = xDist * xDist + yDist * yDist + zDist * zDist;
Expand All @@ -861,8 +873,10 @@
&& !this.player.isSleeping()
&& !this.player.isCreative()
&& !this.player.isSpectator()
&& !this.player.isInPostImpulseGraceTime()) {
- && !this.player.isInPostImpulseGraceTime()) {
- fail = true;
+ && !this.player.isInPostImpulseGraceTime()
+ && !this.player.getBukkitEntity().hasPermission("minecraft.movement.bypass.player.wrongly")) { // Paper - add bypass permission
+ // Paper start - Add fail move event
+ io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.MOVED_WRONGLY,
+ targetX, targetY, targetZ, targetYRot, targetXRot, true);
Expand Down Expand Up @@ -947,6 +961,13 @@
this.player.absSnapTo(targetX, targetY, targetZ, targetYRot, targetXRot);
boolean isAutoSpinAttack = this.player.isAutoSpinAttack();
this.clientIsFloating = oyDist >= -0.03125
&& !playerStandsOnSomething
&& !this.player.isSpectator()
&& !this.server.allowFlight()
+ && !this.player.getBukkitEntity().hasPermission("minecraft.flight.bypass.player") // Paper - add bypass permission
&& !this.player.getAbilities().mayfly
&& !this.player.hasEffect(MobEffects.LEVITATION)
&& !isFallFlying
@@ -1192,7 +_,7 @@
this.lastGoodY = this.player.getY();
this.lastGoodZ = this.player.getZ();
Expand All @@ -956,6 +977,17 @@
this.player
.doCheckFallDamage(
this.player.getX() - startX, this.player.getY() - startY, this.player.getZ() - startZ, packet.isOnGround()
@@ -1216,6 +_,10 @@
return false;
}

+ if (isFallFlying && this.player.getBukkitEntity().hasPermission("minecraft.movement.bypass.elytra")) { // Paper - add bypass permission
+ return false;
+ }
+
GameRules gameRules = this.player.level().getGameRules();
return gameRules.get(GameRules.PLAYER_MOVEMENT_CHECK) && (!isFallFlying || gameRules.get(GameRules.ELYTRA_MOVEMENT_CHECK));
}
@@ -1232,6 +_,7 @@
this.player.getXRot()
);
Expand Down Expand Up @@ -1563,7 +1595,7 @@
return Optional.empty();
}

@@ -1669,31 +_,91 @@
@@ -1669,31 +_,92 @@
return false;
}

Expand Down Expand Up @@ -1644,7 +1676,8 @@
+ // CraftBukkit start - replaced with thread safe throttle
+ // throttler.increment();
+ if (!throttler.isIncrementAndUnderThreshold()
+ // CraftBukkit end - replaced with thread safe throttle
+ // CraftBukkit end - replaced with thread safe throttle
+ && !this.player.getBukkitEntity().hasPermission("minecraft.spam.bypass.rate") // Paper - add bypass permission node
&& !this.server.getPlayerList().isOp(this.player.nameAndId())
&& !this.server.isSingleplayerOwner(this.player.nameAndId())) {
- this.disconnect(Component.translatable("disconnect.spam"));
Expand Down Expand Up @@ -2296,7 +2329,7 @@
public void handlePlaceRecipe(final ServerboundPlaceRecipePacket packet) {
+ // Paper start - auto recipe limit
+ if (!org.bukkit.Bukkit.isPrimaryThread()) {
+ if (!this.recipeSpamPackets.isIncrementAndUnderThreshold()) {
+ if (!this.player.getBukkitEntity().hasPermission("minecraft.spam.bypass.place") && !this.recipeSpamPackets.isIncrementAndUnderThreshold()) { // Paper - add bypass permission node
+ this.disconnectAsync(net.minecraft.network.chat.Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause // Paper - add proper async disconnect
+ return;
+ }
Expand Down
Loading