9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-22 16:29:23 +00:00
Files
DivineMC/divinemc-server/minecraft-patches/features/0014-Lag-compensation.patch
NONPLAYT 03d9aa7325 Updated Upstream (Purpur)
Upstream has released updates that appear to apply and compile correctly

Purpur Changes:
PurpurMC/Purpur@eca78060 Updated Upstream (Paper)
PurpurMC/Purpur@e4e9cfdf Updated Upstream (Paper)
PurpurMC/Purpur@3de2fc7d Updated Upstream (Paper)
PurpurMC/Purpur@09f547de add `mob-griefing-override` config options (#1661)
PurpurMC/Purpur@1dd9bd0c Updated Upstream (Paper)
2025-05-21 21:32:34 +03:00

336 lines
17 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com>
Date: Sat, 1 Feb 2025 18:38:26 +0300
Subject: [PATCH] Lag compensation
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 9956405d7f9d14af7278837adeede76dea8d4bd9..86754cb52caeef962172bcb79cbc8f16bcdd3b63 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -287,6 +287,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
public static final long SERVER_INIT = System.nanoTime(); // Paper - Lag compensation
public boolean lagging = false; // Purpur - Lagging threshold
protected boolean upnp = false; // Purpur - UPnP Port Forwarding
+ public final org.bxteam.divinemc.util.tps.TPSCalculator tpsCalculator = new org.bxteam.divinemc.util.tps.TPSCalculator(); // DivineMC - Lag compensation
public static <S extends MinecraftServer> S spin(Function<Thread, S> threadFunction) {
AtomicReference<S> atomicReference = new AtomicReference<>();
@@ -1533,6 +1534,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
this.server.spark.tickStart(); // Paper - spark
+ this.tpsCalculator.doTick(); // DivineMC - Lag compenstation
new com.destroystokyo.paper.event.server.ServerTickStartEvent(this.tickCount+1).callEvent(); // Paper - Server Tick Events
this.tickCount++;
this.tickRateManager.tick();
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index d003e36a37cbc39d6467a9c45ad716dc27fd62a7..fcd732a923e0ced69d2342fa59122dee0e98438e 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -213,6 +213,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent
private final alternate.current.wire.WireHandler wireHandler = new alternate.current.wire.WireHandler(this); // Paper - optimize redstone (Alternate Current)
public boolean hasRidableMoveEvent = false; // Purpur - Ridables
+ public org.bxteam.divinemc.util.tps.TPSCalculator tpsCalculator = new org.bxteam.divinemc.util.tps.TPSCalculator(); // DivineMC - Lag Compensation
@Override
public @Nullable LevelChunk getChunkIfLoaded(int x, int z) {
@@ -762,6 +763,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
}
}
+ this.tpsCalculator.doTick(); // DivineMC - Lag compensation
+
this.updateSkyBrightness();
if (runsNormally) {
this.tickTime();
@@ -841,11 +844,18 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
this.setDayTime(this.preciseTime);
} else
// Purpur end - Configurable daylight cycle
- this.setDayTime(this.levelData.getDayTime() + 1L);
+ this.setDayTime(lagCompensation(this.levelData.getDayTime()) + 1L); // DivineMC - Lag compensation
}
}
}
+ // DivineMC start - Lag compensation
+ private long lagCompensation(long original) {
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.timeAcceleration) return original;
+ return original + this.tpsCalculator.applicableMissedTicks();
+ }
+ // DivineMC end - Lag compensation
+
public void setDayTime(long time) {
this.serverLevelData.setDayTime(time);
// Purpur start - Configurable daylight cycle
diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java
index f3706dfb6aeb5035cbf0a8bf6b4d9a5243aaaa17..f598c6ae03977998f1cbf79cf3faf7997c2ba9e2 100644
--- a/net/minecraft/world/entity/LivingEntity.java
+++ b/net/minecraft/world/entity/LivingEntity.java
@@ -503,6 +503,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
}
+ lagCompensation(); // DivineMC - Lag Compensation
this.tickEffects();
this.yHeadRotO = this.yHeadRot;
this.yBodyRotO = this.yBodyRot;
@@ -510,6 +511,17 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.xRotO = this.getXRot();
}
+ // DivineMC start - Lag Compensation
+ private void lagCompensation() {
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.potionEffectAcceleration) return;
+ if (this.level().isClientSide()) return;
+
+ for (int i = 0; i < ((ServerLevel) this.level()).tpsCalculator.applicableMissedTicks(); i++) {
+ tickEffects();
+ }
+ }
+ // DivineMC end - Lag Compensation
+
@Override
protected float getBlockSpeedFactor() {
return Mth.lerp((float)this.getAttributeValue(Attributes.MOVEMENT_EFFICIENCY), super.getBlockSpeedFactor(), 1.0F);
diff --git a/net/minecraft/world/entity/PortalProcessor.java b/net/minecraft/world/entity/PortalProcessor.java
index 88b07fbb96b20124777889830afa480673629d43..d2661ea79536010414f77256332f214d19106dd9 100644
--- a/net/minecraft/world/entity/PortalProcessor.java
+++ b/net/minecraft/world/entity/PortalProcessor.java
@@ -24,10 +24,20 @@ public class PortalProcessor {
return false;
} else {
this.insidePortalThisTick = false;
- return canChangeDimensions && this.portalTime++ >= this.portal.getPortalTransitionTime(level, entity);
+ return canChangeDimensions && lagCompensation(this.portalTime++, level) >= this.portal.getPortalTransitionTime(level, entity); // DivineMC - Lag compensation
}
}
+ // DivineMC start - Lag compensation
+ private int lagCompensation(int original, ServerLevel world) {
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.portalAcceleration) return original;
+ if (world.isClientSide()) return original;
+
+ portalTime = portalTime + world.tpsCalculator.applicableMissedTicks();
+ return portalTime;
+ }
+ // DivineMC end - Lag compensation
+
@Nullable
public TeleportTransition getPortalDestination(ServerLevel level, Entity entity) {
return this.portal.getPortalDestination(level, entity, this.entryPosition);
diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java
index 4ddf1cdf7a47bf06f95c5bfce8f3c4d035e87cfc..60f5232b24ace1854a3cea7aa790385ae4e90ea9 100644
--- a/net/minecraft/world/entity/item/ItemEntity.java
+++ b/net/minecraft/world/entity/item/ItemEntity.java
@@ -160,8 +160,25 @@ public class ItemEntity extends Entity implements TraceableEntity {
}
// Paper end - EAR 2
+ // DivineMC start - Lag compensation
+ private void lagCompensation() {
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.pickupAcceleration) return;
+ if ((this).level().isClientSide()) return;
+
+ if (pickupDelay == 0) return;
+
+ if (pickupDelay - ((ServerLevel) this.level()).tpsCalculator.applicableMissedTicks() <= 0) {
+ pickupDelay = 0;
+ return;
+ }
+
+ pickupDelay = pickupDelay - ((ServerLevel) this.level()).tpsCalculator.applicableMissedTicks();
+ }
+ // DivineMC end - Lag compensation
+
@Override
public void tick() {
+ lagCompensation(); // DivineMC - Lag compensation
if (this.getItem().isEmpty()) {
this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause
} else {
diff --git a/net/minecraft/world/item/Item.java b/net/minecraft/world/item/Item.java
index c52fb17d1e496a91223b7387cacb128c1865caee..30ab94fa0a6710cc5a39bd1c74c99aac08037167 100644
--- a/net/minecraft/world/item/Item.java
+++ b/net/minecraft/world/item/Item.java
@@ -286,10 +286,25 @@ public class Item implements FeatureElement, ItemLike {
}
}
+ // DivineMC start - Lag compensation
+ private int lagCompensation(int original, net.minecraft.server.level.ServerLevel level) {
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.eatingAcceleration || original == 0) return original;
+ return org.bxteam.divinemc.util.tps.TPSUtil.tt20(original, true, level);
+ }
+ // DivineMC end - Lag compensation
+
public int getUseDuration(ItemStack stack, LivingEntity entity) {
Consumable consumable = stack.get(DataComponents.CONSUMABLE);
if (consumable != null) {
- return consumable.consumeTicks();
+ // DivineMC start - Lag compensation
+ int original = consumable.consumeTicks();
+
+ if (entity.level() instanceof net.minecraft.server.level.ServerLevel serverLevel) {
+ return lagCompensation(original, serverLevel);
+ }
+
+ return original;
+ // DivineMC end - Lag compensation
} else {
BlocksAttacks blocksAttacks = stack.get(DataComponents.BLOCKS_ATTACKS);
return blocksAttacks != null ? 72000 : 0;
diff --git a/net/minecraft/world/level/GameRules.java b/net/minecraft/world/level/GameRules.java
index c9a2c4f7051639478bd9788911d3c6bead8f5152..df916f661d54bc4373eebafaaf3a94f9863ddd63 100644
--- a/net/minecraft/world/level/GameRules.java
+++ b/net/minecraft/world/level/GameRules.java
@@ -355,8 +355,31 @@ public class GameRules {
}
public int getInt(GameRules.Key<GameRules.IntegerValue> key) {
- return this.getRule(key).get();
+ return lagCompensation(this.getRule(key).get(), key); // DivineMC - Lag compensation
+ }
+
+ // DivineMC start - Lag compensation
+ private final java.util.concurrent.atomic.AtomicReference<net.minecraft.server.level.ServerLevel> level = new java.util.concurrent.atomic.AtomicReference<>();
+
+ private int lagCompensation(int original, GameRules.Key<GameRules.IntegerValue> rule) {
+ ServerLevel level = getOrCacheLevel();
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.randomTickSpeedAcceleration) return original;
+ if (!(rule == GameRules.RULE_RANDOMTICKING)) return original;
+ return (int) (original * org.bxteam.divinemc.util.tps.TPSCalculator.MAX_TPS / (float) level.tpsCalculator.getMostAccurateTPS());
+ }
+
+ private ServerLevel getOrCacheLevel() {
+ if (level.get() == null) {
+ for (final ServerLevel level : MinecraftServer.getServer().getAllLevels()) {
+ if (level.getGameRules() == this) {
+ this.level.set(level);
+ break;
+ }
+ }
+ }
+ return level.get();
}
+ // DivineMC end - Lag compensation
public static class BooleanValue extends GameRules.Value<GameRules.BooleanValue> {
private boolean value;
diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java
index 8db95b74f88f8096de93115ae8d3fb2e6184ad3b..8c0abcbf1af03092b54d2e4bdad8ac152c2431e6 100644
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
@@ -347,13 +347,21 @@ public abstract class BlockBehaviour implements FeatureElement {
protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) {
}
+ // DivineMC start - Lag compensation
+ private float lagCompensation(float original, Player player) {
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.blockBreakingAcceleration) return original;
+ if (player.level().isClientSide) return original;
+ return original * org.bxteam.divinemc.util.tps.TPSCalculator.MAX_TPS / (float) ((ServerLevel) player.level()).tpsCalculator.getMostAccurateTPS();
+ }
+ // DivineMC end - Lag compensation
+
protected float getDestroyProgress(BlockState state, Player player, BlockGetter level, BlockPos pos) {
float destroySpeed = state.getDestroySpeed(level, pos);
if (destroySpeed == -1.0F) {
- return 0.0F;
+ return lagCompensation(0.0F, player); // DivineMC - Lag compensation
} else {
int i = player.hasCorrectToolForDrops(state) ? 30 : 100;
- return player.getDestroySpeed(state) / destroySpeed / i;
+ return lagCompensation(player.getDestroySpeed(state) / destroySpeed / i, player); // DivineMC - Lag compensation
}
}
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
index 04942e23dd2bc82e4c60110756beedb5e0f074d7..7eb6da13dc47eaeac6e70d4e2935c1cc022c6400 100644
--- a/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
@@ -910,6 +910,19 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
this.ticker = ticker;
}
+ // DivineMC start - Lag compensation
+ private <T extends BlockEntity> void lagCompensation(Runnable original) {
+ original.run();
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled) return;
+ if (!org.bxteam.divinemc.DivineConfig.blockEntityAcceleration) return;
+ if (LevelChunk.this.level.isClientSide()) return;
+
+ for (int i = 0; i < ((ServerLevel) this.blockEntity.getLevel()).tpsCalculator.applicableMissedTicks(); i++) {
+ original.run();
+ }
+ }
+ // DivineMC end - Lag compensation
+
@Override
public void tick() {
if (!this.blockEntity.isRemoved() && this.blockEntity.hasLevel()) {
@@ -918,7 +931,11 @@ public class LevelChunk extends ChunkAccess implements ca.spottedleaf.moonrise.p
try {
BlockState blockState = LevelChunk.this.getBlockState(blockPos);
if (this.blockEntity.getType().isValid(blockState)) {
- this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), blockState, this.blockEntity);
+ // DivineMC start - Lag compensation
+ lagCompensation(() -> {
+ this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), blockState, this.blockEntity);
+ });
+ // DivineMC end - Lag compensation
this.loggedInvalidBlockState = false;
// Paper start - Remove the Block Entity if it's invalid
} else {
diff --git a/net/minecraft/world/level/material/LavaFluid.java b/net/minecraft/world/level/material/LavaFluid.java
index e7ae29a4da3bf36b99fdab39af78f03c06696dbc..e57c04df4cb5955713d61d8237094041d3f3ca4f 100644
--- a/net/minecraft/world/level/material/LavaFluid.java
+++ b/net/minecraft/world/level/material/LavaFluid.java
@@ -187,9 +187,22 @@ public abstract class LavaFluid extends FlowingFluid {
return fluidState.getHeight(blockReader, pos) >= 0.44444445F && fluid.is(FluidTags.WATER);
}
+ // DivineMC start - Lag compensation
+ private int lagCompensation(int original, ServerLevel level) {
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.fluidAcceleration) return original;
+ return org.bxteam.divinemc.util.tps.TPSUtil.tt20(original, true, level);
+ }
+ // DivineMC end - Lag compensation
+
@Override
public int getTickDelay(LevelReader level) {
- return level.dimensionType().ultraWarm() ? level.getWorldBorder().world.purpurConfig.lavaSpeedNether : level.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur - Make lava flow speed configurable
+ // DivineMC start - Lag compensation
+ int original = level.dimensionType().ultraWarm() ? level.getWorldBorder().world.purpurConfig.lavaSpeedNether : level.getWorldBorder().world.purpurConfig.lavaSpeedNotNether; // Purpur - Make lava flow speed configurable
+ if (level instanceof ServerLevel serverLevel) {
+ return lagCompensation(original, serverLevel);
+ }
+ return original;
+ // DivineMC end - Lag compensation
}
@Override
diff --git a/net/minecraft/world/level/material/WaterFluid.java b/net/minecraft/world/level/material/WaterFluid.java
index b248fe1d66940c05d56fc322df61c52ece72e77f..8fa7883a0fe5fc2651d640ecde20198293afa654 100644
--- a/net/minecraft/world/level/material/WaterFluid.java
+++ b/net/minecraft/world/level/material/WaterFluid.java
@@ -124,8 +124,16 @@ public abstract class WaterFluid extends FlowingFluid {
return 1;
}
+ // DivineMC start - Lag compensation
+ private int lagCompensation(ServerLevel level) {
+ if (!org.bxteam.divinemc.DivineConfig.lagCompensationEnabled || !org.bxteam.divinemc.DivineConfig.fluidAcceleration) return 5;
+ return org.bxteam.divinemc.util.tps.TPSUtil.tt20(5, true, level);
+ }
+ // DivineMC end - Lag compensation
+
@Override
public int getTickDelay(LevelReader level) {
+ if (level instanceof ServerLevel serverLevel) return lagCompensation(serverLevel); // DivineMC - Lag compensation
return 5;
}