Readd more patches

This commit is contained in:
Nassim Jahnke 2024-07-04 12:34:11 +02:00
parent 8c8b227547
commit b89e6a0195
No known key found for this signature in database
GPG key ID: EF6771C01F6EF02F
39 changed files with 171 additions and 588 deletions

View file

@ -3,7 +3,7 @@ version=1.21-R0.1-SNAPSHOT
mcVersion=1.21
# Set to true while updating Minecraft version
updatingMinecraft=true
updatingMinecraft=false
org.gradle.caching=true
org.gradle.parallel=true

View file

@ -27387,7 +27387,7 @@ index bd20bea7f76a7307f1698fb2dfef37125032d166..70c2017400168d4fef3c14462798edcf
if (shape.isEmpty()) {
return true;
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index e27d3547d1e19c137e05e6b8d075127a8bafb237..613752e2df61fdd8010f8ad0cf25257580bfe32e 100644
index e27d3547d1e19c137e05e6b8d075127a8bafb237..a022bbaa16054c56696a7a03e71ef042340d88ec 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -102,7 +102,7 @@ import org.bukkit.entity.SpawnCategory;
@ -27489,17 +27489,19 @@ index e27d3547d1e19c137e05e6b8d075127a8bafb237..613752e2df61fdd8010f8ad0cf252575
int tilesThisCycle = 0;
var toRemove = new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<TickingBlockEntity>(); // Paper - Fix MC-117075; use removeAll
toRemove.add(null); // Paper - Fix MC-117075
@@ -828,6 +888,9 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -828,6 +888,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
// Spigot end
} else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) {
tickingblockentity.tick();
+ // Paper start - rewrite chunk system
+ if ((++tickedEntities & 7) == 0) {
+ ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemLevel)(Level)(Object)this).moonrise$midTickTasks();
+ }
+ // Paper end - rewrite chunk system
}
}
this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075
@@ -850,6 +913,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -850,6 +915,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
// Paper end - Prevent block entity and entity crashes
}
@ -27507,7 +27509,7 @@ index e27d3547d1e19c137e05e6b8d075127a8bafb237..613752e2df61fdd8010f8ad0cf252575
}
// Paper start - Option to prevent armor stands from doing entity lookups
@Override
@@ -949,7 +1013,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -949,7 +1015,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
}
// Paper end - Perf: Optimize capturedTileEntities lookup
// CraftBukkit end
@ -27516,7 +27518,7 @@ index e27d3547d1e19c137e05e6b8d075127a8bafb237..613752e2df61fdd8010f8ad0cf252575
}
public void setBlockEntity(BlockEntity blockEntity) {
@@ -1039,28 +1103,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -1039,28 +1105,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@Override
public List<Entity> getEntities(@Nullable Entity except, AABB box, Predicate<? super Entity> predicate) {
this.getProfiler().incrementCounter("getEntities");
@ -27550,7 +27552,7 @@ index e27d3547d1e19c137e05e6b8d075127a8bafb237..613752e2df61fdd8010f8ad0cf252575
}
@Override
@@ -1075,36 +1124,77 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -1075,36 +1126,77 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
this.getEntities(filter, box, predicate, result, Integer.MAX_VALUE);
}

View file

@ -29,7 +29,7 @@ index 02367ef1371dde94ff6c4cd40bd32e800d6ccaaf..7b0fc7135bc107103dcaed6dc0707b18
this.x = x;
this.y = y;
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 613752e2df61fdd8010f8ad0cf25257580bfe32e..fe14d02b7c3ed2b69717622f392bf077171343fd 100644
index a022bbaa16054c56696a7a03e71ef042340d88ec..645bdb59d791016083fa14015d94ea2c0d4d2cf0 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -399,7 +399,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl

View file

@ -62,7 +62,7 @@ index bb8e962e63c7a2d931f9bd7f7c002aa35cfa5fd3..0fa131a6c98adb498fc8d534e0e39647
default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
// Paper start - Add predicate for blocks when raytracing
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index fe14d02b7c3ed2b69717622f392bf077171343fd..ea81c6e924091bf86ddbc001f9ecdb58c9c3e5b2 100644
index 645bdb59d791016083fa14015d94ea2c0d4d2cf0..d8adcbb64040cbd24df884f1ef79d4dff7f93a43 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -391,10 +391,87 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl

View file

@ -340,7 +340,7 @@ index 0b7f52021441d633c37543e8ae485e81c292b747..d7f8464bf3eed0e42a5fc7f14a5b243d
+
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index ea81c6e924091bf86ddbc001f9ecdb58c9c3e5b2..c64bb7858345d93e4b2e65404ffdaffde8458c0f 100644
index d8adcbb64040cbd24df884f1ef79d4dff7f93a43..0a03a735ccdfa81c0607d5516b93a15eec43f3aa 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -156,6 +156,12 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl

View file

@ -1168,7 +1168,7 @@ index 9b1a6d8351fb473eec75a2fd08fb892b770e3586..0d0b07c9199be9ca0d5ac3feb1d44f14
}
// Paper end - Send empty chunk
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index c64bb7858345d93e4b2e65404ffdaffde8458c0f..4994b964819600604cb123d4cf7ec27978796bb8 100644
index 0a03a735ccdfa81c0607d5516b93a15eec43f3aa..6bbaf4a60190047a36e463c774630bdc1cf049aa 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -171,6 +171,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl

View file

@ -2035,10 +2035,10 @@ index 8daa490817367391cac5c9852e0755b280fb9054..2d97ca1f3c625c0206d35b785c57d958
EntityCallbacks() {}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 4994b964819600604cb123d4cf7ec27978796bb8..06e9fc703b0ef722cc21a365203a561009047d23 100644
index 6bbaf4a60190047a36e463c774630bdc1cf049aa..0ef67317a922f28202c84c7a1f81f3c534d2b838 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1579,4 +1579,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -1581,4 +1581,14 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
}
}
// Paper end - notify observers even if grow failed

View file

