aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0754-Lag-compensate-block-breaking.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/0754-Lag-compensate-block-breaking.patch')
-rw-r--r--patches/server/0754-Lag-compensate-block-breaking.patch155
1 files changed, 155 insertions, 0 deletions
diff --git a/patches/server/0754-Lag-compensate-block-breaking.patch b/patches/server/0754-Lag-compensate-block-breaking.patch
new file mode 100644
index 0000000000..7ab54b9bd7
--- /dev/null
+++ b/patches/server/0754-Lag-compensate-block-breaking.patch
@@ -0,0 +1,155 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Spottedleaf <[email protected]>
+Date: Fri, 14 Feb 2020 22:16:34 -0800
+Subject: [PATCH] Lag compensate block breaking
+
+Use time instead of ticks if ticks fall behind
+
+diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
+index d9a63e0574676357265c5b971b061b9595081d7d..780754f1c6252fa567d27389978f59dbd71abc94 100644
+--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
++++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
+@@ -617,4 +617,10 @@ public class PaperConfig {
+ }
+ }
+ }
++
++ public static boolean lagCompensateBlockBreaking;
++
++ private static void lagCompensateBlockBreaking() {
++ lagCompensateBlockBreaking = getBoolean("settings.lag-compensate-block-breaking", true);
++ }
+ }
+diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+index b6eef41079120fffd63f06f681378b1b628b95e0..891199d02539fa46454cd0aa7c133637e5dc8235 100644
+--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
++++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+@@ -56,14 +56,28 @@ public class ServerPlayerGameMode {
+ @Nullable
+ private GameType previousGameModeForPlayer;
+ private boolean isDestroyingBlock;
+- private int destroyProgressStart;
++ private int destroyProgressStart; private long lastDigTime; // Paper - lag compensate block breaking
+ private BlockPos destroyPos;
+ private int gameTicks;
+ private boolean hasDelayedDestroy;
+ private BlockPos delayedDestroyPos;
+- private int delayedTickStart;
++ private int delayedTickStart; private long hasDestroyedTooFastStartTime; // Paper - lag compensate block breaking
+ private int lastSentState;
+
++ // Paper start - lag compensate block breaking
++ private int getTimeDiggingLagCompensate() {
++ int lagCompensated = (int)((System.nanoTime() - this.lastDigTime) / (50L * 1000L * 1000L));
++ int tickDiff = this.gameTicks - this.destroyProgressStart;
++ return (com.destroystokyo.paper.PaperConfig.lagCompensateBlockBreaking && lagCompensated > (tickDiff + 1)) ? lagCompensated : tickDiff; // add one to ensure we don't lag compensate unless we need to
++ }
++
++ private int getTimeDiggingTooFastLagCompensate() {
++ int lagCompensated = (int)((System.nanoTime() - this.hasDestroyedTooFastStartTime) / (50L * 1000L * 1000L));
++ int tickDiff = this.gameTicks - this.delayedTickStart;
++ return (com.destroystokyo.paper.PaperConfig.lagCompensateBlockBreaking && lagCompensated > (tickDiff + 1)) ? lagCompensated : tickDiff; // add one to ensure we don't lag compensate unless we need to
++ }
++ // Paper end
++
+ public ServerPlayerGameMode(ServerPlayer player) {
+ this.gameModeForPlayer = GameType.DEFAULT_MODE;
+ this.destroyPos = BlockPos.ZERO;
+@@ -130,7 +144,7 @@ public class ServerPlayerGameMode {
+ if (iblockdata == null || iblockdata.isAir()) { // Paper
+ this.hasDelayedDestroy = false;
+ } else {
+- float f = this.incrementDestroyProgress(iblockdata, this.delayedDestroyPos, this.delayedTickStart);
++ float f = this.updateBlockBreakAnimation(iblockdata, this.delayedDestroyPos, this.getTimeDiggingTooFastLagCompensate()); // Paper - lag compensate destroying blocks
+
+ if (f >= 1.0F) {
+ this.hasDelayedDestroy = false;
+@@ -150,7 +164,7 @@ public class ServerPlayerGameMode {
+ this.lastSentState = -1;
+ this.isDestroyingBlock = false;
+ } else {
+- this.incrementDestroyProgress(iblockdata, this.destroyPos, this.destroyProgressStart);
++ this.updateBlockBreakAnimation(iblockdata, this.destroyPos, this.getTimeDiggingLagCompensate()); // Paper - lag compensate destroying
+ }
+ }
+
+@@ -158,6 +172,12 @@ public class ServerPlayerGameMode {
+
+ private float incrementDestroyProgress(BlockState state, BlockPos pos, int i) {
+ int j = this.gameTicks - i;
++ // Paper start - change i (startTime) to totalTime
++ return this.updateBlockBreakAnimation(state, pos, j);
++ }
++ private float updateBlockBreakAnimation(BlockState state, BlockPos pos, int totalTime) {
++ int j = totalTime;
++ // Paper end
+ float f = state.getDestroyProgress(this.player, this.player.level, pos) * (float) (j + 1);
+ int k = (int) (f * 10.0F);
+
+@@ -234,7 +254,7 @@ public class ServerPlayerGameMode {
+ return;
+ }
+
+- this.destroyProgressStart = this.gameTicks;
++ this.destroyProgressStart = this.gameTicks; this.lastDigTime = System.nanoTime(); // Paper - lag compensate block breaking
+ float f = 1.0F;
+
+ iblockdata1 = this.level.getBlockState(pos);
+@@ -287,12 +307,12 @@ public class ServerPlayerGameMode {
+ int j = (int) (f * 10.0F);
+
+ this.level.destroyBlockProgress(this.player.getId(), pos, j);
+- this.player.connection.send(new ClientboundBlockBreakAckPacket(pos, this.level.getBlockState(pos), action, true, "actual start of destroying"));
++ if (!com.destroystokyo.paper.PaperConfig.lagCompensateBlockBreaking) this.player.connection.send(new ClientboundBlockBreakAckPacket(pos, this.level.getBlockState(pos), action, true, "actual start of destroying"));
+ this.lastSentState = j;
+ }
+ } else if (action == ServerboundPlayerActionPacket.Action.STOP_DESTROY_BLOCK) {
+ if (pos.equals(this.destroyPos)) {
+- int k = this.gameTicks - this.destroyProgressStart;
++ int k = this.getTimeDiggingLagCompensate(); // Paper - lag compensate block breaking
+
+ iblockdata1 = this.level.getBlockState(pos);
+ if (!iblockdata1.isAir()) {
+@@ -309,12 +329,18 @@ public class ServerPlayerGameMode {
+ this.isDestroyingBlock = false;
+ this.hasDelayedDestroy = true;
+ this.delayedDestroyPos = pos;
+- this.delayedTickStart = this.destroyProgressStart;
++ this.delayedTickStart = this.destroyProgressStart; this.hasDestroyedTooFastStartTime = this.lastDigTime; // Paper - lag compensate block breaking
+ }
+ }
+ }
+
++ // Paper start - this can cause clients on a lagging server to think they're not currently destroying a block
++ if (com.destroystokyo.paper.PaperConfig.lagCompensateBlockBreaking) {
++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
++ } else {
+ this.player.connection.send(new ClientboundBlockBreakAckPacket(pos, this.level.getBlockState(pos), action, true, "stopped destroying"));
++ }
++ // Paper end - this can cause clients on a lagging server to think they're not currently destroying a block
+ } else if (action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) {
+ this.isDestroyingBlock = false;
+ if (!Objects.equals(this.destroyPos, pos) && !BlockPos.ZERO.equals(this.destroyPos)) {
+@@ -326,7 +352,7 @@ public class ServerPlayerGameMode {
+ }
+
+ this.level.destroyBlockProgress(this.player.getId(), pos, -1);
+- this.player.connection.send(new ClientboundBlockBreakAckPacket(pos, this.level.getBlockState(pos), action, true, "aborted destroying"));
++ if (!com.destroystokyo.paper.PaperConfig.lagCompensateBlockBreaking) this.player.connection.send(new ClientboundBlockBreakAckPacket(pos, this.level.getBlockState(pos), action, true, "aborted destroying")); // Paper - this can cause clients on a lagging server to think they stopped destroying a block they're currently destroying
+
+ CraftEventFactory.callBlockDamageAbortEvent(this.player, pos, this.player.getInventory().getSelected()); // CraftBukkit
+ }
+@@ -338,7 +364,13 @@ public class ServerPlayerGameMode {
+
+ public void destroyAndAck(BlockPos pos, ServerboundPlayerActionPacket.Action action, String reason) {
+ if (this.destroyBlock(pos)) {
++ // Paper start - this can cause clients on a lagging server to think they're not currently destroying a block
++ if (com.destroystokyo.paper.PaperConfig.lagCompensateBlockBreaking) {
++ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
++ } else {
+ this.player.connection.send(new ClientboundBlockBreakAckPacket(pos, this.level.getBlockState(pos), action, true, reason));
++ }
++ // Paper end - this can cause clients on a lagging server to think they're not currently destroying a block
+ } else {
+ this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos)); // CraftBukkit - SPIGOT-5196
+ }