From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: violetc <58360096+s-yh-china@users.noreply.github.com> Date: Sun, 11 Dec 2022 18:43:35 +0800 Subject: [PATCH] Player operation limiter diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java index 3ed09fe9693b64105466e6102062bce500da0486..fdc64e99738f1940115be06758a2bcb240da5e09 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java @@ -271,6 +271,10 @@ public class ServerPlayer extends Player { public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet cachedSingleHashSet; // Paper public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper public org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - there are a lot of changes to do if we change all methods leading to the event + // Leaves start - player operation limiter + private int instaBreakCountPerTick = 0; + private int placeBlockCountPerTick = 0; + // Leaves end - player operation limiter public ServerPlayer(MinecraftServer server, ServerLevel world, GameProfile profile) { super(world, world.getSharedSpawnPos(), world.getSharedSpawnAngle(), profile); @@ -663,6 +667,7 @@ public class ServerPlayer extends Player { this.joining = false; } // CraftBukkit end + this.resetOperationCountPerTick(); // Leaves - player operation limiter this.gameMode.tick(); this.wardenSpawnTracker.tick(); --this.spawnInvulnerableTime; @@ -2557,5 +2562,32 @@ public class ServerPlayer extends Player { public CraftPlayer getBukkitEntity() { return (CraftPlayer) super.getBukkitEntity(); } + + // Leaves start - player operation limiter + private void resetOperationCountPerTick() { + instaBreakCountPerTick = 0; + placeBlockCountPerTick = 0; + } + + public int getInstaBreakCountPerTick() { + return instaBreakCountPerTick; + } + + public int getPlaceBlockCountPerTick() { + return placeBlockCountPerTick; + } + + public void addInstaBreakCountPerTick() { + ++instaBreakCountPerTick; + } + + public void addPlaceBlockCountPerTick() { + ++placeBlockCountPerTick; + } + + public boolean allowOperation() { + return (instaBreakCountPerTick == 0 || placeBlockCountPerTick == 0) && (instaBreakCountPerTick <= 1 && placeBlockCountPerTick <= 2); + } + // Leaves end - player operation limiter // CraftBukkit end } diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java index 58b093bb1de78ee3b3b2ea364aa50474883f443a..a59cf7c1a34ee54b3a64047498ce4e090648df86 100644 --- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java @@ -44,6 +44,7 @@ import org.bukkit.event.Event; import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerGameModeChangeEvent; import org.bukkit.event.player.PlayerInteractEvent; +import top.leavesmc.leaves.event.player.PlayerOperationLimitEvent; // CraftBukkit end public class ServerPlayerGameMode { @@ -325,6 +326,19 @@ public class ServerPlayerGameMode { } public void destroyAndAck(BlockPos pos, int sequence, String reason) { + // Leaves start - player operation limiter + if (top.leavesmc.leaves.LeavesConfig.playerOperationLimiter) { + if (reason.equals("insta mine")) { + player.addInstaBreakCountPerTick(); + if (!player.allowOperation()) { + MinecraftServer.getServer().server.getPluginManager().callEvent(new PlayerOperationLimitEvent(player.getBukkitEntity(), PlayerOperationLimitEvent.Operation.MINE, CraftBlock.at(level, pos))); + this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos))); + this.debugLogging(pos, false, sequence, reason); + return; + } + } + } + // Leaves end - player operation limiter if (this.destroyBlock(pos)) { this.debugLogging(pos, true, sequence, reason); } else { diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java index 3ab714721b51b039291b8e8a4b4da5118e18f5b7..1aedc8e019fb9d5307a5a2c6c2cc8e8646d51428 100644 --- a/src/main/java/net/minecraft/world/item/BlockItem.java +++ b/src/main/java/net/minecraft/world/item/BlockItem.java @@ -32,9 +32,12 @@ import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.Property; import net.minecraft.world.level.gameevent.GameEvent; import net.minecraft.world.phys.shapes.CollisionContext; +import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.event.block.BlockCanBuildEvent; +import top.leavesmc.leaves.event.player.PlayerOperationLimitEvent; // CraftBukkit end public class BlockItem extends Item { @@ -83,6 +86,18 @@ public class BlockItem extends Item { final org.bukkit.block.BlockState oldBlockstate = blockstate != null ? blockstate : org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); // Paper // CraftBukkit end + // Leaves start - player operation limiter + if (top.leavesmc.leaves.LeavesConfig.playerOperationLimiter && !context.getLevel().isClientSide()) { + ServerPlayer player = (ServerPlayer) context.getPlayer(); + if (player != null && iblockdata != null) { + player.addPlaceBlockCountPerTick(); + if (!player.allowOperation()) { + MinecraftServer.getServer().server.getPluginManager().callEvent(new PlayerOperationLimitEvent(player.getBukkitEntity(), PlayerOperationLimitEvent.Operation.PLACE, blockstate.getBlock())); + return InteractionResult.FAIL; + } + } + } + // Leaves end - player operation limiter if (iblockdata == null) { return InteractionResult.FAIL; } else if (!this.placeBlock(blockactioncontext1, iblockdata)) { diff --git a/src/main/java/top/leavesmc/leaves/LeavesConfig.java b/src/main/java/top/leavesmc/leaves/LeavesConfig.java index 43b0083d51e8d78092595a93755ed2e1b84c4694..d63907fbf908cf6c83c727889abe37058a673f6a 100644 --- a/src/main/java/top/leavesmc/leaves/LeavesConfig.java +++ b/src/main/java/top/leavesmc/leaves/LeavesConfig.java @@ -432,6 +432,11 @@ public final class LeavesConfig { } } + public static boolean playerOperationLimiter = false; + private static void playerOperationLimiter() { + playerOperationLimiter = getBoolean("settings.modify.player-operation-limiter", playerOperationLimiter); + } + public static final class WorldConfig { public final String worldName;