mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 03:17:36 +01:00
42433c2626
Upstream has released updates that appears to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 09f10fd9 SPIGOT-5950: Add PrepareSmithingEvent event CraftBukkit Changes:7c03d257
SPIGOT-6011: End Gateways do not work on Non-Main End Worldsd492e363
SPIGOT-6015: Small Armor Stand doesn't drop items5db13eea
SPIGOT-5950: Add PrepareSmithingEvent event
136 lines
8.1 KiB
Diff
136 lines
8.1 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Thu, 2 Apr 2020 02:37:57 -0400
|
|
Subject: [PATCH] Optimize Collision to not load chunks
|
|
|
|
The collision code takes an AABB and generates a cuboid of checks rather
|
|
than a cylinder, so at high velocity this can generate a lot of chunk checks.
|
|
|
|
Treat an unloaded chunk as a collision for entities, and also for players if
|
|
the "prevent moving into unloaded chunks" setting is enabled.
|
|
|
|
If that serting is not enabled, collisions will be ignored for players, since
|
|
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/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
|
index e895bf811ce5d441541725ade48e3f07ca86fc2b..152f613159ef88977de867c0deec94bfa4353f7a 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -80,6 +80,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
private CraftEntity bukkitEntity;
|
|
|
|
PlayerChunkMap.EntityTracker tracker; // Paper
|
|
+ boolean collisionLoadChunks = false; // Paper
|
|
Throwable addedToWorldStack; // Paper - entity debug
|
|
public CraftEntity getBukkitEntity() {
|
|
if (bukkitEntity == null) {
|
|
diff --git a/src/main/java/net/minecraft/server/ICollisionAccess.java b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
|
index b27260270de80de371a5a71fa0516aa43c44c83e..1cc40b1f0af9e617b2a71bcc442543e10b2dc61a 100644
|
|
--- a/src/main/java/net/minecraft/server/ICollisionAccess.java
|
|
+++ b/src/main/java/net/minecraft/server/ICollisionAccess.java
|
|
@@ -46,7 +46,9 @@ public interface ICollisionAccess extends IBlockAccess {
|
|
}
|
|
|
|
default boolean b(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate<Entity> predicate) {
|
|
+ try { if (entity != null) entity.collisionLoadChunks = true; // Paper
|
|
return this.d(entity, axisalignedbb, predicate).allMatch(VoxelShape::isEmpty);
|
|
+ } finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper
|
|
}
|
|
|
|
Stream<VoxelShape> c(@Nullable Entity entity, AxisAlignedBB axisalignedbb, Predicate<Entity> predicate);
|
|
diff --git a/src/main/java/net/minecraft/server/PlayerList.java b/src/main/java/net/minecraft/server/PlayerList.java
|
|
index 15a12ebc266c54d2b29f368fc31df76b994b28ae..f0caadb6117d761e6ce0ee573e2c351b894a00c2 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerList.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerList.java
|
|
@@ -722,6 +722,7 @@ public abstract class PlayerList {
|
|
entityplayer1.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
|
// CraftBukkit end
|
|
|
|
+ worldserver1.getChunkProvider().addTicket(TicketType.POST_TELEPORT, new ChunkCoordIntPair(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
|
|
while (avoidSuffocation && !worldserver1.getCubes(entityplayer1) && entityplayer1.locY() < 256.0D) {
|
|
entityplayer1.setPosition(entityplayer1.locX(), entityplayer1.locY() + 1.0D, entityplayer1.locZ());
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java
|
|
index 4967d1ebd109c462a322e4829d01ff519d1b5366..ed0f3ddbcb7d6ce8a59ae3829f4cb11ae75046cb 100644
|
|
--- a/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java
|
|
+++ b/src/main/java/net/minecraft/server/VoxelShapeSpliterator.java
|
|
@@ -9,13 +9,13 @@ import javax.annotation.Nullable;
|
|
public class VoxelShapeSpliterator extends AbstractSpliterator<VoxelShape> {
|
|
|
|
@Nullable
|
|
- private final Entity a;
|
|
+ private final Entity a; final Entity getEntity() { return this.a; } // Paper - OBFHELPER
|
|
private final AxisAlignedBB b;
|
|
private final VoxelShapeCollision c;
|
|
private final CursorPosition d;
|
|
- private final BlockPosition.MutableBlockPosition e;
|
|
+ private final BlockPosition.MutableBlockPosition e; final BlockPosition.MutableBlockPosition getMutablePos() { return this.e; } // Paper - OBFHELPER
|
|
private final VoxelShape f;
|
|
- private final ICollisionAccess g;
|
|
+ private final ICollisionAccess g; final ICollisionAccess getCollisionAccess() { return this.g; } // Paper - OBFHELPER
|
|
private boolean h;
|
|
private final BiPredicate<IBlockData, BlockPosition> i;
|
|
|
|
@@ -52,23 +52,37 @@ public class VoxelShapeSpliterator extends AbstractSpliterator<VoxelShape> {
|
|
boolean a(Consumer<? super VoxelShape> consumer) {
|
|
while (true) {
|
|
if (this.d.a()) {
|
|
- int i = this.d.b();
|
|
- int j = this.d.c();
|
|
- int k = this.d.d();
|
|
+ int i = this.d.b(); final int x = i;
|
|
+ int j = this.d.c(); final int y = j;
|
|
+ int k = this.d.d(); final int z = k;
|
|
int l = this.d.e();
|
|
|
|
if (l == 3) {
|
|
continue;
|
|
}
|
|
|
|
- IBlockAccess iblockaccess = this.a(i, k);
|
|
-
|
|
- if (iblockaccess == null) {
|
|
+ // Paper start - ensure we don't load chunks
|
|
+ Entity entity = this.getEntity();
|
|
+ BlockPosition.MutableBlockPosition blockposition_mutableblockposition = this.getMutablePos();
|
|
+ boolean far = entity != null && MCUtil.distanceSq(entity.locX(), y, entity.locZ(), x, y, z) > 14;
|
|
+ blockposition_mutableblockposition.setValues(x, y, z);
|
|
+
|
|
+ boolean isRegionLimited = this.getCollisionAccess() instanceof RegionLimitedWorldAccess;
|
|
+ IBlockData iblockdata = isRegionLimited ? Blocks.VOID_AIR.getBlockData() : ((!far && entity instanceof EntityPlayer) || (entity != null && entity.collisionLoadChunks)
|
|
+ ? this.getCollisionAccess().getType(blockposition_mutableblockposition)
|
|
+ : this.getCollisionAccess().getTypeIfLoaded(blockposition_mutableblockposition)
|
|
+ );
|
|
+
|
|
+ if (iblockdata == null) {
|
|
+ if (!(entity instanceof EntityPlayer) || entity.world.paperConfig.preventMovingIntoUnloadedChunks) {
|
|
+ VoxelShape voxelshape3 = VoxelShapes.of(far ? entity.getBoundingBox() : new AxisAlignedBB(new BlockPosition(x, y, z)));
|
|
+ consumer.accept(voxelshape3);
|
|
+ return true;
|
|
+ }
|
|
continue;
|
|
}
|
|
-
|
|
- this.e.d(i, j, k);
|
|
- IBlockData iblockdata = iblockaccess.getType(this.e);
|
|
+ // Paper - moved up
|
|
+ // Paper end
|
|
|
|
if (!this.i.test(iblockdata, this.e) || l == 1 && !iblockdata.d() || l == 2 && !iblockdata.a(Blocks.MOVING_PISTON)) {
|
|
continue;
|
|
diff --git a/src/main/java/net/minecraft/server/VoxelShapes.java b/src/main/java/net/minecraft/server/VoxelShapes.java
|
|
index b6e2a3d8d0cf510f497c6f974356fafaf2adc13b..4acde367542247627574fdeb586fb8c9087eef1a 100644
|
|
--- a/src/main/java/net/minecraft/server/VoxelShapes.java
|
|
+++ b/src/main/java/net/minecraft/server/VoxelShapes.java
|
|
@@ -239,7 +239,8 @@ public final class VoxelShapes {
|
|
|
|
if (k2 < 3) {
|
|
blockposition_mutableblockposition.a(enumaxiscycle1, i2, j2, l1);
|
|
- IBlockData iblockdata = iworldreader.getType(blockposition_mutableblockposition);
|
|
+ IBlockData iblockdata = iworldreader.getTypeIfLoaded(blockposition_mutableblockposition); // Paper
|
|
+ if (iblockdata == null) return 0.0D; // Paper
|
|
|
|
if ((k2 != 1 || iblockdata.d()) && (k2 != 2 || iblockdata.a(Blocks.MOVING_PISTON))) {
|
|
d0 = iblockdata.b((IBlockAccess) iworldreader, blockposition_mutableblockposition, voxelshapecollision).a(enumdirection_enumaxis2, axisalignedbb.d((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), d0);
|