geforkt von Mirrors/Paper
c5a10665b8
Spigot still maintains some partial implementation of "tick skipping", a practice in which the MinecraftServer.currentTick field is updated not by an increment of one per actual tick, but instead set to System.currentTimeMillis() / 50. This behaviour means that the tracked tick may "skip" a tick value in case a previous tick took more than the expected 50ms. To compensate for this in important paths, spigot/craftbukkit implements "wall-time". Instead of incrementing/decrementing ticks on block entities/entities by one for each call to their tick() method, they instead increment/decrement important values, like an ItemEntity's age or pickupDelay, by the difference of `currentTick - lastTick`, where `lastTick` is the value of `currentTick` during the last tick() call. These "fixes" however do not play nicely with minecraft's simulation distance as entities/block entities implementing the above behaviour would "catch up" their values when moving from a non-ticking chunk to a ticking one as their `lastTick` value remains stuck on the last tick in a ticking chunk and hence lead to a large "catch up" once ticked again. Paper completely removes the "tick skipping" behaviour (See patch "Further-improve-server-tick-loop"), making the above precautions completely unnecessary, which also rids paper of the previous described incompatibility with non-ticking chunks.
76 Zeilen
4.2 KiB
Diff
76 Zeilen
4.2 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Martijn Muijsers <martijnmuijsers@live.nl>
|
|
Date: Tue, 15 Aug 2023 21:04:55 +0200
|
|
Subject: [PATCH] Do crystal-portal proximity check before entity lookup
|
|
|
|
This adds a very cheap distance check when an end crystal is placed.
|
|
|
|
Attempting to respawn the dragon, which involves looking up the end crystal
|
|
entities near the portal, every time an end crystal is placed, can be slow on
|
|
some servers that have players placing end crystals as a style of combat.
|
|
|
|
The very cheap distance check prevents running the entity lookup every time.
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/item/EndCrystalItem.java b/src/main/java/net/minecraft/world/item/EndCrystalItem.java
|
|
index 273bb38f14b8af08d123e02742d365fb5d91cdf5..5f51e64cb0611a4ba6bdcdcacbcba1063a7f3a5c 100644
|
|
--- a/src/main/java/net/minecraft/world/item/EndCrystalItem.java
|
|
+++ b/src/main/java/net/minecraft/world/item/EndCrystalItem.java
|
|
@@ -30,7 +30,7 @@ public class EndCrystalItem extends Item {
|
|
if (!iblockdata.is(Blocks.OBSIDIAN) && !iblockdata.is(Blocks.BEDROCK)) {
|
|
return InteractionResult.FAIL;
|
|
} else {
|
|
- BlockPos blockposition1 = blockposition.above();
|
|
+ BlockPos blockposition1 = blockposition.above(); final BlockPos aboveBlockPosition = blockposition1; // Paper - OBFHELPER
|
|
|
|
if (!world.isEmptyBlock(blockposition1)) {
|
|
return InteractionResult.FAIL;
|
|
@@ -58,7 +58,7 @@ public class EndCrystalItem extends Item {
|
|
EndDragonFight enderdragonbattle = ((ServerLevel) world).getDragonFight();
|
|
|
|
if (enderdragonbattle != null) {
|
|
- enderdragonbattle.tryRespawn();
|
|
+ enderdragonbattle.tryRespawn(aboveBlockPosition); // Paper - Perf: Do crystal-portal proximity check before entity lookup
|
|
}
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
|
index 4a0479fcff94bf6a1f239c1f694202345cdea1d4..84300f2f7b7be4f5281edd8e263646dbcbb3ba07 100644
|
|
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
|
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
|
@@ -560,6 +560,12 @@ public class EndDragonFight {
|
|
}
|
|
|
|
public boolean tryRespawn() { // CraftBukkit - return boolean
|
|
+ // Paper start - Perf: Do crystal-portal proximity check before entity lookup
|
|
+ return this.tryRespawn(null);
|
|
+ }
|
|
+
|
|
+ public boolean tryRespawn(@Nullable BlockPos placedEndCrystalPos) { // placedEndCrystalPos is null if the tryRespawn() call was not caused by a placed end crystal
|
|
+ // Paper end - Perf: Do crystal-portal proximity check before entity lookup
|
|
if (this.dragonKilled && this.respawnStage == null) {
|
|
BlockPos blockposition = this.portalLocation;
|
|
|
|
@@ -577,6 +583,22 @@ public class EndDragonFight {
|
|
blockposition = this.portalLocation;
|
|
}
|
|
|
|
+ // Paper start - Perf: Do crystal-portal proximity check before entity lookup
|
|
+ if (placedEndCrystalPos != null) {
|
|
+ // The end crystal must be 0 or 1 higher than the portal origin
|
|
+ int dy = placedEndCrystalPos.getY() - blockposition.getY();
|
|
+ if (dy != 0 && dy != 1) {
|
|
+ return false;
|
|
+ }
|
|
+ // The end crystal must be within a distance of 1 in one planar direction, and 3 in the other
|
|
+ int dx = placedEndCrystalPos.getX() - blockposition.getX();
|
|
+ int dz = placedEndCrystalPos.getZ() - blockposition.getZ();
|
|
+ if (!((dx >= -1 && dx <= 1 && dz >= -3 && dz <= 3) || (dx >= -3 && dx <= 3 && dz >= -1 && dz <= 1))) {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ // Paper end - Perf: Do crystal-portal proximity check before entity lookup
|
|
+
|
|
List<EndCrystal> list = Lists.newArrayList();
|
|
BlockPos blockposition1 = blockposition.above(1);
|
|
Iterator iterator = Direction.Plane.HORIZONTAL.iterator();
|