aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/1020-Lag-compensation-ticks.patch
blob: 8b870b4b4fe9c63a201ea89ebe5a005c21cc50c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sat, 23 Sep 2023 22:05:35 -0700
Subject: [PATCH] Lag compensation ticks

Areas affected by lag comepnsation:
 - Block breaking and destroying
 - Eating food items

diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 810b6099e734a5524e696beb3f25d6ca686625ea..0408d5d54fef7767ecf70e70686ad520d890ff26 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -315,6 +315,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
 
     public volatile Thread shutdownThread; // Paper
     public volatile boolean abnormalExit = false; // Paper
+    public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
 
     public static <S extends MinecraftServer> S spin(Function<Thread, S> serverFactory) {
         AtomicReference<S> atomicreference = new AtomicReference();
@@ -1754,6 +1755,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
             worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - BlockPhysicsEvent
             worldserver.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent
             net.minecraft.world.level.block.entity.HopperBlockEntity.skipHopperEvents = worldserver.paperConfig().hopper.disableMoveEvent || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper - Perf: Optimize Hoppers
+            worldserver.updateLagCompensationTick(); // Paper - lag compensation
 
             this.profiler.push(() -> {
                 String s = String.valueOf(worldserver);
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 05bf2094d10f924401eb122cd3fe4540aafce497..d4376ed215d97066a21e462fae2a0e25ad8a16a1 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -570,6 +570,17 @@ public class ServerLevel extends Level implements WorldGenLevel {
         return player != null && player.level() == this ? player : null;
     }
     // Paper end - optimise getPlayerByUUID
+    // Paper start - lag compensation
+    private long lagCompensationTick = net.minecraft.server.MinecraftServer.SERVER_INIT;
+
+    public long getLagCompensationTick() {
+        return this.lagCompensationTick;
+    }
+
+    public void updateLagCompensationTick() {
+        this.lagCompensationTick = (System.nanoTime() - net.minecraft.server.MinecraftServer.SERVER_INIT) / (java.util.concurrent.TimeUnit.MILLISECONDS.toNanos(50L));
+    }
+    // Paper end - lag compensation
 
     // Add env and gen to constructor, IWorldDataServer -> WorldDataServer
     public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, PrimaryLevelData iworlddataserver, ResourceKey<Level> resourcekey, LevelStem worlddimension, ChunkProgressListener worldloadlistener, boolean flag, long i, List<CustomSpawner> list, boolean flag1, @Nullable RandomSequences randomsequences, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider) {
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
index f168044d36f22080504da171e5ed31a6f02385ba..5cedce1f432f6b809b25269242a16477682c824f 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -127,7 +127,7 @@ public class ServerPlayerGameMode {
     }
 
     public void tick() {
-        this.gameTicks = MinecraftServer.currentTick; // CraftBukkit;
+        this.gameTicks = (int)this.level.getLagCompensationTick(); // CraftBukkit; // Paper - lag compensation
         BlockState iblockdata;
 
         if (this.hasDelayedDestroy) {
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 8e7ff76818ad26f69785a60de25ad07a3ba72039..ca242ba1312263ec095fa2850dc0f02351e844ab 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3839,6 +3839,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
         this.resendPossiblyDesyncedDataValues(java.util.List.of(DATA_LIVING_ENTITY_FLAGS), serverPlayer);
     }
     // Paper end - Properly cancel usable items
+    // Paper start - lag compensate eating
+    protected long eatStartTime;
+    protected int totalEatTimeTicks;
+    // Paper end - lag compensate eating
     private void updatingUsingItem() {
         if (this.isUsingItem()) {
             if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) {
@@ -3857,7 +3861,12 @@ public abstract class LivingEntity extends Entity implements Attackable {
             this.triggerItemUseEffects(stack, 5);
         }
 
-        if (--this.useItemRemaining == 0 && !this.level().isClientSide && !stack.useOnRelease()) {
+        // Paper start - lag compensate eating
+        // we add 1 to the expected time to avoid lag compensating when we should not
+        boolean shouldLagCompensate = this.useItem.getItem().components().has(DataComponents.FOOD) && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1 + this.totalEatTimeTicks) * 50 * (1000 * 1000));
+        if ((--this.useItemRemaining == 0 || shouldLagCompensate) && !this.level().isClientSide && !stack.useOnRelease()) {
+            this.useItemRemaining = 0;
+            // Paper end - lag compensate eating
             this.completeUsingItem();
         }
 
@@ -3903,7 +3912,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
 
         if (!itemstack.isEmpty() && !this.isUsingItem() || forceUpdate) { // Paper - Prevent consuming the wrong itemstack
             this.useItem = itemstack;
-            this.useItemRemaining = itemstack.getUseDuration();
+            // Paper start - lag compensate eating
+            this.useItemRemaining = this.totalEatTimeTicks = itemstack.getUseDuration();
+            this.eatStartTime = System.nanoTime();
+            // Paper end - lag compensate eating
             if (!this.level().isClientSide) {
                 this.setLivingEntityFlag(1, true);
                 this.setLivingEntityFlag(2, hand == InteractionHand.OFF_HAND);
@@ -3928,7 +3940,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
                 }
             } else if (!this.isUsingItem() && !this.useItem.isEmpty()) {
                 this.useItem = ItemStack.EMPTY;
-                this.useItemRemaining = 0;
+                // Paper start - lag compensate eating
+                this.useItemRemaining = this.totalEatTimeTicks = 0;
+                this.eatStartTime = -1L;
+                // Paper end - lag compensate eating
             }
         }
 
@@ -4063,7 +4078,10 @@ public abstract class LivingEntity extends Entity implements Attackable {
         }
 
         this.useItem = ItemStack.EMPTY;
-        this.useItemRemaining = 0;
+        // Paper start - lag compensate eating
+        this.useItemRemaining = this.totalEatTimeTicks = 0;
+        this.eatStartTime = -1L;
+        // Paper end - lag compensate eating
     }
 
     public boolean isBlocking() {