@ -14,22 +14,22 @@ movement will load only the chunk the player enters anyways and avoids loading
massive amounts of surrounding chunks due to large AABB lookups.
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 8f1a2de2a5542929f8a2fdd4d38de141eda985b2..29b35b8c0a6001d626e327a82eaff26d068660db 100644
index 0d0b07c9199be9ca0d5ac3feb1d44f149ba69283..14fb62dedabf2d858bea1877c2e28d1a7b6f5be4 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -934,6 +934,7 @@ public abstract class PlayerList {
entityplayer1.setShiftKeyDown(false);
entityplayer1.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
@@ -865,6 +865,7 @@ public abstract class PlayerList {
Vec3 vec3d = dimensiontransition.pos();
+ worldserver1.getChunkSource().addRegionTicket(net.minecraft.server.level.TicketType.POST_TELEPORT, new net.minecraft.world.level.ChunkPos(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
while (avoidSuffocation && !worldserver1.noCollision((Entity) entityplayer1) && entityplayer1.getY() < (double) worldserver1.getMaxBuildHeight()) {
// CraftBukkit end
entityplayer1.setPos(entityplayer1.getX(), entityplayer1.getY() + 1.0D, entityplayer1.getZ());
entityplayer1.forceSetPositionRotation(vec3d.x, vec3d.y, vec3d.z, dimensiontransition.yRot(), dimensiontransition.xRot());
+ worldserver.getChunkSource().addRegionTicket(net.minecraft.server.level.TicketType.POST_TELEPORT, new net.minecraft.world.level.ChunkPos(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
// CraftBukkit end
if (dimensiontransition.missingRespawnBlock()) {
entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F));
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 6f48af629392f4426e50f752424fc9f58985688a..26b21af65ff63c83fb3be80740e41b40f0feb944 100644
index 5d7bc6470ab3818b0a189aab18ff26c0180e3912..f1fb4e830c6720d09b22056e3d0b9a08fe2bd472 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -244,6 +244,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -250,6 +250,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// Paper end - Share random for entities to make them more random
public org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason

View file

@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 2 Aug 2021 10:10:40 +0200
Subject: [PATCH] Improve boat collision performance
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index 42d7ecfab6f72517904451d9df3f0404b176fdb2..5869f2f5c72f736e6b077683327c64b9e0e0c733 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -125,6 +125,7 @@ public class Util {
.filter(fileSystemProvider -> fileSystemProvider.getScheme().equalsIgnoreCase("jar"))
.findFirst()
.orElseThrow(() -> new IllegalStateException("No jar file system provider found"));
+ public static final double COLLISION_EPSILON = 1.0E-7; // Paper - Improve boat collision performance
private static Consumer<String> thePauser = message -> {
};
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 25a7dfddb44a11f6e20c459141a61270c0c12d4c..affc39430e1f77e09768d2f614fcd5073d5a9270 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1436,7 +1436,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (!source.is(DamageTypeTags.IS_PROJECTILE)) {
Entity entity = source.getDirectEntity();
- if (entity instanceof LivingEntity) {
+ if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Improve boat collision performance
LivingEntity entityliving = (LivingEntity) entity;
this.blockUsingShield(entityliving);
@@ -1533,8 +1533,13 @@ public abstract class LivingEntity extends Entity implements Attackable {
double d0 = 0.0D;
double d1 = 0.0D;
Entity entity2 = source.getDirectEntity();
-
- if (entity2 instanceof Projectile) {
+ // Paper start - improve boat collision performance
+ final boolean far = entity2.distanceToSqr(this) > (200.0D * 200.0D);
+ if (far) {
+ d0 = Math.random() - Math.random();
+ d1 = Math.random() - Math.random();
+ } else if (entity2 instanceof Projectile) {
+ // Paper end - improve boat collision performance
Projectile iprojectile = (Projectile) entity2;
DoubleDoubleImmutablePair doubledoubleimmutablepair = iprojectile.calculateHorizontalHurtKnockbackDirection(this, source);
@@ -2325,7 +2330,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING));
Entity entity = damagesource.getDirectEntity();
- if (!damagesource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity) { // Paper - Fix shield disable inconsistency
+ if (!damagesource.is(DamageTypeTags.IS_PROJECTILE) && entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Fix shield disable inconsistency & improve boat collision performance
this.blockUsingShield((LivingEntity) entity);
}
}
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
index 907f751c859855484151fb5d607acee2f2a35076..edd30d872d151f953df28c8f6d40efa8d39f5e36 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
@@ -718,7 +718,7 @@ public class Boat extends VehicleEntity implements Leashable, VariantHolder<Boat
double d2 = (double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D;
if (this.level().noCollision(this, this.getBoundingBox().move(0.0D, d2 - this.getY(), 0.0D))) {
- this.setPos(this.getX(), d2, this.getZ());
+ this.move(MoverType.SELF, new Vec3(0.0D, d2 - this.getY(), 0.0D)); // Paper - improve boat collision performance
this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
this.lastYd = 0.0D;
}

View file

@ -32,7 +32,7 @@ had to be specifically modified.
diff --git a/src/main/java/io/papermc/paper/util/PoiAccess.java b/src/main/java/io/papermc/paper/util/PoiAccess.java
new file mode 100644
index 0000000000000000000000000000000000000000..69be1761b3b5ba7b496c1c10a4db897e6212d671
index 0000000000000000000000000000000000000000..d8190b56d216b0e48bfc2d5739bdf533bf95b425
--- /dev/null
+++ b/src/main/java/io/papermc/paper/util/PoiAccess.java
@@ -0,0 +1,804 @@
@ -249,10 +249,10 @@ index 0000000000000000000000000000000000000000..69be1761b3b5ba7b496c1c10a4db897e
+ double closestDistanceSquared = maxDistanceSquared;
+
+ final int lowerX = Mth.floor(sourcePosition.getX() - range) >> 4;
+ final int lowerY = WorldUtil.getMinSection(poiStorage.world);
+ final int lowerY = WorldUtil.getMinSection(poiStorage.moonrise$getWorld());
+ final int lowerZ = Mth.floor(sourcePosition.getZ() - range) >> 4;
+ final int upperX = Mth.floor(sourcePosition.getX() + range) >> 4;
+ final int upperY = WorldUtil.getMaxSection(poiStorage.world);
+ final int upperY = WorldUtil.getMaxSection(poiStorage.moonrise$getWorld());
+ final int upperZ = Mth.floor(sourcePosition.getZ() + range) >> 4;
+
+ final int centerX = sourcePosition.getX() >> 4;
@ -492,10 +492,10 @@ index 0000000000000000000000000000000000000000..69be1761b3b5ba7b496c1c10a4db897e
+ double furthestDistanceSquared = maxDistanceSquared;
+
+ final int lowerX = Mth.floor(sourcePosition.getX() - range) >> 4;
+ final int lowerY = WorldUtil.getMinSection(poiStorage.world);
+ final int lowerY = WorldUtil.getMinSection(poiStorage.moonrise$getWorld());
+ final int lowerZ = Mth.floor(sourcePosition.getZ() - range) >> 4;
+ final int upperX = Mth.floor(sourcePosition.getX() + range) >> 4;
+ final int upperY = WorldUtil.getMaxSection(poiStorage.world);
+ final int upperY = WorldUtil.getMaxSection(poiStorage.moonrise$getWorld());
+ final int upperZ = Mth.floor(sourcePosition.getZ() + range) >> 4;
+
+ final int centerX = sourcePosition.getX() >> 4;
@ -769,10 +769,10 @@ index 0000000000000000000000000000000000000000..69be1761b3b5ba7b496c1c10a4db897e
+ // First up, we need to iterate the chunks
+ // all the values here are in chunk sections
+ final int lowerX = Mth.floor(sourcePosition.getX() - range) >> 4;
+ final int lowerY = Math.max(WorldUtil.getMinSection(poiStorage.world), Mth.floor(sourcePosition.getY() - range) >> 4);
+ final int lowerY = Math.max(WorldUtil.getMinSection(poiStorage.moonrise$getWorld()), Mth.floor(sourcePosition.getY() - range) >> 4);
+ final int lowerZ = Mth.floor(sourcePosition.getZ() - range) >> 4;
+ final int upperX = Mth.floor(sourcePosition.getX() + range) >> 4;
+ final int upperY = Math.min(WorldUtil.getMaxSection(poiStorage.world), Mth.floor(sourcePosition.getY() + range) >> 4);
+ final int upperY = Math.min(WorldUtil.getMaxSection(poiStorage.moonrise$getWorld()), Mth.floor(sourcePosition.getY() + range) >> 4);
+ final int upperZ = Mth.floor(sourcePosition.getZ() + range) >> 4;
+
+ // Vanilla iterates by x until max is reached then increases z
@ -884,10 +884,10 @@ index d5a549f08b98c80a5cf0eef02cb8a389c32dfecb..92731b6b593289e9f583c9b705b219e8
BlockPos blockPos = path.getTarget();
Optional<Holder<PoiType>> optional = poiManager.getType(blockPos);
diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
index 7b52b0507cbda76aee1db954641f397bef51f94d..c6f193339fdcbcc938d4eafdcad0b112cf1698d5 100644
index 274ddf479d38495d84838f9cd73c13d2841c3b44..0be7346f9c5e89ea03c69f7c8ba4733d2c7759fc 100644
--- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
@@ -138,36 +138,45 @@ public class PoiManager extends SectionStorage<PoiSection> {
@@ -268,36 +268,45 @@ public class PoiManager extends SectionStorage<PoiSection> implements ca.spotted
public Optional<BlockPos> find(
Predicate<Holder<PoiType>> typePredicate, Predicate<BlockPos> posPredicate, BlockPos pos, int radius, PoiManager.Occupancy occupationStatus
) {
@ -947,7 +947,7 @@ index 7b52b0507cbda76aee1db954641f397bef51f94d..c6f193339fdcbcc938d4eafdcad0b112
.map(poi -> {
poi.acquireTicket();
return poi.getPos();
@@ -182,8 +191,21 @@ public class PoiManager extends SectionStorage<PoiSection> {
@@ -312,8 +321,21 @@ public class PoiManager extends SectionStorage<PoiSection> implements ca.spotted
int radius,
RandomSource random
) {
@ -972,23 +972,23 @@ index 7b52b0507cbda76aee1db954641f397bef51f94d..c6f193339fdcbcc938d4eafdcad0b112
public boolean release(BlockPos pos) {
diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java
index 5b7deae326228e482b218aeebd857a59b7434eaf..4ee7d75c56d9f9ff3607276857dde84410ba3f2a 100644
index a6c0e89cb645693034f8e90ac2de8f2da457453c..11e895d837794d79a76303b912092096bd7d07a8 100644
--- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java
+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiSection.java
@@ -26,7 +26,7 @@ import org.slf4j.Logger;
public class PoiSection {
public class PoiSection implements ca.spottedleaf.moonrise.patches.chunk_system.level.poi.ChunkSystemPoiSection { // Paper - rewrite chunk system
private static final Logger LOGGER = LogUtils.getLogger();
private final Short2ObjectMap<PoiRecord> records = new Short2ObjectOpenHashMap<>();
- private final Map<Holder<PoiType>, Set<PoiRecord>> byType = Maps.newHashMap();
+ private final Map<Holder<PoiType>, Set<PoiRecord>> byType = Maps.newHashMap(); public final Map<Holder<PoiType>, Set<PoiRecord>> getData() { return this.byType; } // Paper - public accessor
private final Runnable setDirty;
private boolean isValid;
public final Optional<PoiSection> noAllocateOptional = Optional.of(this); // Paper - rewrite chunk system
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
index 883fbe5c81e3be27007a1a0489f80ba1863e5a04..a4a919d8373f1535e336de7e648d41a07efb1cba 100644
index c7ed3eb80f6e8b918434153093644776866aa220..21de1b95f2a5d136149447472e871f675760ba1a 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
@@ -74,11 +74,11 @@ public class SectionStorage<R> extends RegionFileStorage implements AutoCloseabl
@@ -81,11 +81,11 @@ public abstract class SectionStorage<R> implements AutoCloseable, ca.spottedleaf
}
@Nullable
@ -1003,25 +1003,24 @@ index 883fbe5c81e3be27007a1a0489f80ba1863e5a04..a4a919d8373f1535e336de7e648d41a0
return Optional.empty();
} else {
diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
index a61959700d5e00739a79eaa617ac383160335f26..2407d93c11b806701fc7d192f39d535128281e80 100644
index fd04a50183ccb1f21fc6efa70256e1bb4db2d6d4..49f7ba292b82bac1643cc07aa576f3c37b8e8ab3 100644
--- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
+++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
@@ -51,18 +51,39 @@ public class PortalForcer {
@@ -53,17 +53,39 @@ public class PortalForcer {
// int i = flag ? 16 : 128;
// CraftBukkit end
- villageplace.ensureLoadedAndValid(this.level, blockposition, i);
- Optional<PoiRecord> optional = villageplace.getInSquare((holder) -> {
- Stream<BlockPos> stream = villageplace.getInSquare((holder) -> { // CraftBukkit - decompile error
- return holder.is(PoiTypes.NETHER_PORTAL);
- }, blockposition, i, PoiManager.Occupancy.ANY).filter((villageplacerecord) -> {
- return worldborder.isWithinBounds(villageplacerecord.getPos()) && !(this.level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> villageplacerecord.getPos().getY() >= v)); // Paper - Configurable nether ceiling damage
- }).sorted(Comparator.comparingDouble((PoiRecord villageplacerecord) -> { // CraftBukkit - decompile error
- return villageplacerecord.getPos().distSqr(blockposition);
- }).thenComparingInt((villageplacerecord) -> {
- return villageplacerecord.getPos().getY();
- })).filter((villageplacerecord) -> {
- return this.level.getBlockState(villageplacerecord.getPos()).hasProperty(BlockStateProperties.HORIZONTAL_AXIS);
- }).findFirst();
- }, blockposition, i, PoiManager.Occupancy.ANY).map(PoiRecord::getPos);
-
- Objects.requireNonNull(worldborder);
- return stream.filter(worldborder::isWithinBounds).filter(pos -> !(this.level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER && this.level.paperConfig().environment.netherCeilingVoidDamageHeight.test(v -> pos.getY() >= v))).filter((blockposition1) -> { // Paper - Configurable nether ceiling damage
- return this.level.getBlockState(blockposition1).hasProperty(BlockStateProperties.HORIZONTAL_AXIS);
- }).min(Comparator.comparingDouble((BlockPos blockposition1) -> { // CraftBukkit - decompile error
- return blockposition1.distSqr(blockposition);
- }).thenComparingInt(Vec3i::getY));
+ // Paper start - optimise portals
+ Optional<PoiRecord> optional;
+ java.util.List<PoiRecord> records = new java.util.ArrayList<>();
@ -1030,7 +1029,7 @@ index a61959700d5e00739a79eaa617ac383160335f26..2407d93c11b806701fc7d192f39d5351
+ type -> type.is(PoiTypes.NETHER_PORTAL),
+ (BlockPos pos) -> {
+ net.minecraft.world.level.chunk.ChunkAccess lowest = this.level.getChunk(pos.getX() >> 4, pos.getZ() >> 4, net.minecraft.world.level.chunk.status.ChunkStatus.EMPTY);
+ if (!lowest.getStatus().isOrAfter(net.minecraft.world.level.chunk.status.ChunkStatus.FULL)
+ if (!lowest.getPersistedStatus().isOrAfter(net.minecraft.world.level.chunk.status.ChunkStatus.FULL)
+ && (lowest.getBelowZeroRetrogen() == null || !lowest.getBelowZeroRetrogen().targetStatus().isOrAfter(net.minecraft.world.level.chunk.status.ChunkStatus.SPAWN))) {
+ // why would we generate the chunk?
+ return false;
@ -1044,17 +1043,17 @@ index a61959700d5e00739a79eaa617ac383160335f26..2407d93c11b806701fc7d192f39d5351
+ );
+
+ // this gets us most of the way there, but we bias towards lower y values.
+ PoiRecord lowestYRecord = null;
+ BlockPos lowestPos = null;
+ for (PoiRecord record : records) {
+ if (lowestYRecord == null) {
+ lowestYRecord = record;
+ } else if (lowestYRecord.getPos().getY() > record.getPos().getY()) {
+ lowestYRecord = record;
+ if (lowestPos == null) {
+ lowestPos = record.getPos();
+ } else if (lowestPos.getY() > record.getPos().getY()) {
+ lowestPos = record.getPos();
+ }
+ }
+ // now we're done
+ optional = Optional.ofNullable(lowestYRecord);
+ return Optional.ofNullable(lowestPos);
+ // Paper end - optimise portals
}
return optional.map((villageplacerecord) -> {
BlockPos blockposition1 = villageplacerecord.getPos();
public Optional<BlockUtil.FoundRectangle> createPortal(BlockPos pos, Direction.Axis axis) {

View file

@ -102,7 +102,7 @@ index a8debfad8c8e66099f8a9aedc6f1971a8576dade..7796e191747be545e744564a2b0b6579
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 0d0b07c9199be9ca0d5ac3feb1d44f149ba69283..3d30427e75bdfb9cf453fb5cd2a344227da1641a 100644
index 14fb62dedabf2d858bea1877c2e28d1a7b6f5be4..bad83045ff9409678a0699cdc0781efd8ef30a44 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -393,7 +393,7 @@ public abstract class PlayerList {
@ -115,10 +115,10 @@ index 0d0b07c9199be9ca0d5ac3feb1d44f149ba69283..3d30427e75bdfb9cf453fb5cd2a34422
this.sendLevelInfo(player, worldserver1);
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 5d7bc6470ab3818b0a189aab18ff26c0180e3912..2519c08a45ce3febcf51ac308ad98ac0e2657cf3 100644
index f1fb4e830c6720d09b22056e3d0b9a08fe2bd472..83f3ffdd8fa901b3de580d2359cdb5ead0d762cb 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -664,13 +664,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -665,13 +665,44 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
// CraftBukkit start
public void refreshEntityData(ServerPlayer to) {
@ -166,10 +166,10 @@ index 5d7bc6470ab3818b0a189aab18ff26c0180e3912..2519c08a45ce3febcf51ac308ad98ac0
public boolean equals(Object object) {
return object instanceof Entity ? ((Entity) object).id == this.id : false;
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 25a7dfddb44a11f6e20c459141a61270c0c12d4c..e980c8c356b30d25e2fc5a73b91ad2c6edd4fe05 100644
index affc39430e1f77e09768d2f614fcd5073d5a9270..b9cef93fe382b666bec04ca95eeaf2d8acbb3c40 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3840,6 +3840,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
@@ -3845,6 +3845,11 @@ public abstract class LivingEntity extends Entity implements Attackable {
return ((Byte) this.entityData.get(LivingEntity.DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
}

View file

@ -90,10 +90,10 @@ index 0000000000000000000000000000000000000000..7d93652c1abbb6aee6eb7c26cf35d4d0
+ }
+}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 3a49f8933bc6ca1862994b7e0b3006f5236dd94a..bdad61438e7fd89f5f0cac6632dd395fcf024361 100644
index 2d97ca1f3c625c0206d35b785c57d9587924ed0a..e079f4db4e4738f60a6fdbdbf5e4d1baf593a62f 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -861,6 +861,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -813,6 +813,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
entityplayer.stopSleepInBed(false, false);
});
}
@ -104,7 +104,7 @@ index 3a49f8933bc6ca1862994b7e0b3006f5236dd94a..bdad61438e7fd89f5f0cac6632dd395f
public void tickChunk(LevelChunk chunk, int randomTickSpeed) {
ChunkPos chunkcoordintpair = chunk.getPos();
@@ -870,8 +874,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -822,8 +826,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
ProfilerFiller gameprofilerfiller = this.getProfiler();
gameprofilerfiller.push("thunder");
@ -116,7 +116,7 @@ index 3a49f8933bc6ca1862994b7e0b3006f5236dd94a..bdad61438e7fd89f5f0cac6632dd395f
if (this.isRainingAt(blockposition)) {
DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
@@ -903,7 +909,10 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -855,7 +861,10 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow
for (int l = 0; l < randomTickSpeed; ++l) {
if (this.random.nextInt(48) == 0) {
@ -128,7 +128,7 @@ index 3a49f8933bc6ca1862994b7e0b3006f5236dd94a..bdad61438e7fd89f5f0cac6632dd395f
}
}
} // Paper - Option to disable ice and snow
@@ -911,36 +920,37 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -863,36 +872,37 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
gameprofilerfiller.popPush("tickBlocks");
timings.chunkTicksBlocks.startTiming(); // Paper
if (randomTickSpeed > 0) {
@ -190,7 +190,7 @@ index 3a49f8933bc6ca1862994b7e0b3006f5236dd94a..bdad61438e7fd89f5f0cac6632dd395f
timings.chunkTicksBlocks.stopTiming(); // Paper
gameprofilerfiller.pop();
@@ -948,17 +958,25 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -900,17 +910,25 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
@VisibleForTesting
public void tickPrecipitation(BlockPos pos) {
@ -220,7 +220,7 @@ index 3a49f8933bc6ca1862994b7e0b3006f5236dd94a..bdad61438e7fd89f5f0cac6632dd395f
if (i > 0 && biomebase.shouldSnow(this, blockposition1)) {
BlockState iblockdata = this.getBlockState(blockposition1);
@@ -976,12 +994,13 @@ public class ServerLevel extends Level implements WorldGenLevel {
@@ -928,12 +946,13 @@ public class ServerLevel extends Level implements WorldGenLevel, ca.spottedleaf.
}
}
@ -311,7 +311,7 @@ index 50040c497a819cd1229042ab3cb057d34a32cacc..01f5b946fabbe34f31110e75973dab9f
public void getAll(IntConsumer action) {
for (int i = 0; i < this.size; i++) {
diff --git a/src/main/java/net/minecraft/world/entity/animal/Turtle.java b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
index ffffa53fcaa6ec8681b283fa20bb5a3320ad9c11..30b87b5cb18c25cdd04eab64cfbe5acd6c1b6d84 100644
index 4bfa947531c4a67989e18032754dabf4c69e989c..caf4120721be8f2f7e2d737abbf73296cbe170b5 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
@@ -88,7 +88,7 @@ public class Turtle extends Animal {
@ -324,10 +324,10 @@ index ffffa53fcaa6ec8681b283fa20bb5a3320ad9c11..30b87b5cb18c25cdd04eab64cfbe5acd
public BlockPos getHomePos() {
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index dab55ab08665f2b5ae0c899a4ab07c18460552ae..4001bec504b8fcda1eec03f49abd4e4d82cf6336 100644
index 0ef67317a922f28202c84c7a1f81f3c534d2b838..81f28afeea34d5e4ebb7f8fa7e3f5f124069a5ab 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -1387,10 +1387,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
@@ -1500,10 +1500,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
public abstract RecipeManager getRecipeManager();
public BlockPos getBlockRandomPos(int x, int y, int z, int l) {

View file

@ -262,7 +262,7 @@ index 7d2896918ff5fed37e5de5a22c37b0c7f32634a8..7d82cc6b847124cf4225428ba3103095
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 3d30427e75bdfb9cf453fb5cd2a344227da1641a..ef177f21d654d69c128f3f39ea58f2d8ee598628 100644
index bad83045ff9409678a0699cdc0781efd8ef30a44..22c705e4e3f852102c46ae0c885feb1b085545b6 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -604,7 +604,7 @@ public abstract class PlayerList {
@ -287,10 +287,10 @@ index 2510589400b3012b827efcab477c6483d9d55901..43487a9ee202c5b0e5a416519939111f
}
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 06e9fc703b0ef722cc21a365203a561009047d23..fa6b8ce6505a3c094187298a63b0e944e1e74af1 100644
index 81f28afeea34d5e4ebb7f8fa7e3f5f124069a5ab..0d202ce8eb88bfdb8ca3306593d758fa483d8612 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -992,6 +992,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
@@ -994,6 +994,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable, ca.spottedl
try {
tickConsumer.accept(entity);
} catch (Throwable throwable) {

View file

@ -1,243 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sat, 15 Jun 2019 08:54:33 -0700
Subject: [PATCH] Fix World#isChunkGenerated calls
Optimize World#loadChunk() too
This patch also adds a chunk status cache on region files (note that
its only purpose is to cache the status on DISK)
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index d6ecee1db17cb9eaeffa94b3d8dd150238fdefe5..1d2d4d38ff3414896d07f7f4e40d0edb9a8c3993 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -735,9 +735,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end
private CompletableFuture<Optional<CompoundTag>> readChunk(ChunkPos chunkPos) {
- return this.read(chunkPos).thenApplyAsync((optional) -> {
- return optional.map((nbttagcompound) -> this.upgradeChunkTag(nbttagcompound, chunkPos)); // CraftBukkit
- }, Util.backgroundExecutor());
+ // Paper start - Cache chunk status on disk
+ try {
+ return CompletableFuture.completedFuture(Optional.ofNullable(this.readConvertChunkSync(chunkPos)));
+ } catch (Throwable thr) {
+ return CompletableFuture.failedFuture(thr);
+ }
+ // Paper end - Cache chunk status on disk
}
// CraftBukkit start
@@ -746,6 +750,60 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// CraftBukkit end
}
+ // Paper start - Cache chunk status on disk
+ @Nullable
+ public CompoundTag readConvertChunkSync(ChunkPos pos) throws IOException {
+ CompoundTag nbttagcompound = this.readSync(pos);
+ if (nbttagcompound == null) {
+ return null;
+ }
+
+ nbttagcompound = this.upgradeChunkTag(nbttagcompound, pos); // CraftBukkit
+ if (nbttagcompound == null) {
+ return null;
+ }
+
+ this.updateChunkStatusOnDisk(pos, nbttagcompound);
+
+ return nbttagcompound;
+ }
+
+ public ChunkStatus getChunkStatusOnDiskIfCached(ChunkPos chunkPos) {
+ net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFileIfLoaded(chunkPos);
+
+ return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
+ }
+
+ public ChunkStatus getChunkStatusOnDisk(ChunkPos chunkPos) throws IOException {
+ net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFile(chunkPos, true);
+
+ if (regionFile == null || !regionFileCache.chunkExists(chunkPos)) {
+ return null;
+ }
+
+ ChunkStatus status = regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
+
+ if (status != null) {
+ return status;
+ }
+
+ this.readChunk(chunkPos);
+
+ return regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
+ }
+
+ public void updateChunkStatusOnDisk(ChunkPos chunkPos, @Nullable CompoundTag compound) throws IOException {
+ net.minecraft.world.level.chunk.storage.RegionFile regionFile = regionFileCache.getRegionFile(chunkPos, false);
+
+ regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkSerializer.getStatus(compound));
+ }
+
+ public ChunkAccess getUnloadingChunk(int chunkX, int chunkZ) {
+ ChunkHolder chunkHolder = io.papermc.paper.chunk.system.ChunkSystem.getUnloadingChunkHolder(this.level, chunkX, chunkZ);
+ return chunkHolder == null ? null : chunkHolder.getAvailableChunkNow();
+ }
+ // Paper end - Cache chunk status on disk
+
public boolean anyPlayerCloseEnoughForSpawning(ChunkPos pos) { // Paper - public
// Spigot start
return this.anyPlayerCloseEnoughForSpawning(pos, false);
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
index f994f91dd4b4a0a6d540a5605af0b6623e229f84..cf43daa019b239464401784938d01af83f9da47c 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
@@ -52,6 +52,29 @@ public class RegionFile implements AutoCloseable {
@VisibleForTesting
protected final RegionBitmap usedSectors;
public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(); // Paper
+ // Paper start - Cache chunk status
+ private final net.minecraft.world.level.chunk.status.ChunkStatus[] statuses = new net.minecraft.world.level.chunk.status.ChunkStatus[32 * 32];
+
+ private boolean closed;
+
+ // invoked on write/read
+ public void setStatus(int x, int z, net.minecraft.world.level.chunk.status.ChunkStatus status) {
+ if (this.closed) {
+ // We've used an invalid region file.
+ throw new IllegalStateException("RegionFile is closed");
+ }
+ this.statuses[getChunkLocation(x, z)] = status;
+ }
+
+ public net.minecraft.world.level.chunk.status.ChunkStatus getStatusIfCached(int x, int z) {
+ if (this.closed) {
+ // We've used an invalid region file.
+ throw new IllegalStateException("RegionFile is closed");
+ }
+ final int location = getChunkLocation(x, z);
+ return this.statuses[location];
+ }
+ // Paper end - Cache chunk status
public RegionFile(RegionStorageInfo storageKey, Path directory, Path path, boolean dsync) throws IOException {
this(storageKey, directory, path, RegionFileVersion.getCompressionFormat(), dsync); // Paper - Configurable region compression format
@@ -417,6 +440,7 @@ public class RegionFile implements AutoCloseable {
return this.getOffset(pos) != 0;
}
+ private static int getChunkLocation(int x, int z) { return (x & 31) + (z & 31) * 32; } // Paper - Cache chunk status; OBFHELPER - sort of, mirror of logic below
private static int getOffsetIndex(ChunkPos pos) {
return pos.getRegionLocalX() + pos.getRegionLocalZ() * 32;
}
@@ -427,6 +451,7 @@ public class RegionFile implements AutoCloseable {
synchronized (this) {
try {
// Paper end
+ this.closed = true; // Paper - Cache chunk status
try {
this.padToFullSector();
} finally {
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
index c2838ae91b7f078369b63503df57a1eb5d2b0df5..c33640859aab837c85f3e860fe2241a0e78bb09a 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -268,6 +268,7 @@ public class RegionFileStorage implements AutoCloseable {
try {
NbtIo.write(nbt, (DataOutput) dataoutputstream);
+ regionfile.setStatus(pos.x, pos.z, ChunkSerializer.getStatus(nbt)); // Paper - Cache chunk status
regionfile.setOversized(pos.x, pos.z, false); // Paper - We don't do this anymore, mojang stores differently, but clear old meta flag if it exists to get rid of our own meta file once last oversized is gone
// Paper start - don't write garbage data to disk if writing serialization fails
dataoutputstream.close(); // Only write if successful
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 9c06c3729b09726e1da6ff8fb975cef2aeba9643..8f50d893f8f9dea306756b640abd2373ee028a86 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -391,9 +391,23 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public boolean isChunkGenerated(int x, int z) {
+ // Paper start - Fix this method
+ if (!Bukkit.isPrimaryThread()) {
+ return java.util.concurrent.CompletableFuture.supplyAsync(() -> {
+ return CraftWorld.this.isChunkGenerated(x, z);
+ }, world.getChunkSource().mainThreadProcessor).join();
+ }
+ ChunkAccess chunk = world.getChunkSource().getChunkAtImmediately(x, z);
+ if (chunk == null) {
+ chunk = world.getChunkSource().chunkMap.getUnloadingChunk(x, z);
+ }
+ if (chunk != null) {
+ return chunk instanceof ImposterProtoChunk || chunk instanceof net.minecraft.world.level.chunk.LevelChunk;
+ }
try {
- return this.isChunkLoaded(x, z) || this.world.getChunkSource().chunkMap.read(new ChunkPos(x, z)).get().isPresent();
- } catch (InterruptedException | ExecutionException ex) {
+ return world.getChunkSource().chunkMap.getChunkStatusOnDisk(new ChunkPos(x, z)) == ChunkStatus.FULL;
+ } catch (java.io.IOException ex) {
+ // Paper end - Fix this method
throw new RuntimeException(ex);
}
}
@@ -572,20 +586,48 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public boolean loadChunk(int x, int z, boolean generate) {
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
warnUnsafeChunk("loading a faraway chunk", x, z); // Paper
- ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
-
- // If generate = false, but the chunk already exists, we will get this back.
- if (chunk instanceof ImposterProtoChunk) {
- // We then cycle through again to get the full chunk immediately, rather than after the ticket addition
- chunk = this.world.getChunkSource().getChunk(x, z, ChunkStatus.FULL, true);
- }
-
- if (chunk instanceof net.minecraft.world.level.chunk.LevelChunk) {
- this.world.getChunkSource().addRegionTicket(TicketType.PLUGIN, new ChunkPos(x, z), 0, Unit.INSTANCE); // Paper
+ // Paper start - Optimize this method
+ ChunkPos chunkPos = new ChunkPos(x, z);
+ ChunkAccess immediate = world.getChunkSource().getChunkAtIfLoadedImmediately(x, z);
+ if (immediate != null) {
+ // Plugins should use plugin tickets instead of this method to keep a chunk perpetually loaded
return true;
}
- return false;
+ if (!generate) {
+ immediate = world.getChunkSource().chunkMap.getUnloadingChunk(x, z);
+ if (immediate != null) {
+ if (!(immediate instanceof ImposterProtoChunk) && !(immediate instanceof net.minecraft.world.level.chunk.LevelChunk)) {
+ return false; // not full status
+ }
+ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper
+ world.getChunk(x, z); // make sure we're at ticket level 32 or lower
+ return true;
+ }
+ net.minecraft.world.level.chunk.storage.RegionFile file;
+ try {
+ file = world.getChunkSource().chunkMap.regionFileCache.getRegionFile(chunkPos, false);
+ } catch (java.io.IOException ex) {
+ throw new RuntimeException(ex);
+ }
+
+ ChunkStatus status = file.getStatusIfCached(x, z);
+ if (!file.hasChunk(chunkPos) || (status != null && status != ChunkStatus.FULL)) {
+ return false;
+ }
+
+ ChunkAccess chunk = world.getChunkSource().getChunk(x, z, ChunkStatus.EMPTY, true);
+ if (!(chunk instanceof ImposterProtoChunk) && !(chunk instanceof net.minecraft.world.level.chunk.LevelChunk)) {
+ return false;
+ }
+
+ // fall through to load
+ // we do this so we do not re-read the chunk data on disk
+ }
+ world.getChunkSource().addRegionTicket(TicketType.PLUGIN, chunkPos, 0, Unit.INSTANCE); // Paper
+ world.getChunkSource().getChunk(x, z, ChunkStatus.FULL, true);
+ return true;
+ // Paper end - Optimize this method
}
@Override

View file

@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 2 Aug 2021 10:10:40 +0200
Subject: [PATCH] Improve boat collision performance
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index 2cd0a4dc4f0baa08bd7f5a053303bb63733f0bab..0bd367235f80c1f0d319a6aa5130d82ad82d895c 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -125,6 +125,7 @@ public class Util {
.filter(fileSystemProvider -> fileSystemProvider.getScheme().equalsIgnoreCase("jar"))
.findFirst()
.orElseThrow(() -> new IllegalStateException("No jar file system provider found"));
+ public static final double COLLISION_EPSILON = 1.0E-7; // Paper - Improve boat collision performance
private static Consumer<String> thePauser = message -> {
};
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 56351d5c2b4ea2c1b335253153cedafdf058d9ae..9601d3def5e4ac0650bae42a1da2a64ab1e5aef7 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1459,7 +1459,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (!source.is(DamageTypeTags.IS_PROJECTILE)) {
Entity entity = source.getDirectEntity();
- if (entity instanceof LivingEntity) {
+ if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Improve boat collision performance
LivingEntity entityliving = (LivingEntity) entity;
this.blockUsingShield(entityliving);
@@ -1553,11 +1553,12 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
if (entity1 != null && !source.is(DamageTypeTags.NO_KNOCKBACK)) {
- double d0 = entity1.getX() - this.getX();
+ final boolean far = entity1.distanceToSqr(this) > (200.0 * 200.0); // Paper - Improve boat collision performance
+ double d0 = far ? (Math.random() - Math.random()) : entity1.getX() - this.getX(); // Paper - Improve boat collision performance
double d1;
- for (d1 = entity1.getZ() - this.getZ(); d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) {
+ for (d1 = far ? Math.random() - Math.random() : entity1.getZ() - this.getZ(); d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) { // Paper - Improve boat collision performance
d0 = (Math.random() - Math.random()) * 0.01D;
}
@@ -2324,7 +2325,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING));
Entity entity = damagesource.getDirectEntity();
- if (entity instanceof LivingEntity) {
+ if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper - Improve boat collision performance
this.blockUsingShield((LivingEntity) entity);
}
}
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
index 549202706396fee91c23f6e34f7faa7672e4b03f..b068cff9b5aa457d65b679529956e8210296d799 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
@@ -686,7 +686,7 @@ public class Boat extends VehicleEntity implements VariantHolder<Boat.Type> {
this.invFriction = 0.05F;
if (this.oldStatus == Boat.Status.IN_AIR && this.status != Boat.Status.IN_AIR && this.status != Boat.Status.ON_LAND) {
this.waterLevel = this.getY(1.0D);
- this.setPos(this.getX(), (double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D, this.getZ());
+ this.move(MoverType.SELF, new Vec3(0.0, ((double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D) - this.getY(), 0.0)); // Paper - Improve boat collision performance
this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
this.lastYd = 0.0D;
this.status = Boat.Status.IN_WATER;

View file

@ -1,176 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 6 Apr 2020 04:20:44 -0700
Subject: [PATCH] Execute chunk tasks mid-tick
This will help the server load chunks if tick times are high.
diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java
index 6b3cde6d4d1e63bec01f502f2027ee9fddac08aa..46449728f69ee7d4f78470f8da23c055acd53a3b 100644
--- a/src/main/java/co/aikar/timings/MinecraftTimings.java
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
@@ -48,6 +48,8 @@ public final class MinecraftTimings {
public static final Timing antiXrayObfuscateTimer = Timings.ofSafe("anti-xray - obfuscate");
public static final Timing scoreboardScoreSearch = Timings.ofSafe("Scoreboard score search"); // Paper - add timings for scoreboard search
+ public static final Timing midTickChunkTasks = Timings.ofSafe("Mid Tick Chunk Tasks");
+
private static final Map<Class<?>, String> taskNameCache = new MapMaker().weakKeys().makeMap();
private MinecraftTimings() {}
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 03552ca486807d057147f6a05f024989d593d046..64ae2745c3144d43cad12dfe9baf1a291756d129 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -1411,8 +1411,79 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
return flag;
}
+ // Paper start - execute chunk tasks mid tick
+ static final long CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME = 25L * 1000L; // 25us
+ static final long MAX_CHUNK_EXEC_TIME = 1000L; // 1us
+
+ static final long TASK_EXECUTION_FAILURE_BACKOFF = 5L * 1000L; // 5us
+
+ private static long lastMidTickExecute;
+ private static long lastMidTickExecuteFailure;
+
+ private boolean tickMidTickTasks() {
+ // give all worlds a fair chance at by targetting them all.
+ // if we execute too many tasks, that's fine - we have logic to correctly handle overuse of allocated time.
+ boolean executed = false;
+ for (ServerLevel world : this.getAllLevels()) {
+ long currTime = System.nanoTime();
+ if (currTime - world.lastMidTickExecuteFailure <= TASK_EXECUTION_FAILURE_BACKOFF) {
+ continue;
+ }
+ if (!world.getChunkSource().pollTask()) {
+ // we need to back off if this fails
+ world.lastMidTickExecuteFailure = currTime;
+ } else {
+ executed = true;
+ }
+ }
+
+ return executed;
+ }
+
+ public final void executeMidTickTasks() {
+ org.spigotmc.AsyncCatcher.catchOp("mid tick chunk task execution");
+ long startTime = System.nanoTime();
+ if ((startTime - lastMidTickExecute) <= CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME || (startTime - lastMidTickExecuteFailure) <= TASK_EXECUTION_FAILURE_BACKOFF) {
+ // it's shown to be bad to constantly hit the queue (chunk loads slow to a crawl), even if no tasks are executed.
+ // so, backoff to prevent this
+ return;
+ }
+
+ co.aikar.timings.MinecraftTimings.midTickChunkTasks.startTiming();
+ try {
+ for (;;) {
+ boolean moreTasks = this.tickMidTickTasks();
+ long currTime = System.nanoTime();
+ long diff = currTime - startTime;
+
+ if (!moreTasks || diff >= MAX_CHUNK_EXEC_TIME) {
+ if (!moreTasks) {
+ lastMidTickExecuteFailure = currTime;
+ }
+
+ // note: negative values reduce the time
+ long overuse = diff - MAX_CHUNK_EXEC_TIME;
+ if (overuse >= (10L * 1000L * 1000L)) { // 10ms
+ // make sure something like a GC or dumb plugin doesn't screw us over...
+ overuse = 10L * 1000L * 1000L; // 10ms
+ }
+
+ double overuseCount = (double)overuse/(double)MAX_CHUNK_EXEC_TIME;
+ long extraSleep = (long)Math.round(overuseCount*CHUNK_TASK_QUEUE_BACKOFF_MIN_TIME);
+
+ lastMidTickExecute = currTime + extraSleep;
+ return;
+ }
+ }
+ } finally {
+ co.aikar.timings.MinecraftTimings.midTickChunkTasks.stopTiming();
+ }
+ }
+ // Paper end - execute chunk tasks mid tick
+
private boolean pollTaskInternal() {
if (super.pollTask()) {
+ this.executeMidTickTasks(); // Paper - execute chunk tasks mid tick
return true;
} else {
boolean ret = false; // Paper - force execution of all worlds, do not just bias the first
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 6b258a2bd85bb71b030d42b488e1a4742d1e147d..01577dbb16ff6abc9edcf897f7fadaad14350184 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -559,6 +559,7 @@ public class ServerChunkCache extends ChunkSource {
boolean flag1 = this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) != 0L && this.level.getLevelData().getGameTime() % this.level.ticksPerSpawnCategory.getLong(org.bukkit.entity.SpawnCategory.ANIMAL) == 0L; // CraftBukkit
Iterator iterator1 = list.iterator();
+ int chunksTicked = 0; // Paper
while (iterator1.hasNext()) {
ServerChunkCache.ChunkAndHolder chunkproviderserver_a = (ServerChunkCache.ChunkAndHolder) iterator1.next();
LevelChunk chunk1 = chunkproviderserver_a.chunk;
@@ -572,6 +573,7 @@ public class ServerChunkCache extends ChunkSource {
if (this.level.shouldTickBlocksAt(chunkcoordintpair.toLong())) {
this.level.tickChunk(chunk1, l);
+ if ((chunksTicked++ & 1) == 0) net.minecraft.server.MinecraftServer.getServer().executeMidTickTasks(); // Paper
}
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 1ec7865e2e2bd23607e9b3041d77bd4badf39a4a..3a49f8933bc6ca1862994b7e0b3006f5236dd94a 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -221,6 +221,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
private final StructureCheck structureCheck;
private final boolean tickTime;
private final RandomSequences randomSequences;
+ public long lastMidTickExecuteFailure; // Paper - execute chunk tasks mid tick
// CraftBukkit start
public final LevelStorageSource.LevelStorageAccess convertable;
@@ -1211,6 +1212,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (fluid1.is(fluid)) {
fluid1.tick(this, pos);
}
+ MinecraftServer.getServer().executeMidTickTasks(); // Paper - exec chunk tasks during world tick
}
@@ -1220,6 +1222,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (iblockdata.is(block)) {
iblockdata.tick(this, pos, this.random);
}
+ MinecraftServer.getServer().executeMidTickTasks(); // Paper - exec chunk tasks during world tick
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index d3d7abb2d31e8ce9f9c53eca66a83a1c28fec792..dab55ab08665f2b5ae0c899a4ab07c18460552ae 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -915,6 +915,11 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
// Spigot end
} else if (flag && this.shouldTickBlocksAt(tickingblockentity.getPos())) {
tickingblockentity.tick();
+ // Paper start - execute chunk tasks during tick
+ if ((this.tileTickPosition & 7) == 0) {
+ MinecraftServer.getServer().executeMidTickTasks();
+ }
+ // Paper end - execute chunk tasks during tick
}
}
this.blockEntityTickers.removeAll(toRemove); // Paper - Fix MC-117075
@@ -929,6 +934,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public <T extends Entity> void guardEntityTick(Consumer<T> tickConsumer, T entity) {
try {
tickConsumer.accept(entity);
+ MinecraftServer.getServer().executeMidTickTasks(); // Paper - execute chunk tasks mid tick
} catch (Throwable throwable) {
if (throwable instanceof ThreadDeath) throw throwable; // Paper
// Paper start - Prevent block entity and entity crashes

View file

@ -8,7 +8,7 @@ Move collision logic to just the hasNewCollision call instead of getCubes + hasN
CHECK ME
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 34d4243fb5198e36ea3291ffe8ed2480bc960cdb..56d32a919cff2a9d4a5775665ed4d1d14b9c708b 100644
index 7796e191747be545e744564a2b0b65790f69114d..2b94b2dc3f29e7005b1a30c83f4a68e1263780b4 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -572,7 +572,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@ -55,7 +55,7 @@ index 34d4243fb5198e36ea3291ffe8ed2480bc960cdb..56d32a919cff2a9d4a5775665ed4d1d1
entity.absMoveTo(d0, d1, d2, f, f1);
this.player.absMoveTo(d0, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit
this.send(new ClientboundMoveVehiclePacket(entity));
@@ -688,7 +697,32 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -691,7 +700,32 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
private boolean noBlocksAround(Entity entity) {
@ -89,16 +89,7 @@ index 34d4243fb5198e36ea3291ffe8ed2480bc960cdb..56d32a919cff2a9d4a5775665ed4d1d1
}
@Override
@@ -1283,7 +1317,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
if (this.awaitingPositionFromClient != null) {
- if (this.tickCount - this.awaitingTeleportTime > 20) {
+ if (false && this.tickCount - this.awaitingTeleportTime > 20) { // Paper - this will greatly screw with clients with > 1000ms RTT
this.awaitingTeleportTime = this.tickCount;
this.teleport(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot());
}
@@ -1392,7 +1426,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1387,7 +1421,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
}
@ -107,7 +98,7 @@ index 34d4243fb5198e36ea3291ffe8ed2480bc960cdb..56d32a919cff2a9d4a5775665ed4d1d1
d6 = d0 - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above
d7 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above
@@ -1434,6 +1468,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1429,6 +1463,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
this.player.move(MoverType.PLAYER, new Vec3(d6, d7, d8));
this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
@ -115,7 +106,7 @@ index 34d4243fb5198e36ea3291ffe8ed2480bc960cdb..56d32a919cff2a9d4a5775665ed4d1d1
// Paper start - prevent position desync
if (this.awaitingPositionFromClient != null) {
return; // ... thanks Mojang for letting move calls teleport across dimensions.
@@ -1464,7 +1499,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1459,7 +1494,17 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
// Paper start - Add fail move event
@ -134,7 +125,16 @@ index 34d4243fb5198e36ea3291ffe8ed2480bc960cdb..56d32a919cff2a9d4a5775665ed4d1d1
if (teleportBack) {
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
toX, toY, toZ, toYaw, toPitch, false);
@@ -1570,6 +1615,33 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
@@ -1570,7 +1615,7 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
private boolean updateAwaitingTeleport() {
if (this.awaitingPositionFromClient != null) {
- if (this.tickCount - this.awaitingTeleportTime > 20) {
+ if (false && this.tickCount - this.awaitingTeleportTime > 20) { // Paper - this will greatly screw with clients with > 1000ms RTT
this.awaitingTeleportTime = this.tickCount;
this.teleport(this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, this.player.getYRot(), this.player.getXRot());
}
@@ -1583,6 +1628,33 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
}
}

View file

@ -34,10 +34,10 @@ The results indicate that this logic is 5 times faster than Vanilla
and 2.3 times faster than Lithium.
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
index ef40b996864c81d7e8fbb0727ea0a96f866c725f..638447e8cb74b26f4f8e3862c2fb4a3048979ebc 100644
index bff83fe413c7baef4ba56a3270ea4463a58c792f..7aa9ddb1d61ffb7da3f867e5a5bd04e3432b5621 100644
--- a/src/main/java/net/minecraft/world/level/Explosion.java
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
@@ -112,6 +112,271 @@ public class Explosion {
@@ -113,6 +113,271 @@ public class Explosion {
this.yield = this.blockInteraction == Explosion.BlockInteraction.DESTROY_WITH_DECAY ? 1.0F / this.radius : 1.0F; // CraftBukkit
}
@ -309,7 +309,7 @@ index ef40b996864c81d7e8fbb0727ea0a96f866c725f..638447e8cb74b26f4f8e3862c2fb4a30
private ExplosionDamageCalculator makeDamageCalculator(@Nullable Entity entity) {
return (ExplosionDamageCalculator) (entity == null ? Explosion.EXPLOSION_DAMAGE_CALCULATOR : new EntityBasedExplosionDamageCalculator(entity));
}
@@ -172,40 +437,88 @@ public class Explosion {
@@ -173,40 +438,88 @@ public class Explosion {
int i;
int j;
@ -420,7 +420,7 @@ index ef40b996864c81d7e8fbb0727ea0a96f866c725f..638447e8cb74b26f4f8e3862c2fb4a30
set.add(blockposition);
// Paper start - prevent headless pistons from forming
if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowHeadlessPistons && iblockdata.getBlock() == Blocks.MOVING_PISTON) {
@@ -216,11 +529,12 @@ public class Explosion {
@@ -217,11 +530,12 @@ public class Explosion {
}
}
// Paper end - prevent headless pistons from forming
@ -436,7 +436,7 @@ index ef40b996864c81d7e8fbb0727ea0a96f866c725f..638447e8cb74b26f4f8e3862c2fb4a30
}
}
}
@@ -240,6 +554,8 @@ public class Explosion {
@@ -241,6 +555,8 @@ public class Explosion {
Vec3 vec3d = new Vec3(this.x, this.y, this.z);
Iterator iterator = list.iterator();
@ -445,7 +445,7 @@ index ef40b996864c81d7e8fbb0727ea0a96f866c725f..638447e8cb74b26f4f8e3862c2fb4a30
while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next();
@@ -275,11 +591,11 @@ public class Explosion {
@@ -276,11 +592,11 @@ public class Explosion {
for (EnderDragonPart entityComplexPart : ((EnderDragon) entity).subEntities) {
// Calculate damage separately for each EntityComplexPart
if (list.contains(entityComplexPart)) {
@ -459,7 +459,7 @@ index ef40b996864c81d7e8fbb0727ea0a96f866c725f..638447e8cb74b26f4f8e3862c2fb4a30
}
if (entity.lastDamageCancelled) { // SPIGOT-5339, SPIGOT-6252, SPIGOT-6777: Skip entity if damage event was cancelled
@@ -288,7 +604,7 @@ public class Explosion {
@@ -289,7 +605,7 @@ public class Explosion {
// CraftBukkit end
}
@ -468,7 +468,7 @@ index ef40b996864c81d7e8fbb0727ea0a96f866c725f..638447e8cb74b26f4f8e3862c2fb4a30
double d13;
if (entity instanceof LivingEntity) {
@@ -327,6 +643,9 @@ public class Explosion {
@@ -328,6 +644,9 @@ public class Explosion {
}
}
@ -478,7 +478,7 @@ index ef40b996864c81d7e8fbb0727ea0a96f866c725f..638447e8cb74b26f4f8e3862c2fb4a30
}
public void finalizeExplosion(boolean particles) {
@@ -542,14 +861,14 @@ public class Explosion {
@@ -547,14 +866,14 @@ public class Explosion {
private BlockInteraction() {}
}
// Paper start - Optimize explosions