Move patches around
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
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/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
import net.minecraft.server.ServerScoreboard;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.server.level.ServerPlayerGameMode;
|
||||
+import net.minecraft.server.level.TicketType;
|
||||
+import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
+import net.minecraft.server.network.ServerLoginPacketListenerImpl;
|
||||
+import net.minecraft.sounds.SoundEvents;
|
||||
+import net.minecraft.sounds.SoundSource;
|
||||
+import net.minecraft.stats.ServerStatsCounter;
|
||||
+import net.minecraft.stats.Stats;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -0,0 +0,0 @@ import io.papermc.paper.adventure.PaperAdventure; // Paper
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
-import net.minecraft.server.level.ServerLevel;
|
||||
-import net.minecraft.server.level.ServerPlayer;
|
||||
-import net.minecraft.server.level.ServerPlayerGameMode;
|
||||
-import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
-import net.minecraft.server.network.ServerLoginPacketListenerImpl;
|
||||
-import net.minecraft.sounds.SoundEvents;
|
||||
-import net.minecraft.sounds.SoundSource;
|
||||
-import net.minecraft.stats.ServerStatsCounter;
|
||||
-import net.minecraft.stats.Stats;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
entityplayer1.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
// CraftBukkit end
|
||||
|
||||
+ worldserver1.getChunkSource().addRegionTicket(TicketType.POST_TELEPORT, new ChunkPos(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
|
||||
while (avoidSuffocation && !worldserver1.noCollision(entityplayer1) && entityplayer1.getY() < 256.0D) {
|
||||
entityplayer1.setPos(entityplayer1.getX(), entityplayer1.getY() + 1.0D, entityplayer1.getZ());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
ChunkMap.TrackedEntity tracker; // Paper
|
||||
+ public boolean collisionLoadChunks = false; // Paper
|
||||
public Throwable addedToWorldStack; // Paper - entity debug
|
||||
public CraftEntity getBukkitEntity() {
|
||||
if (bukkitEntity == null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/CollisionGetter.java b/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
@@ -0,0 +0,0 @@ public interface CollisionGetter extends BlockGetter {
|
||||
}
|
||||
|
||||
default boolean noCollision(@Nullable Entity entity, AABB axisalignedbb, Predicate<Entity> predicate) {
|
||||
+ try { if (entity != null) entity.collisionLoadChunks = true; // Paper
|
||||
return this.getCollisions(entity, axisalignedbb, predicate).allMatch(VoxelShape::isEmpty);
|
||||
+ } finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper
|
||||
}
|
||||
|
||||
Stream<VoxelShape> getEntityCollisions(@Nullable Entity entity, AABB axisalignedbb, Predicate<Entity> predicate);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/CollisionSpliterator.java b/src/main/java/net/minecraft/world/level/CollisionSpliterator.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/CollisionSpliterator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/CollisionSpliterator.java
|
||||
@@ -0,0 +0,0 @@ import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Cursor3D;
|
||||
+import net.minecraft.server.MCUtil;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.server.level.WorldGenRegion;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
public class CollisionSpliterator extends AbstractSpliterator<VoxelShape> {
|
||||
|
||||
@Nullable
|
||||
- private final Entity source;
|
||||
+ private final Entity source; final Entity getEntity() { return this.source; } // Paper - OBFHELPER
|
||||
private final AABB box;
|
||||
private final CollisionContext context;
|
||||
private final Cursor3D cursor;
|
||||
- private final BlockPos.MutableBlockPos pos;
|
||||
+ private final BlockPos.MutableBlockPos pos; final BlockPos.MutableBlockPos getMutablePos() { return this.pos; } // Paper - OBFHELPER
|
||||
private final VoxelShape entityShape;
|
||||
- private final CollisionGetter collisionGetter;
|
||||
+ private final CollisionGetter collisionGetter; final CollisionGetter getCollisionAccess() { return this.collisionGetter; } // Paper - OBFHELPER
|
||||
private boolean needsBorderCheck;
|
||||
private final BiPredicate<BlockState, BlockPos> predicate;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CollisionSpliterator extends AbstractSpliterator<VoxelShape> {
|
||||
boolean collisionCheck(Consumer<? super VoxelShape> consumer) {
|
||||
while (true) {
|
||||
if (this.cursor.advance()) {
|
||||
- int i = this.cursor.nextX();
|
||||
- int j = this.cursor.nextY();
|
||||
- int k = this.cursor.nextZ();
|
||||
+ int i = this.cursor.nextX(); final int x = i;
|
||||
+ int j = this.cursor.nextY(); final int y = j;
|
||||
+ int k = this.cursor.nextZ(); final int z = k;
|
||||
int l = this.cursor.getNextType();
|
||||
|
||||
if (l == 3) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- BlockGetter iblockaccess = this.getChunk(i, k);
|
||||
-
|
||||
- if (iblockaccess == null) {
|
||||
+ // Paper start - ensure we don't load chunks
|
||||
+ Entity entity = this.getEntity();
|
||||
+ BlockPos.MutableBlockPos blockposition_mutableblockposition = this.getMutablePos();
|
||||
+ boolean far = entity != null && MCUtil.distanceSq(entity.getX(), y, entity.getZ(), x, y, z) > 14;
|
||||
+ blockposition_mutableblockposition.setValues(x, y, z);
|
||||
+
|
||||
+ boolean isRegionLimited = this.getCollisionAccess() instanceof WorldGenRegion;
|
||||
+ BlockState iblockdata = isRegionLimited ? Blocks.VOID_AIR.defaultBlockState() : ((!far && entity instanceof ServerPlayer) || (entity != null && entity.collisionLoadChunks)
|
||||
+ ? this.getCollisionAccess().getBlockState(blockposition_mutableblockposition)
|
||||
+ : this.getCollisionAccess().getTypeIfLoaded(blockposition_mutableblockposition)
|
||||
+ );
|
||||
+
|
||||
+ if (iblockdata == null) {
|
||||
+ if (!(entity instanceof ServerPlayer) || entity.level.paperConfig.preventMovingIntoUnloadedChunks) {
|
||||
+ VoxelShape voxelshape3 = Shapes.of(far ? entity.getBoundingBox() : new AABB(new BlockPos(x, y, z)));
|
||||
+ consumer.accept(voxelshape3);
|
||||
+ return true;
|
||||
+ }
|
||||
continue;
|
||||
}
|
||||
-
|
||||
- this.pos.set(i, j, k);
|
||||
- BlockState iblockdata = iblockaccess.getBlockState(this.pos);
|
||||
+ // Paper - moved up
|
||||
+ // Paper end
|
||||
|
||||
if (!this.predicate.test(iblockdata, this.pos) || l == 1 && !iblockdata.hasLargeCollisionShape() || l == 2 && !iblockdata.is(Blocks.MOVING_PISTON)) {
|
||||
continue;
|
||||
diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
@@ -0,0 +0,0 @@ public final class Shapes {
|
||||
|
||||
if (k2 < 3) {
|
||||
blockposition_mutableblockposition.set(enumaxiscycle1, i2, j2, l1);
|
||||
- BlockState iblockdata = world.getBlockState(blockposition_mutableblockposition);
|
||||
+ BlockState iblockdata = world.getTypeIfLoaded(blockposition_mutableblockposition); // Paper
|
||||
+ if (iblockdata == null) return 0.0D; // Paper
|
||||
|
||||
if ((k2 != 1 || iblockdata.hasLargeCollisionShape()) && (k2 != 2 || iblockdata.is(Blocks.MOVING_PISTON))) {
|
||||
initial = iblockdata.getCollisionShape((BlockGetter) world, blockposition_mutableblockposition, context).collide(enumdirection_enumaxis2, box.move((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), initial);
|
||||
Reference in New Issue
Block a user