MOAR PATCHES
This commit is contained in:
parent
27a8d6da9a
commit
f55b6e04b1
|
@ -10,6 +10,8 @@ Vs behavior of non ticking of just overwriting state.
|
|||
|
||||
We will now simply log a warning when this happens instead of crashing the server.
|
||||
|
||||
1.17: Probably not needed?
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 9da0d98bc2ed7876a00a734690ed42f01b9a9a9b..9898d5c8fab63c576831bd416ccf1854ed077b0d 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
@ -14,6 +14,8 @@ This then results in dead entities lingering in the Chunk.
|
|||
Combine that with a buggy detail of the previous implementation of
|
||||
the Dupe UUID patch, then this was the likely source of the "Ghost entities"
|
||||
|
||||
1.17: Probably not needed?
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 9898d5c8fab63c576831bd416ccf1854ed077b0d..c5dc41a3cf499038bd33451a189913cd3978b230 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
|
@ -1,55 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 26 Jan 2020 16:30:19 -0600
|
||||
Subject: [PATCH] Bees get gravity in void. Fixes MC-167279
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/control/FlyingMoveControl.java b/src/main/java/net/minecraft/world/entity/ai/control/FlyingMoveControl.java
|
||||
index 2c9e3dd1b9dd7bb8825a2eb9fecc2b2be348d055..868e9cdeb3c7effb398cef6f6f9c1e4fffa2db8c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/control/FlyingMoveControl.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/control/FlyingMoveControl.java
|
||||
@@ -16,7 +16,7 @@ public class FlyingMoveControl extends MoveControl {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void tick() {
|
||||
+ public void tick() { tick(); } public void tick() { // Paper - OBFHELPER
|
||||
if (this.operation == MoveControl.Operation.MOVE_TO) {
|
||||
this.operation = MoveControl.Operation.WAIT;
|
||||
this.mob.setNoGravity(true);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java b/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java
|
||||
index ab65f0327766463a5e53fdd723e243464319fdbe..f4984d601d14c684e75f887f5f5d2f5a29326b15 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/control/MoveControl.java
|
||||
@@ -16,7 +16,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
|
||||
public class MoveControl {
|
||||
|
||||
- protected final Mob mob;
|
||||
+ protected final Mob mob; public final Mob getEntity() { return mob; } // Paper - OBFHELPER
|
||||
protected double wantedX;
|
||||
protected double wantedY;
|
||||
protected double wantedZ;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
|
||||
index edd6d63f715acef1a77eba0cf46ff8267228f4c6..9b68809b91910d2bbb82cafe23d1de5dfff4221c 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
|
||||
@@ -111,7 +111,17 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
|
||||
public Bee(EntityType<? extends Bee> type, Level world) {
|
||||
super(type, world);
|
||||
- this.moveControl = new FlyingMoveControl(this, 20, true);
|
||||
+ // Paper start - apply gravity to bees when they get stuck in the void, fixes MC-167279
|
||||
+ this.moveControl = new FlyingMoveControl(this, 20, true) {
|
||||
+ @Override
|
||||
+ public void tick() {
|
||||
+ if (getEntity().getY() <= 0) {
|
||||
+ getEntity().setNoGravity(false);
|
||||
+ }
|
||||
+ super.tick();
|
||||
+ }
|
||||
+ };
|
||||
+ // Paper end
|
||||
this.lookControl = new Bee.BeeLookControl(this);
|
||||
this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F);
|
||||
this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F);
|
|
@ -1,185 +0,0 @@
|
|||
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 dfdde9722bc0d83916779014b7718eef2c01b3db..86c5549196a4e9011c5240e7918b466c299be4a3 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -59,12 +59,23 @@ 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;
|
||||
@@ -90,15 +101,6 @@ 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;
|
||||
|
||||
@@ -805,6 +807,7 @@ 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 7e198b94f349d4c4d61502f5ad8c60686800d88f..b8dcc91a191f25ca578e0858abf6c1b874fee15d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -168,6 +168,7 @@ 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 d9e69195ee0af4dfb90bf0e8f4cc65e63f7ecf5b..1b52f2a0ce9cb847d7d57b38f4b8b6bed8de2cd9 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
@@ -54,7 +54,9 @@ 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 7208c61da48ce5e735810b6268490584e1d5c260..feca9ff34936686c0665ae0dbc926869087df3a7 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/CollisionSpliterator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/CollisionSpliterator.java
|
||||
@@ -7,6 +7,9 @@ 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;
|
||||
@@ -21,13 +24,13 @@ 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;
|
||||
|
||||
@@ -64,23 +67,37 @@ 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 fa2942d0b0424390daee2121f8959034c5352e0b..c14d5ebe16a693834ed218af8f737714065b2e17 100644
|
||||
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
@@ -249,7 +249,8 @@ 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);
|
|
@ -8,10 +8,10 @@ Sets tracking range of watermobs to animals instead of misc and simplifies code
|
|||
Also ignores Enderdragon, defaulting it to Mojang's setting
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 190ddd4d9ef3472c33d46c2ead72fa0dc918054a..6da406c8403797a1cd9276ac06577c3c080a8a22 100644
|
||||
index fdf5d8ede4b01e399272ddebfbd49258b166f00b..273cd2e0fc38801a5ecb26579e4d0e9ee017bb3c 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1795,6 +1795,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -1791,6 +1791,7 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially
|
||||
while (iterator.hasNext()) {
|
||||
Entity entity = (Entity) iterator.next();
|
||||
int j = entity.getType().clientTrackingRange() * 16;
|
||||
|
@ -20,7 +20,7 @@ index 190ddd4d9ef3472c33d46c2ead72fa0dc918054a..6da406c8403797a1cd9276ac06577c3c
|
|||
if (j > i) {
|
||||
i = j;
|
||||
diff --git a/src/main/java/org/spigotmc/TrackingRange.java b/src/main/java/org/spigotmc/TrackingRange.java
|
||||
index 8e3e36a8739a7dea1feb3785e96b7b9f19720446..b03fa9024c7f0238e1379f6ae4486db5300a70e9 100644
|
||||
index 2d5cb8991e368372f1ab227735aac0c060deb199..24b1dfcf91d36947c87e9e5c2524317f8775ba95 100644
|
||||
--- a/src/main/java/org/spigotmc/TrackingRange.java
|
||||
+++ b/src/main/java/org/spigotmc/TrackingRange.java
|
||||
@@ -6,7 +6,6 @@ import net.minecraft.world.entity.ExperienceOrb;
|
||||
|
@ -31,7 +31,7 @@ index 8e3e36a8739a7dea1feb3785e96b7b9f19720446..b03fa9024c7f0238e1379f6ae4486db5
|
|||
|
||||
public class TrackingRange
|
||||
{
|
||||
@@ -25,26 +24,26 @@ public class TrackingRange
|
||||
@@ -29,26 +28,26 @@ public class TrackingRange
|
||||
if ( entity instanceof ServerPlayer )
|
||||
{
|
||||
return config.playerTrackingRange;
|
|
@ -13,16 +13,16 @@ Quickly loading the exact world spawn chunk before searching the
|
|||
heightmap resolves the issue without having to load all spawn chunks.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index c6881a9a5da2caed77dea30e4906d2dd99a624c1..efc9cb6def2f4ee327329dc090d2918ff60d8e19 100644
|
||||
index fffeba61e9af5c69876921b48241edb881af2a64..3d3286070c9c4db6d6487e119070794dadf493bd 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -2734,6 +2734,9 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
@@ -2983,6 +2983,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
BlockPos blockposition1;
|
||||
|
||||
if (flag1) {
|
||||
+ // Paper start - Ensure spawn chunk is always loaded before calculating Y coordinate
|
||||
+ this.level.getChunkAt(this.level.getSpawn());
|
||||
+ this.level.getChunkAt(this.level.getSharedSpawnPos());
|
||||
+ // Paper end
|
||||
blockposition1 = ServerLevel.END_SPAWN_POINT;
|
||||
} else {
|
||||
blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSpawn());
|
||||
blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSharedSpawnPos());
|
|
@ -0,0 +1,29 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 26 Jan 2020 16:30:19 -0600
|
||||
Subject: [PATCH] Bees get gravity in void. Fixes MC-167279
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
|
||||
index f3ba4b26553915917c79f013ed9dd7c87d9f65a4..b4cd490a1b2a2a118dc5f49bcb0fb755fbad853b 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
|
||||
@@ -143,7 +143,17 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
public Bee(EntityType<? extends Bee> type, Level world) {
|
||||
super(type, world);
|
||||
this.remainingCooldownBeforeLocatingNewFlower = Mth.nextInt(this.random, 20, 60);
|
||||
- this.moveControl = new FlyingMoveControl(this, 20, true);
|
||||
+ // Paper start - apply gravity to bees when they get stuck in the void, fixes MC-167279
|
||||
+ this.moveControl = new FlyingMoveControl(this, 20, true) {
|
||||
+ @Override
|
||||
+ public void tick() {
|
||||
+ if (this.mob.getY() <= 0) {
|
||||
+ this.mob.setNoGravity(false);
|
||||
+ }
|
||||
+ super.tick();
|
||||
+ }
|
||||
+ };
|
||||
+ // Paper end
|
||||
this.lookControl = new Bee.BeeLookControl(this);
|
||||
this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, -1.0F);
|
||||
this.setPathfindingMalus(BlockPathTypes.WATER, -1.0F);
|
|
@ -7,10 +7,10 @@ bypass the need to get a player chunk, then get the either,
|
|||
then unwrap it...
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index eac5e799c4d26e53286a27c54b56899ba0b9ffb2..3aeb8426b0461ec572c1499116be80f968bb4104 100644
|
||||
index c47d1772044913475a60292162ef4be594bed4c6..7cbd3db81c73d466a6e6012c1c91698b53a0cb86 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -470,6 +470,12 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -451,6 +451,12 @@ public class ServerChunkCache extends ChunkSource {
|
||||
return this.getChunk(x, z, leastStatus, create);
|
||||
}, this.mainThreadProcessor).join();
|
||||
} else {
|
||||
|
@ -23,7 +23,7 @@ index eac5e799c4d26e53286a27c54b56899ba0b9ffb2..3aeb8426b0461ec572c1499116be80f9
|
|||
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
|
||||
|
||||
gameprofilerfiller.incrementCounter("getChunk");
|
||||
@@ -520,39 +526,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -502,39 +508,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
if (Thread.currentThread() != this.mainThread) {
|
||||
return null;
|
||||
} else {
|
|
@ -6,11 +6,11 @@ Subject: [PATCH] Allow overriding the java version check
|
|||
-DPaper.IgnoreJavaVersion=true
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index 808a7688ed81bdfef623ee0a151ff8f94df2a3d7..c519ceca6f7788ca7c5d74ad1001dbc09f62681c 100644
|
||||
index f68d44721c91c20a7e4abffe26dabff8b5d2c3ce..fd48cfe3dfaf7c867becfbf90246af2f33a74612 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -181,7 +181,7 @@ public class Main {
|
||||
float javaVersion = Float.parseFloat(System.getProperty("java.class.version"));
|
||||
@@ -185,7 +185,7 @@ public class Main {
|
||||
}
|
||||
if (javaVersion > 60.0) {
|
||||
System.err.println("Unsupported Java detected (" + javaVersion + "). Only up to Java 16 is supported.");
|
||||
- return;
|
|
@ -7,10 +7,10 @@ Adds a new event similar to PlayerEggThrowEvent, but without the Player requirem
|
|||
(dispensers can throw eggs to hatch them, too).
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
index f3808a5e9155e1bf6c6219fc494864bb7dc61117..520eace73b569c2c77e76e0dfd18eb9c7188ec30 100644
|
||||
index 4e083dcd07e5975c7379035e72ac2f3469e919fd..77941e3981e49cf5662b3e3c86a9c419080b17c8 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownEgg.java
|
||||
@@ -63,6 +63,16 @@ public class ThrownEgg extends ThrowableItemProjectile {
|
||||
@@ -77,6 +77,14 @@ public class ThrownEgg extends ThrowableItemProjectile {
|
||||
hatchingType = event.getHatchingType();
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,6 @@ index f3808a5e9155e1bf6c6219fc494864bb7dc61117..520eace73b569c2c77e76e0dfd18eb9c
|
|||
+ hatching = event.isHatching();
|
||||
+ hatchingType = event.getHatchingType();
|
||||
+ // Paper end
|
||||
+
|
||||
+
|
||||
if (hatching) {
|
||||
for (int i = 0; i < b0; ++i) {
|
||||
Entity entity = level.getWorld().createEntity(new org.bukkit.Location(level.getWorld(), this.getX(), this.getY(), this.getZ(), this.yRot, 0.0F), hatchingType.getEntityClass());
|
||||
Entity entity = level.getWorld().createEntity(new org.bukkit.Location(level.getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F), hatchingType.getEntityClass());
|
|
@ -70,23 +70,11 @@ index 0000000000000000000000000000000000000000..3edc8e52e06a62ce9f8cc734fd7458b3
|
|||
+ return fastRandomBounded(this.next(32) & 0xFFFFFFFFL, bound);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
index b13e5d05d862ea8c6031b8071f525f00bc48f7e7..3db77d9eda98eacb099135643aff5e94751f4c7c 100644
|
||||
--- a/src/main/java/net/minecraft/core/BlockPos.java
|
||||
+++ b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
@@ -468,6 +468,7 @@ public class BlockPos extends Vec3i {
|
||||
return this.set(Mth.floor(x), Mth.floor(y), Mth.floor(z));
|
||||
}
|
||||
|
||||
+ public final BlockPos.MutableBlockPos setValues(final Vec3i baseblockposition) { return this.set(baseblockposition); } // Paper - OBFHELPER
|
||||
public BlockPos.MutableBlockPos set(Vec3i pos) {
|
||||
return this.set(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index bf1bb1530037ebcacc8d5a491789909bddb8b697..5d85895456b5d65954889cadf932027ea23b400b 100644
|
||||
index 67b9daee8d7e55fdf2015e6616f393f176b1ca96..ecb9c5a1958c89494417bdb3e6c6363f3fc84534 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -669,7 +669,12 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
@@ -664,7 +664,12 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -100,7 +88,7 @@ index bf1bb1530037ebcacc8d5a491789909bddb8b697..5d85895456b5d65954889cadf932027e
|
|||
ChunkPos chunkcoordintpair = chunk.getPos();
|
||||
boolean flag = this.isRaining();
|
||||
int j = chunkcoordintpair.getMinBlockX();
|
||||
@@ -677,10 +682,10 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
@@ -672,10 +677,10 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
ProfilerFiller gameprofilerfiller = this.getProfiler();
|
||||
|
||||
gameprofilerfiller.push("thunder");
|
||||
|
@ -108,12 +96,12 @@ index bf1bb1530037ebcacc8d5a491789909bddb8b697..5d85895456b5d65954889cadf932027e
|
|||
+ final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change
|
||||
|
||||
if (!this.paperConfig.disableThunder && flag && this.isThundering() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder
|
||||
- blockposition = this.findLightingTargetAround(this.getBlockRandomPos(j, 0, k, 15));
|
||||
+ blockposition.setValues(this.findLightingTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper
|
||||
- blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
|
||||
+ blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper
|
||||
if (this.isRainingAt(blockposition)) {
|
||||
DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
|
||||
boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * paperConfig.skeleHorseSpawnChance; // Paper
|
||||
@@ -703,59 +708,77 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * paperConfig.skeleHorseSpawnChance && !this.getBlockState(blockposition.below()).is(Blocks.LIGHTNING_ROD); // Paper
|
||||
@@ -698,66 +703,81 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
}
|
||||
|
||||
gameprofilerfiller.popPush("iceandsnow");
|
||||
|
@ -129,7 +117,7 @@ index bf1bb1530037ebcacc8d5a491789909bddb8b697..5d85895456b5d65954889cadf932027e
|
|||
+ // Paper end
|
||||
Biome biomebase = this.getBiome(blockposition);
|
||||
|
||||
- if (biomebase.shouldFreeze(this, blockposition1)) {
|
||||
- if (biomebase.shouldFreeze((LevelReader) this, blockposition1)) {
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition1, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
|
||||
+ // Paper start - optimise chunk ticking
|
||||
+ blockposition.setY(downY);
|
||||
|
@ -138,18 +126,24 @@ index bf1bb1530037ebcacc8d5a491789909bddb8b697..5d85895456b5d65954889cadf932027e
|
|||
+ // Paper end
|
||||
}
|
||||
|
||||
+ blockposition.setY(normalY); // Paper
|
||||
if (flag && biomebase.shouldSnow(this, blockposition)) {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.defaultBlockState(), null); // CraftBukkit
|
||||
}
|
||||
if (flag) {
|
||||
+ blockposition.setY(normalY); // Paper
|
||||
if (biomebase.shouldSnow(this, blockposition)) {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.defaultBlockState(), null); // CraftBukkit
|
||||
}
|
||||
|
||||
- if (flag && this.getBiome(blockposition1).getPrecipitation() == Biome.Precipitation.RAIN) {
|
||||
- this.getBlockState(blockposition1).getBlock().handleRain((net.minecraft.world.level.Level) this, blockposition1);
|
||||
+ // Paper start - optimise chunk ticking
|
||||
+ blockposition.setY(downY);
|
||||
+ if (flag && this.getBiome(blockposition).getPrecipitation() == Biome.Precipitation.RAIN) {
|
||||
+ chunk.getBlockState(blockposition).getBlock().handleRain((net.minecraft.world.level.Level) this, blockposition);
|
||||
+ // Paper end
|
||||
- BlockState iblockdata = this.getBlockState(blockposition1);
|
||||
+ blockposition.setY(downY); // Paper
|
||||
+ BlockState iblockdata = this.getBlockState(blockposition); // Paper
|
||||
Biome.Precipitation biomebase_precipitation = this.getBiome(blockposition).getPrecipitation();
|
||||
|
||||
- if (biomebase_precipitation == Biome.Precipitation.RAIN && biomebase.isColdEnoughToSnow(blockposition1)) {
|
||||
+ if (biomebase_precipitation == Biome.Precipitation.RAIN && biomebase.isColdEnoughToSnow(blockposition)) { // Paper
|
||||
biomebase_precipitation = Biome.Precipitation.SNOW;
|
||||
}
|
||||
|
||||
- iblockdata.getBlock().handlePrecipitation(iblockdata, (net.minecraft.world.level.Level) this, blockposition1, biomebase_precipitation);
|
||||
+ iblockdata.getBlock().handlePrecipitation(iblockdata, (net.minecraft.world.level.Level) this, blockposition, biomebase_precipitation); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,27 +154,27 @@ index bf1bb1530037ebcacc8d5a491789909bddb8b697..5d85895456b5d65954889cadf932027e
|
|||
if (randomTickSpeed > 0) {
|
||||
- LevelChunkSection[] achunksection = chunk.getSections();
|
||||
- int l = achunksection.length;
|
||||
-
|
||||
- for (int i1 = 0; i1 < l; ++i1) {
|
||||
- LevelChunkSection chunksection = achunksection[i1];
|
||||
+ gameprofilerfiller.push("randomTick");
|
||||
+ timings.chunkTicksBlocks.startTiming(); // Paper
|
||||
|
||||
- for (int i1 = 0; i1 < l; ++i1) {
|
||||
- LevelChunkSection chunksection = achunksection[i1];
|
||||
+ LevelChunkSection[] sections = chunk.getSections();
|
||||
|
||||
- if (chunksection != LevelChunk.EMPTY_SECTION && chunksection.isRandomlyTicking()) {
|
||||
- int j1 = chunksection.bottomBlockY();
|
||||
+ LevelChunkSection[] sections = chunk.getSections();
|
||||
|
||||
- for (int k1 = 0; k1 < randomTickSpeed; ++k1) {
|
||||
- BlockPos blockposition2 = this.getBlockRandomPos(j, j1, k, 15);
|
||||
+ for (int sectionIndex = 0; sectionIndex < 16; ++sectionIndex) {
|
||||
+ LevelChunkSection section = sections[sectionIndex];
|
||||
+ if (section == null || section.tickingList.size() == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- for (int k1 = 0; k1 < randomTickSpeed; ++k1) {
|
||||
- BlockPos blockposition2 = this.getBlockRandomPos(j, j1, k, 15);
|
||||
+ int yPos = sectionIndex << 4;
|
||||
|
||||
- gameprofilerfiller.push("randomTick");
|
||||
- BlockState iblockdata = chunksection.getBlockState(blockposition2.getX() - j, blockposition2.getY() - j1, blockposition2.getZ() - k);
|
||||
- BlockState iblockdata1 = chunksection.getBlockState(blockposition2.getX() - j, blockposition2.getY() - j1, blockposition2.getZ() - k);
|
||||
+ int yPos = sectionIndex << 4;
|
||||
+ for (int a = 0; a < randomTickSpeed1; ++a) {
|
||||
+ int tickingBlocks = section.tickingList.size();
|
||||
+ int index = this.randomTickRandom.nextInt(16 * 16 * 16);
|
||||
|
@ -188,8 +182,8 @@ index bf1bb1530037ebcacc8d5a491789909bddb8b697..5d85895456b5d65954889cadf932027e
|
|||
+ continue;
|
||||
+ }
|
||||
|
||||
- if (iblockdata.isRandomlyTicking()) {
|
||||
- iblockdata.randomTick(this, blockposition2, this.random);
|
||||
- if (iblockdata1.isRandomlyTicking()) {
|
||||
- iblockdata1.randomTick(this, blockposition2, this.random);
|
||||
- }
|
||||
+ long raw = section.tickingList.getRaw(index);
|
||||
+ int location = com.destroystokyo.paper.util.maplist.IBlockDataList.getLocationFromRaw(raw);
|
||||
|
@ -197,7 +191,7 @@ index bf1bb1530037ebcacc8d5a491789909bddb8b697..5d85895456b5d65954889cadf932027e
|
|||
+ int randomY = ((location >>> (4 + 4)) & 255) | yPos;
|
||||
+ int randomZ = (location >>> 4) & 15;
|
||||
|
||||
- FluidState fluid = iblockdata.getFluidState();
|
||||
- FluidState fluid = iblockdata1.getFluidState();
|
||||
+ BlockPos blockposition2 = blockposition.setValues(j + randomX, randomY, k + randomZ);
|
||||
+ BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
|
||||
|
||||
|
@ -220,12 +214,12 @@ index bf1bb1530037ebcacc8d5a491789909bddb8b697..5d85895456b5d65954889cadf932027e
|
|||
- gameprofilerfiller.pop();
|
||||
}
|
||||
|
||||
protected BlockPos findLightingTargetAround(BlockPos pos) {
|
||||
private Optional<BlockPos> findLightningRod(BlockPos pos) {
|
||||
diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java
|
||||
index dd84984f28484cf7129c294222696784e128221a..9ea72751354e893cd3820befaa5df3e5e503de6e 100644
|
||||
index 9b955a027bd2c3cbcfa659a41a6687221c5fea63..6c036335b28258cd8c268173d73707af00d12bf9 100644
|
||||
--- a/src/main/java/net/minecraft/util/BitStorage.java
|
||||
+++ b/src/main/java/net/minecraft/util/BitStorage.java
|
||||
@@ -112,4 +112,32 @@ public class BitStorage {
|
||||
@@ -105,4 +105,32 @@ public class BitStorage {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -259,7 +253,7 @@ index dd84984f28484cf7129c294222696784e128221a..9ea72751354e893cd3820befaa5df3e5
|
|||
+ // Paper end
|
||||
}
|
||||
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 42b636c4ebb6eb83c8a9f3f5f9a766d37d065dc3..0e15ca2fb9cd1aeb4a075b8d50350dd7fd463c72 100644
|
||||
index e638d982b4bd1d261a7282cad6dab98ad0b55213..e305173fd1652a8b88ae8a9b94d0fae083e2da95 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Turtle.java
|
||||
@@ -91,7 +91,7 @@ public class Turtle extends Animal {
|
||||
|
@ -272,10 +266,10 @@ index 42b636c4ebb6eb83c8a9f3f5f9a766d37d065dc3..0e15ca2fb9cd1aeb4a075b8d50350dd7
|
|||
|
||||
public BlockPos getHomePos() { // Paper - public
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 1d536d77518a70bdc1a23924aea99df1042b3cd5..632f32405053fbcff2fd26fa99f98c6add9f9dc7 100644
|
||||
index 07e81fa1119bba4981e34e70b9e67f43280f8071..5fccec12c0325dd9873905c5c3559128c3b4d9ad 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -1472,10 +1472,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
@@ -1299,10 +1299,18 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public abstract TagContainer getTagManager();
|
||||
|
||||
public BlockPos getBlockRandomPos(int x, int y, int z, int l) {
|
||||
|
@ -296,27 +290,24 @@ index 1d536d77518a70bdc1a23924aea99df1042b3cd5..632f32405053fbcff2fd26fa99f98c6a
|
|||
|
||||
public boolean noSave() {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 4fef3abe4b416cbebe1b456468b5c3e162de18f1..87d7a87a2925f2c062658e960bb5128738828d9f 100644
|
||||
index 922026da8c234427e0322443004d3c32993adfce..88b053d8181d2a5abdb2c5527529a81855e1de7c 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -639,8 +639,8 @@ public class LevelChunk implements ChunkAccess {
|
||||
this.entities.remove(entity); // Paper
|
||||
}
|
||||
@@ -568,6 +568,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
@Override
|
||||
public void addEntity(Entity entity) {}
|
||||
|
||||
- @Override
|
||||
- public int getHeight(Heightmap.Types type, int x, int z) {
|
||||
+ public final int getHighestBlockY(Heightmap.Types heightmap_type, int i, int j) { return this.getHeight(heightmap_type, i, j) + 1; } // Paper - sort of an obfhelper, but without -1
|
||||
+ @Override public int getHeight(Heightmap.Types type, int x, int z) { // Paper
|
||||
@Override
|
||||
public int getHeight(Heightmap.Types type, int x, int z) {
|
||||
return ((Heightmap) this.heightmaps.get(type)).getFirstAvailable(x & 15, z & 15) - 1;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
index 38c7c5f18fc84d4a1de2da1ddc6d3ac37c25f341..c44d32f966c61497b4a8892eb51da3a71ad031d9 100644
|
||||
index 5fd66020a937b641e2a060cf38df731a43f3bf55..b5497272bc03a290298b5a829bdf653ac986866b 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
@@ -14,12 +14,14 @@ import net.minecraft.world.level.material.FluidState;
|
||||
public class LevelChunkSection {
|
||||
|
||||
@@ -14,11 +14,12 @@ public class LevelChunkSection {
|
||||
public static final int SECTION_HEIGHT = 16;
|
||||
public static final int SECTION_SIZE = 4096;
|
||||
public static final Palette<BlockState> GLOBAL_BLOCKSTATE_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState());
|
||||
- private final int bottomBlockY;
|
||||
+ final int bottomBlockY; // Paper - private -> package-private
|
||||
|
@ -325,15 +316,13 @@ index 38c7c5f18fc84d4a1de2da1ddc6d3ac37c25f341..c44d32f966c61497b4a8892eb51da3a7
|
|||
+ short tickingBlockCount; // Paper - private -> package-private
|
||||
private short tickingFluidCount;
|
||||
final PalettedContainer<BlockState> states; // Paper - package-private
|
||||
|
||||
+ public final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper
|
||||
+
|
||||
// Paper start - Anti-Xray - Add parameters
|
||||
@Deprecated public LevelChunkSection(int yOffset) { this(yOffset, null, null, true); } // Notice for updates: Please make sure this constructor isn't used anywhere
|
||||
public LevelChunkSection(int i, ChunkAccess chunk, Level world, boolean initializeBlocks) {
|
||||
@@ -74,6 +76,9 @@ public class LevelChunkSection {
|
||||
|
||||
public LevelChunkSection(int yOffset) {
|
||||
this(yOffset, (short)0, (short)0, (short)0);
|
||||
@@ -70,6 +71,9 @@ public class LevelChunkSection {
|
||||
--this.nonEmptyBlockCount;
|
||||
if (iblockdata1.isRandomlyTicking()) {
|
||||
if (blockState.isRandomlyTicking()) {
|
||||
--this.tickingBlockCount;
|
||||
+ // Paper start
|
||||
+ this.tickingList.remove(x, y, z);
|
||||
|
@ -341,7 +330,7 @@ index 38c7c5f18fc84d4a1de2da1ddc6d3ac37c25f341..c44d32f966c61497b4a8892eb51da3a7
|
|||
}
|
||||
}
|
||||
|
||||
@@ -85,6 +90,9 @@ public class LevelChunkSection {
|
||||
@@ -81,6 +85,9 @@ public class LevelChunkSection {
|
||||
++this.nonEmptyBlockCount;
|
||||
if (state.isRandomlyTicking()) {
|
||||
++this.tickingBlockCount;
|
||||
|
@ -351,7 +340,7 @@ index 38c7c5f18fc84d4a1de2da1ddc6d3ac37c25f341..c44d32f966c61497b4a8892eb51da3a7
|
|||
}
|
||||
}
|
||||
|
||||
@@ -120,23 +128,29 @@ public class LevelChunkSection {
|
||||
@@ -116,22 +123,28 @@ public class LevelChunkSection {
|
||||
}
|
||||
|
||||
public void recalcBlockCounts() {
|
||||
|
@ -361,36 +350,35 @@ index 38c7c5f18fc84d4a1de2da1ddc6d3ac37c25f341..c44d32f966c61497b4a8892eb51da3a7
|
|||
this.nonEmptyBlockCount = 0;
|
||||
this.tickingBlockCount = 0;
|
||||
this.tickingFluidCount = 0;
|
||||
- this.states.count((iblockdata, i) -> {
|
||||
+ this.states.forEachLocation((iblockdata, location) -> { // Paper
|
||||
FluidState fluid = iblockdata.getFluidState();
|
||||
|
||||
if (!iblockdata.isAir()) {
|
||||
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
||||
if (iblockdata.isRandomlyTicking()) {
|
||||
- this.tickingBlockCount = (short) (this.tickingBlockCount + i);
|
||||
+ this.tickingBlockCount = (short) (this.tickingBlockCount + 1);
|
||||
- this.states.count((state, count) -> {
|
||||
+ this.states.forEachLocation((state, location) -> { // Paper
|
||||
FluidState fluidState = state.getFluidState();
|
||||
if (!state.isAir()) {
|
||||
- this.nonEmptyBlockCount = (short)(this.nonEmptyBlockCount + count);
|
||||
+ this.nonEmptyBlockCount = (short)(this.nonEmptyBlockCount + 1); // Paper
|
||||
if (state.isRandomlyTicking()) {
|
||||
- this.tickingBlockCount = (short)(this.tickingBlockCount + count);
|
||||
+ // Paper start
|
||||
+ this.tickingList.add(location, iblockdata);
|
||||
+ this.tickingBlockCount = (short)(this.tickingBlockCount + 1);
|
||||
+ this.tickingList.add(location, state);
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
if (!fluid.isEmpty()) {
|
||||
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
||||
if (fluid.isRandomlyTicking()) {
|
||||
- this.tickingFluidCount = (short) (this.tickingFluidCount + i);
|
||||
+ this.tickingFluidCount = (short) (this.tickingFluidCount + 1);
|
||||
if (!fluidState.isEmpty()) {
|
||||
- this.nonEmptyBlockCount = (short)(this.nonEmptyBlockCount + count);
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); // Paper
|
||||
if (fluidState.isRandomlyTicking()) {
|
||||
- this.tickingFluidCount = (short)(this.tickingFluidCount + count);
|
||||
+ this.tickingFluidCount = (short) (this.tickingFluidCount + 1); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
index dd252372e1e380674b1191e9ea265cbb10de437b..f93316b3ae5cd5fb960fa24f8c921b5b9276d9f3 100644
|
||||
index 5ea60bbb56450502f1ceb41959239ab579458ac2..5ac948b5b82f3144cdf402af440251cb8c7369d7 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/PalettedContainer.java
|
||||
@@ -285,6 +285,14 @@ public class PalettedContainer<T> implements PaletteResize<T> {
|
||||
@@ -259,6 +259,14 @@ public class PalettedContainer<T> implements PaletteResize<T> {
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -404,4 +392,4 @@ index dd252372e1e380674b1191e9ea265cbb10de437b..f93316b3ae5cd5fb960fa24f8c921b5b
|
|||
+
|
||||
@FunctionalInterface
|
||||
public interface CountConsumer<T> {
|
||||
|
||||
void accept(T object, int count);
|
|
@ -5,10 +5,10 @@ Subject: [PATCH] Entity Jump API
|
|||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index b84dab1043c56e2deb58aec8639226f98db165d1..43fbe7d220f61802ae0cb0620ad078c5df7b69bc 100644
|
||||
index bd1cc5e6fea4b9a171718c1249f652782b7ce13e..6cc2d26403aa5074218b4b76e2d8ed9e8409a0ae 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -2873,8 +2873,10 @@ public abstract class LivingEntity extends Entity {
|
||||
@@ -3159,8 +3159,10 @@ public abstract class LivingEntity extends Entity {
|
||||
} else if (this.isInLava() && (!this.onGround || d7 > d8)) {
|
||||
this.jumpInLiquid((Tag) FluidTags.LAVA);
|
||||
} else if ((this.onGround || flag && d7 <= d8) && this.noJumpDelay == 0) {
|
||||
|
@ -20,10 +20,10 @@ index b84dab1043c56e2deb58aec8639226f98db165d1..43fbe7d220f61802ae0cb0620ad078c5
|
|||
} else {
|
||||
this.noJumpDelay = 0;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
index 1621d8748e96c6e1abb33b699a1273bb698f67d2..423bdbe25b6f2261cb5092378b0564a82faeecb4 100644
|
||||
index 2d59eab846db2c0a624cf6d06a570b2313aa6b13..851ee58e52c6003d6ae7b58c9b6b9a9a9795fa85 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java
|
||||
@@ -489,7 +489,9 @@ public class Panda extends Animal {
|
||||
@@ -514,7 +514,9 @@ public class Panda extends Animal {
|
||||
Panda entitypanda = (Panda) iterator.next();
|
||||
|
||||
if (!entitypanda.isBaby() && entitypanda.onGround && !entitypanda.isInWater() && entitypanda.canPerformAction()) {
|
||||
|
@ -34,7 +34,7 @@ index 1621d8748e96c6e1abb33b699a1273bb698f67d2..423bdbe25b6f2261cb5092378b0564a8
|
|||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index a01bd035846df0e2e28dc55e2ef2f5f35b83f905..5dac3bf5a117bfbf57798238f0614558deafcd1b 100644
|
||||
index 5477f288db57d63051f4579b8cd3c19e3af430ee..76e9977f7b2f7fb50631fc56f3318d59d04b1398 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -792,5 +792,19 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
|
@ -5,24 +5,26 @@ Subject: [PATCH] Add option to nerf pigmen from nether portals
|
|||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 7fbd501d70dccf869a4454e2789a5d68f2e15754..9e4591ddc4b755f4ff5a6f1078b51cb13db80480 100644
|
||||
index 3cd8895adecd345c3bdfb8b5e3e9fdf0ef9097db..e70e0b1115422b9b901c2879138433da2d4f94d8 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -594,4 +594,9 @@ public class PaperWorldConfig {
|
||||
disableHopperMoveEvents = getBoolean("hopper.disable-move-event", disableHopperMoveEvents);
|
||||
@@ -441,6 +441,11 @@ public class PaperWorldConfig {
|
||||
log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled"));
|
||||
}
|
||||
+
|
||||
|
||||
+ public boolean nerfNetherPortalPigmen = false;
|
||||
+ private void nerfNetherPortalPigmen() {
|
||||
+ nerfNetherPortalPigmen = getBoolean("game-mechanics.nerf-pigmen-from-nether-portals", nerfNetherPortalPigmen);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
public int lightQueueSize = 20;
|
||||
private void lightQueueSize() {
|
||||
lightQueueSize = getInt("light-queue-size", lightQueueSize);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index efc9cb6def2f4ee327329dc090d2918ff60d8e19..43f77d01fceab107d3502d282205aa579d64cc4b 100644
|
||||
index 3d3286070c9c4db6d6487e119070794dadf493bd..facb09e49d92d22dbcde7d187d4ba1c9a04202a9 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -277,6 +277,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
@@ -307,6 +307,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
public long activatedTick = Integer.MIN_VALUE;
|
||||
public boolean isTemporarilyActive = false; // Paper
|
||||
public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
|
||||
|
@ -30,42 +32,34 @@ index efc9cb6def2f4ee327329dc090d2918ff60d8e19..43f77d01fceab107d3502d282205aa57
|
|||
protected int numCollisions = 0; // Paper
|
||||
public void inactiveTick() { }
|
||||
// Spigot end
|
||||
@@ -1693,6 +1694,9 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
@@ -1861,6 +1862,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
if (spawnedViaMobSpawner) {
|
||||
tag.putBoolean("Paper.FromMobSpawner", true);
|
||||
nbt.putBoolean("Paper.FromMobSpawner", true);
|
||||
}
|
||||
+ if (fromNetherPortal) {
|
||||
+ tag.putBoolean("Paper.FromNetherPortal", true);
|
||||
+ nbt.putBoolean("Paper.FromNetherPortal", true);
|
||||
+ }
|
||||
// Paper end
|
||||
return tag;
|
||||
return nbt;
|
||||
} catch (Throwable throwable) {
|
||||
@@ -1827,6 +1831,7 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
|
||||
@@ -1999,6 +2003,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
}
|
||||
|
||||
spawnedViaMobSpawner = tag.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
|
||||
+ fromNetherPortal = tag.getBoolean("Paper.FromNetherPortal");
|
||||
if (tag.contains("Paper.SpawnReason")) {
|
||||
String spawnReasonName = tag.getString("Paper.SpawnReason");
|
||||
spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
|
||||
+ fromNetherPortal = nbt.getBoolean("Paper.FromNetherPortal");
|
||||
if (nbt.contains("Paper.SpawnReason")) {
|
||||
String spawnReasonName = nbt.getString("Paper.SpawnReason");
|
||||
try {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
index 805d83a93bce20910d17c3f419bc085251b6cfc1..ae58929886921d0714bf811de92f99dc0dc120dc 100644
|
||||
index e34716f2a19eb578fef3f19182c124d359deb88f..cfea29f5bf1c5e74a0292c1344baaaa49c2f4403 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
@@ -8,6 +8,7 @@ import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
+import net.minecraft.world.entity.Mob;
|
||||
import net.minecraft.world.entity.MobSpawnType;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
@@ -61,6 +62,8 @@ public class NetherPortalBlock extends Block {
|
||||
@@ -66,6 +66,8 @@ public class NetherPortalBlock extends Block {
|
||||
|
||||
if (entity != null) {
|
||||
entity.setPortalCooldown();
|
||||
+ entity.fromNetherPortal = true; // Paper
|
||||
+ if (world.paperConfig.nerfNetherPortalPigmen) ((Mob) entity).aware = false; // Paper
|
||||
+ if (world.paperConfig.nerfNetherPortalPigmen) ((net.minecraft.world.entity.Mob) entity).aware = false; // Paper
|
||||
}
|
||||
}
|
||||
}
|
|
@ -109,7 +109,7 @@ index 0000000000000000000000000000000000000000..186fc722965e403f76b1480e1c2381fc
|
|||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/gui/GuiStatsComponent.java b/src/main/java/com/destroystokyo/paper/gui/GuiStatsComponent.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0f29ad583e798c09b2fe3f568ed50cbc719e40e2
|
||||
index 0000000000000000000000000000000000000000..537bc6213545e8ff1b7b51bc4b27fd5b2a740883
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/gui/GuiStatsComponent.java
|
||||
@@ -0,0 +1,41 @@
|
||||
|
@ -149,14 +149,14 @@ index 0000000000000000000000000000000000000000..0f29ad583e798c09b2fe3f568ed50cbc
|
|||
+ return new Dimension(350, 200);
|
||||
+ }
|
||||
+
|
||||
+ public void stop() { a(); } public void a() {
|
||||
+ public void close() {
|
||||
+ timer.stop();
|
||||
+ ramGraph.stop();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..c0923ec75ecced2e0a1c0d3ec2c046d69af3e9a9
|
||||
index 0000000000000000000000000000000000000000..23239679d6584f1088b2b94c46eb9a5c1f9ad91d
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/gui/RAMDetails.java
|
||||
@@ -0,0 +1,73 @@
|
||||
|
@ -176,7 +176,7 @@ index 0000000000000000000000000000000000000000..c0923ec75ecced2e0a1c0d3ec2c046d6
|
|||
+import java.util.Vector;
|
||||
+
|
||||
+public class RAMDetails extends JList<String> {
|
||||
+ public static final DecimalFormat DECIMAL_FORMAT = Util.peek(new DecimalFormat("########0.000"), (format)
|
||||
+ public static final DecimalFormat DECIMAL_FORMAT = Util.make(new DecimalFormat("########0.000"), (format)
|
||||
+ -> format.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)));
|
||||
+
|
||||
+ private final MinecraftServer server;
|
||||
|
@ -221,7 +221,7 @@ index 0000000000000000000000000000000000000000..c0923ec75ecced2e0a1c0d3ec2c046d6
|
|||
+ Vector<String> vector = new Vector<>();
|
||||
+ vector.add("Memory use: " + (data.getUsedMem() / 1024L / 1024L) + " mb (" + (data.getFree() * 100L / data.getMax()) + "% free)");
|
||||
+ vector.add("Heap: " + (data.getTotal() / 1024L / 1024L) + " / " + (data.getMax() / 1024L / 1024L) + " mb");
|
||||
+ vector.add("Avg tick: " + DECIMAL_FORMAT.format(getAverage(server.getTickTimes())) + " ms");
|
||||
+ vector.add("Avg tick: " + DECIMAL_FORMAT.format(getAverage(server.tickTimes)) + " ms");
|
||||
+ setListData(vector);
|
||||
+ }
|
||||
+
|
||||
|
@ -383,57 +383,16 @@ index 0000000000000000000000000000000000000000..c3e54da4ab6440811aab2f9dd1e21880
|
|||
+ timer.stop();
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
|
||||
index cec5ad5052c8cf6059e9b117117846bdb217748f..c2f747226f10479c826849af898538610a2dd659 100644
|
||||
--- a/src/main/java/net/minecraft/Util.java
|
||||
+++ b/src/main/java/net/minecraft/Util.java
|
||||
@@ -259,6 +259,7 @@ public class Util {
|
||||
return factory.get();
|
||||
}
|
||||
|
||||
+ public static <T> T peek(T t0, Consumer<T> consumer) { return make(t0, consumer); } // Paper - OBFHELPER
|
||||
public static <T> T make(T object, Consumer<T> initializer) {
|
||||
initializer.accept(object);
|
||||
return object;
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 7038897b8fb4c18ca97b95a3b24c30b40b62b005..e33189dc8375a3034910087654607fb531061636 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -216,7 +216,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
private String motd;
|
||||
private int maxBuildHeight;
|
||||
private int playerIdleTimeout;
|
||||
- public final long[] tickTimes;
|
||||
+ public final long[] tickTimes; public long[] getTickTimes() { return tickTimes; } // Paper - OBFHELPER
|
||||
@Nullable
|
||||
private KeyPair keyPair;
|
||||
@Nullable
|
||||
diff --git a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||
index 2299349e701ffd5ee53cc5fe25f4d1e271cc3d65..2567c588a1dcf732800e6cf87352b020c7bb84d6 100644
|
||||
index 737ae68ab486a324628e994586862ef7397ae278..703d2bb93d6ab76fc117a320f155570addcc543c 100644
|
||||
--- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||
+++ b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||
@@ -91,9 +91,9 @@ public class MinecraftServerGui extends JComponent {
|
||||
@@ -95,7 +95,7 @@ public class MinecraftServerGui extends JComponent {
|
||||
|
||||
private JComponent buildInfoPanel() {
|
||||
JPanel jpanel = new JPanel(new BorderLayout());
|
||||
- StatsComponent guistatscomponent = new StatsComponent(this.server);
|
||||
+ com.destroystokyo.paper.gui.GuiStatsComponent guistatscomponent = new com.destroystokyo.paper.gui.GuiStatsComponent(this.server); // Paper
|
||||
Collection<Runnable> collection = this.finalizers; // CraftBukkit - decompile error
|
||||
|
||||
- this.finalizers.add(guistatscomponent::close);
|
||||
+ this.finalizers.add(guistatscomponent::a);
|
||||
jpanel.add(guistatscomponent, "North");
|
||||
jpanel.add(this.buildPlayerPanel(), "Center");
|
||||
jpanel.setBorder(new TitledBorder(new EtchedBorder(), "Stats"));
|
||||
diff --git a/src/main/java/net/minecraft/server/gui/StatsComponent.java b/src/main/java/net/minecraft/server/gui/StatsComponent.java
|
||||
index 30960738de03edf7aa8745a176b3a2be86eaf282..09414d04208a843f8d337569b53f61b34e64ed92 100644
|
||||
--- a/src/main/java/net/minecraft/server/gui/StatsComponent.java
|
||||
+++ b/src/main/java/net/minecraft/server/gui/StatsComponent.java
|
||||
@@ -13,7 +13,7 @@ import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class StatsComponent extends JComponent {
|
||||
|
||||
- private static final DecimalFormat DECIMAL_FORMAT = (DecimalFormat) Util.make((Object) (new DecimalFormat("########0.000")), (decimalformat) -> {
|
||||
+ private static final DecimalFormat DECIMAL_FORMAT = (DecimalFormat) Util.make(new DecimalFormat("########0.000"), (decimalformat) -> { // Paper - decompile error
|
||||
decimalformat.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT));
|
||||
});
|
||||
private final int[] values = new int[256];
|
||||
Objects.requireNonNull(guistatscomponent);
|
|
@ -5,10 +5,10 @@ Subject: [PATCH] add hand to BlockMultiPlaceEvent
|
|||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index e696d2e52532df25d74a1f559e2c9ca0f3d5058d..7d9a3b65b2d6b294d3a11414289e64fac88665f0 100644
|
||||
index c3341d1c4e9cda85b0b236461b0a00cbebc9a856..98bec353d6dbd85c7b329f75e09f4d0bfcfdaa6c 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -337,13 +337,18 @@ public class CraftEventFactory {
|
||||
@@ -339,13 +339,18 @@ public class CraftEventFactory {
|
||||
}
|
||||
|
||||
org.bukkit.inventory.ItemStack item;
|
|
@ -5,15 +5,15 @@ Subject: [PATCH] Prevent teleporting dead entities
|
|||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 2b79413bb8a592a7b7093e11d3a0cce895286c8f..09a663cc53cdf8ae45352b280200c8170dbbcdfc 100644
|
||||
index 9240064a17e7ac2492fe157b759d1f724105cd0e..fcfd57fd7af655aafb330986e8f6f9cc55819165 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -1468,6 +1468,10 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener {
|
||||
@@ -1501,6 +1501,10 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
}
|
||||
|
||||
private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<ClientboundPlayerPositionPacket.RelativeArgument> set) {
|
||||
+ if (player.removed) {
|
||||
+ LOGGER.info("Attempt to teleport dead player {} restricted", player.getScoreboardName());
|
||||
private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<ClientboundPlayerPositionPacket.RelativeArgument> set, boolean flag) {
|
||||
+ if (player.isRemoved()) {
|
||||
+ LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
|
||||
+ return;
|
||||
+ }
|
||||
// CraftBukkit start
|
|
@ -5,10 +5,10 @@ Subject: [PATCH] Validate tripwire hook placement before update
|
|||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
index f44d4809fe87c832e4d3bda429af2254e8c746d6..20428aff54527b664d988a6a0f54236b693fda89 100644
|
||||
index 3a5252afa9681fb1956493bead27e6cdb13679ca..0cfa1abca2c5744a4147b05905983ae4acaa569a 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TripWireHookBlock.java
|
||||
@@ -169,6 +169,7 @@ public class TripWireHookBlock extends Block {
|
||||
@@ -174,6 +174,7 @@ public class TripWireHookBlock extends Block {
|
||||
|
||||
this.playSound(world, pos, flag4, flag5, flag2, flag3);
|
||||
if (!beingRemoved) {
|
|
@ -5,10 +5,10 @@ Subject: [PATCH] Add option to allow iron golems to spawn in air
|
|||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 9e4591ddc4b755f4ff5a6f1078b51cb13db80480..fe1c9dd8258ec8c3fdf343d4a44de2be2ae3d35f 100644
|
||||
index e70e0b1115422b9b901c2879138433da2d4f94d8..19e0532ea296d6862ab6508658726e96e05346c9 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -387,6 +387,11 @@ public class PaperWorldConfig {
|
||||
@@ -380,6 +380,11 @@ public class PaperWorldConfig {
|
||||
scanForLegacyEnderDragon = getBoolean("game-mechanics.scan-for-legacy-ender-dragon", true);
|
||||
}
|
||||
|
||||
|
@ -21,10 +21,10 @@ index 9e4591ddc4b755f4ff5a6f1078b51cb13db80480..fe1c9dd8258ec8c3fdf343d4a44de2be
|
|||
private void armorStandEntityLookups() {
|
||||
armorStandEntityLookups = getBoolean("armor-stands-do-collision-entity-lookups", true);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
|
||||
index 9cedac83304847bdc92c2e97c4e6e119664c3bd0..59f0224b6a743408a03b642dd7cbe545f406c57e 100644
|
||||
index b5481299f551b7150425a4a1b1c21b43d8a1d382..ec00c2dd8f969eb99ec6a014e3bcd09c7484b237 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/IronGolem.java
|
||||
@@ -297,7 +297,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
|
||||
@@ -322,7 +322,7 @@ public class IronGolem extends AbstractGolem implements NeutralMob {
|
||||
BlockPos blockposition1 = blockposition.below();
|
||||
BlockState iblockdata = world.getBlockState(blockposition1);
|
||||
|
|
@ -8,37 +8,38 @@ This allows you to solve an issue in vanilla behavior where:
|
|||
* On normal difficulty they will have a 50% of getting infected or dying.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index fe1c9dd8258ec8c3fdf343d4a44de2be2ae3d35f..525d702d78a609af987ebd2c32169b873e5c05ed 100644
|
||||
index 19e0532ea296d6862ab6508658726e96e05346c9..b57d9c84db5685b86cb077e3b42db7a8578d6f62 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -604,4 +604,9 @@ public class PaperWorldConfig {
|
||||
private void nerfNetherPortalPigmen() {
|
||||
@@ -451,6 +451,11 @@ public class PaperWorldConfig {
|
||||
nerfNetherPortalPigmen = getBoolean("game-mechanics.nerf-pigmen-from-nether-portals", nerfNetherPortalPigmen);
|
||||
}
|
||||
+
|
||||
|
||||
+ public double zombieVillagerInfectionChance = -1.0;
|
||||
+ private void zombieVillagerInfectionChance() {
|
||||
+ zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
public int lightQueueSize = 20;
|
||||
private void lightQueueSize() {
|
||||
lightQueueSize = getInt("light-queue-size", lightQueueSize);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
index 6fecf4188fc0247143edc688c03e645376960687..1e7c2c603b967c8c606efd94ce95a17c856f78d7 100644
|
||||
index ee17cba501e0cc4822bd1278d18b561c77fe9674..b036cbb9a1b6bcac91ffc8ee659fc95d6e04d5d4 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
@@ -447,10 +447,14 @@ public class Zombie extends Monster {
|
||||
@@ -453,10 +453,13 @@ public class Zombie extends Monster {
|
||||
@Override
|
||||
public void killed(ServerLevel worldserver, LivingEntity entityliving) {
|
||||
super.killed(worldserver, entityliving);
|
||||
- if ((worldserver.getDifficulty() == Difficulty.NORMAL || worldserver.getDifficulty() == Difficulty.HARD) && entityliving instanceof Villager) {
|
||||
- if (worldserver.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
|
||||
+ // Paper start
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance != 0.0 && (level.paperConfig.zombieVillagerInfectionChance != -1.0 || worldserver.getDifficulty() == Difficulty.NORMAL || worldserver.getDifficulty() == Difficulty.HARD) && entityliving instanceof Villager) {
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance == -1.0 && worldserver.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
|
||||
public void killed(ServerLevel world, LivingEntity other) {
|
||||
super.killed(world, other);
|
||||
- if ((world.getDifficulty() == Difficulty.NORMAL || world.getDifficulty() == Difficulty.HARD) && other instanceof Villager) {
|
||||
- if (world.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance != 0.0 && (level.paperConfig.zombieVillagerInfectionChance != -1.0 || world.getDifficulty() == Difficulty.NORMAL || world.getDifficulty() == Difficulty.HARD) && other instanceof Villager) {
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance == -1.0 && world.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
|
||||
return;
|
||||
}
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > level.paperConfig.zombieVillagerInfectionChance) {
|
||||
+ return;
|
||||
+ } // Paper end
|
||||
|
||||
Villager entityvillager = (Villager) entityliving;
|
||||
Villager entityvillager = (Villager) other;
|
||||
// CraftBukkit start
|
|
@ -8,22 +8,24 @@ faster on its own, however removing the try catch makes it
|
|||
easier to inline due to code size
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
index 87d7a87a2925f2c062658e960bb5128738828d9f..8a14bdda4a408ec1e2b51efeb35467835f62b42c 100644
|
||||
index 88b053d8181d2a5abdb2c5527529a81855e1de7c..59a77541bbda880ae8f84e3535a2b6112caa78fb 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -430,25 +430,29 @@ public class LevelChunk implements ChunkAccess {
|
||||
@@ -461,18 +461,20 @@ public class LevelChunk implements ChunkAccess {
|
||||
}
|
||||
|
||||
public FluidState getFluidState(int x, int y, int z) {
|
||||
- try {
|
||||
- if (y >= 0 && y >> 4 < this.sections.length) {
|
||||
- LevelChunkSection chunksection = this.sections[y >> 4];
|
||||
- int l = this.getSectionIndex(y);
|
||||
-
|
||||
- if (l >= 0 && l < this.sections.length) {
|
||||
- LevelChunkSection chunksection = this.sections[l];
|
||||
-
|
||||
- if (!LevelChunkSection.isEmpty(chunksection)) {
|
||||
- return chunksection.getFluidState(x & 15, y & 15, z & 15);
|
||||
+ //try { // Paper - remove try catch
|
||||
+ // try { // Paper - remove try catch
|
||||
+ // Paper start - reduce the number of ops in this call
|
||||
+ int index = y >> 4;
|
||||
+ int index = this.getSectionIndex(y);
|
||||
+ if (index >= 0 && index < this.sections.length) {
|
||||
+ LevelChunkSection chunksection = this.sections[index];
|
||||
+
|
||||
|
@ -34,17 +36,11 @@ index 87d7a87a2925f2c062658e960bb5128738828d9f..8a14bdda4a408ec1e2b51efeb3546783
|
|||
}
|
||||
|
||||
return Fluids.EMPTY.defaultFluidState();
|
||||
- } catch (Throwable throwable) {
|
||||
- CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting fluid state");
|
||||
- CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being got");
|
||||
+ /*} catch (Throwable throwable) { // Paper - remove try catch
|
||||
+ CrashReport crashreport = CrashReport.a(throwable, "Getting fluid state");
|
||||
+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being got");
|
||||
|
||||
- crashreportsystemdetails.setDetail("Location", () -> {
|
||||
- return CrashReportCategory.formatLocation(x, y, z);
|
||||
+ crashreportsystemdetails.a("Location", () -> {
|
||||
+ return CrashReportSystemDetails.a(i, j, k);
|
||||
+ /* // Paper - remove try catch
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting fluid state");
|
||||
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being got");
|
||||
@@ -482,6 +484,7 @@ public class LevelChunk implements ChunkAccess {
|
||||
});
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
|
@ -53,15 +49,15 @@ index 87d7a87a2925f2c062658e960bb5128738828d9f..8a14bdda4a408ec1e2b51efeb3546783
|
|||
|
||||
// CraftBukkit start
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
index c44d32f966c61497b4a8892eb51da3a71ad031d9..5e7f6000df129100ef306703f325af9f60da8ae6 100644
|
||||
index b5497272bc03a290298b5a829bdf653ac986866b..fa350db3f4ada07a385d9f57b46aa799effb6039 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
@@ -45,7 +45,7 @@ public class LevelChunkSection {
|
||||
@@ -42,7 +42,7 @@ public class LevelChunkSection {
|
||||
}
|
||||
|
||||
public FluidState getFluidState(int x, int y, int z) {
|
||||
- return ((BlockState) this.states.get(x, y, z)).getFluidState();
|
||||
+ return ((BlockState) this.states.get(x, y, z)).getFluidState(); // Paper - diff on change - we expect this to be effectively just getType(x, y, z).getFluid(). If this changes we need to check other patches that use IBlockData#getFluid.
|
||||
- return this.states.get(x, y, z).getFluidState();
|
||||
+ return this.states.get(x, y, z).getFluidState(); // Paper - diff on change - we expect this to be effectively just getType(x, y, z).getFluid(). If this changes we need to check other patches that use IBlockData#getFluid.
|
||||
}
|
||||
|
||||
public void acquire() {
|
|
@ -61,7 +61,7 @@ index 8bf4d2b8c38c02d6a5b2fea37113689a252f1571..da93d38fe63035e4ff198ada84a4431f
|
|||
ConfigurationSection section;
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2d579909b
|
||||
index 0000000000000000000000000000000000000000..da13ff17609b7bc8076d9297edf8decf01a2ed88
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/server/ticklist/PaperTickList.java
|
||||
@@ -0,0 +1,628 @@
|
||||
|
@ -168,7 +168,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+
|
||||
+ private void queueEntryForTick(final TickNextTickData<T> entry, final ServerChunkCache chunkProvider) {
|
||||
+ if (entry.tickState == STATE_SCHEDULED) {
|
||||
+ if (chunkProvider.isTickingReadyMainThread(entry.getPosition())) {
|
||||
+ if (chunkProvider.isTickingReadyMainThread(entry.pos)) {
|
||||
+ this.toTickThisTick.add(entry);
|
||||
+ entry.tickState = STATE_PENDING_TICK;
|
||||
+ } else {
|
||||
|
@ -179,13 +179,13 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ }
|
||||
+
|
||||
+ private void addToNotTickingReady(final TickNextTickData<T> entry) {
|
||||
+ this.pendingChunkTickLoad.computeIfAbsent(MCUtil.getCoordinateKey(entry.getPosition()), (long keyInMap) -> {
|
||||
+ this.pendingChunkTickLoad.computeIfAbsent(MCUtil.getCoordinateKey(entry.pos), (long keyInMap) -> {
|
||||
+ return new ArrayList<>();
|
||||
+ }).add(entry);
|
||||
+ }
|
||||
+
|
||||
+ private void addToSchedule(final TickNextTickData<T> entry) {
|
||||
+ long delay = entry.getTargetTick() - (this.currentTick + 1);
|
||||
+ long delay = entry.triggerTick - (this.currentTick + 1);
|
||||
+ if (delay < SHORT_SCHEDULE_TICK_THRESHOLD) {
|
||||
+ if (delay < 0) {
|
||||
+ // longScheduled orders by tick time, short scheduled does not
|
||||
|
@ -202,7 +202,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ entry.tickState = STATE_CANCELLED_TICK;
|
||||
+ // short/long scheduled will skip the entry
|
||||
+
|
||||
+ final BlockPos pos = entry.getPosition();
|
||||
+ final BlockPos pos = entry.pos;
|
||||
+ final long blockKey = MCUtil.getBlockKey(pos);
|
||||
+
|
||||
+ final ArrayList<TickNextTickData<T>> currentEntries = this.entriesByBlock.get(blockKey);
|
||||
|
@ -221,7 +221,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final long chunkKey = MCUtil.getCoordinateKey(entry.getPosition());
|
||||
+ final long chunkKey = MCUtil.getCoordinateKey(entry.pos);
|
||||
+
|
||||
+ ObjectRBTreeSet<TickNextTickData<T>> set = this.entriesByChunk.get(chunkKey);
|
||||
+
|
||||
|
@ -246,7 +246,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
+ long delay = entry.getTargetTick() - (this.currentTick + 1);
|
||||
+ long delay = entry.triggerTick - (this.currentTick + 1);
|
||||
+ if (delay >= SHORT_SCHEDULE_TICK_THRESHOLD) {
|
||||
+ this.longScheduled.remove(entry);
|
||||
+ }
|
||||
|
@ -274,7 +274,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+
|
||||
+ // we don't remove items from shortScheduled (but do from longScheduled) because they're cleared at the end of
|
||||
+ // this tick
|
||||
+ if (this.longScheduled.isEmpty() || this.longScheduled.first().getTargetTick() > currentTick) {
|
||||
+ if (this.longScheduled.isEmpty() || this.longScheduled.first().triggerTick > currentTick) {
|
||||
+ // nothing in longScheduled to worry about
|
||||
+ final TickListServerInterval<T> interval = this.shortScheduled[this.shortScheduledIndex];
|
||||
+ for (int i = 0, len = interval.byPriority.length; i < len; ++i) {
|
||||
|
@ -300,7 +300,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ longScheduledIterator.remove();
|
||||
+ if (longScheduledIterator.hasNext()) {
|
||||
+ longCurrent = longScheduledIterator.next();
|
||||
+ if (longCurrent.getTargetTick() > currentTick) {
|
||||
+ if (longCurrent.triggerTick > currentTick) {
|
||||
+ longCurrent = null;
|
||||
+ break;
|
||||
+ }
|
||||
|
@ -316,7 +316,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+
|
||||
+ // add remaining from long scheduled
|
||||
+ for (;;) {
|
||||
+ if (longCurrent == null || longCurrent.getTargetTick() > currentTick) {
|
||||
+ if (longCurrent == null || longCurrent.triggerTick > currentTick) {
|
||||
+ break;
|
||||
+ }
|
||||
+ longScheduledIterator.remove();
|
||||
|
@ -368,7 +368,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ continue;
|
||||
+ }
|
||||
+ try {
|
||||
+ if (chunkProvider.isTickingReadyMainThread(toTick.getPosition())) {
|
||||
+ if (chunkProvider.isTickingReadyMainThread(toTick.pos)) {
|
||||
+ toTick.tickState = STATE_TICKING;
|
||||
+ this.tickFunction.accept(toTick);
|
||||
+ if (toTick.tickState == STATE_TICKING) {
|
||||
|
@ -384,7 +384,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ CrashReport crashreport = CrashReport.forThrowable(thr, "Exception while ticking");
|
||||
+ CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being ticked");
|
||||
+
|
||||
+ CrashReportCategory.populateBlockDetails(crashreportsystemdetails, toTick.getPosition(), (BlockState) null);
|
||||
+ CrashReportCategory.populateBlockDetails(crashreportsystemdetails, this.world, toTick.pos, (BlockState) null);
|
||||
+ throw new ReportedException(crashreport);
|
||||
+ // end copy from TickListServer
|
||||
+ }
|
||||
|
@ -413,7 +413,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ }
|
||||
+ entry.tickState = STATE_UNSCHEDULED;
|
||||
+
|
||||
+ final BlockPos pos = entry.getPosition();
|
||||
+ final BlockPos pos = entry.pos;
|
||||
+ final long blockKey = MCUtil.getBlockKey(pos);
|
||||
+
|
||||
+ final ArrayList<TickNextTickData<T>> currentEntries = this.entriesByBlock.get(blockKey);
|
||||
|
@ -432,7 +432,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final long chunkKey = MCUtil.getCoordinateKey(entry.getPosition());
|
||||
+ final long chunkKey = MCUtil.getCoordinateKey(entry.pos);
|
||||
+
|
||||
+ ObjectRBTreeSet<TickNextTickData<T>> set = this.entriesByChunk.get(chunkKey);
|
||||
+
|
||||
|
@ -446,7 +446,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isPendingTickThisTick(final BlockPos blockposition, final T data) {
|
||||
+ public boolean willTickThisTick(final BlockPos blockposition, final T data) {
|
||||
+ final ArrayList<TickNextTickData<T>> entries = this.entriesByBlock.get(MCUtil.getBlockKey(blockposition));
|
||||
+
|
||||
+ if (entries == null) {
|
||||
|
@ -455,7 +455,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+
|
||||
+ for (int i = 0, size = entries.size(); i < size; ++i) {
|
||||
+ final TickNextTickData<T> entry = entries.get(i);
|
||||
+ if (entry.getData() == data && entry.tickState == STATE_PENDING_TICK) {
|
||||
+ if (entry.getType() == data && entry.tickState == STATE_PENDING_TICK) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
|
@ -464,7 +464,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isScheduledForTick(final BlockPos blockposition, final T data) {
|
||||
+ public boolean hasScheduledTick(final BlockPos blockposition, final T data) {
|
||||
+ final ArrayList<TickNextTickData<T>> entries = this.entriesByBlock.get(MCUtil.getBlockKey(blockposition));
|
||||
+
|
||||
+ if (entries == null) {
|
||||
|
@ -473,7 +473,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+
|
||||
+ for (int i = 0, size = entries.size(); i < size; ++i) {
|
||||
+ final TickNextTickData<T> entry = entries.get(i);
|
||||
+ if (entry.getData() == data && entry.tickState == STATE_SCHEDULED) {
|
||||
+ if (entry.getType() == data && entry.tickState == STATE_SCHEDULED) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
|
@ -482,22 +482,22 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void schedule(BlockPos blockPosition, T t, int i, TickPriority tickListPriority) {
|
||||
+ public void scheduleTick(BlockPos blockPosition, T t, int i, TickPriority tickListPriority) {
|
||||
+ this.schedule(blockPosition, t, i + this.currentTick, tickListPriority);
|
||||
+ }
|
||||
+
|
||||
+ public void schedule(final TickNextTickData<T> entry) {
|
||||
+ this.schedule(entry.getPosition(), entry.getData(), entry.getTargetTick(), entry.getPriority());
|
||||
+ this.schedule(entry.pos, entry.getType(), entry.triggerTick, entry.priority);
|
||||
+ }
|
||||
+
|
||||
+ public void schedule(final BlockPos pos, final T data, final long targetTick, final TickPriority priority) {
|
||||
+ final TickNextTickData<T> entry = new TickNextTickData<>(pos, data, targetTick, priority);
|
||||
+ if (this.excludeFromScheduling.test(entry.getData())) {
|
||||
+ if (this.excludeFromScheduling.test(entry.getType())) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (WARN_ON_EXCESSIVE_DELAY) {
|
||||
+ final long delay = entry.getTargetTick() - this.currentTick;
|
||||
+ final long delay = entry.triggerTick - this.currentTick;
|
||||
+ if (delay >= EXCESSIVE_DELAY_THRESHOLD) {
|
||||
+ MinecraftServer.LOGGER.warn("Entry " + entry.toString() + " has been scheduled with an excessive delay of: " + delay, new Throwable());
|
||||
+ }
|
||||
|
@ -514,7 +514,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ final TickNextTickData<T> currentEntry = currentEntries.get(i);
|
||||
+
|
||||
+ // entries are only blocked from scheduling if currentEntry.equals(toSchedule) && currentEntry is scheduled to tick (NOT including pending)
|
||||
+ if (currentEntry.getData() == entry.getData() && currentEntry.tickState == STATE_SCHEDULED) {
|
||||
+ if (currentEntry.getType() == entry.getType() && currentEntry.tickState == STATE_SCHEDULED) {
|
||||
+ // can't add
|
||||
+ return;
|
||||
+ }
|
||||
|
@ -524,7 +524,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+
|
||||
+ entry.tickState = STATE_SCHEDULED;
|
||||
+
|
||||
+ this.entriesByChunk.computeIfAbsent(MCUtil.getCoordinateKey(entry.getPosition()), (final long keyInMap) -> {
|
||||
+ this.entriesByChunk.computeIfAbsent(MCUtil.getCoordinateKey(entry.pos), (final long keyInMap) -> {
|
||||
+ return new ObjectRBTreeSet<>(TickListServerInterval.ENTRY_COMPARATOR);
|
||||
+ }).add(entry);
|
||||
+
|
||||
|
@ -541,19 +541,19 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ // i.e the y value is ignored? the x, z calc isn't correct?
|
||||
+ // however for the copy op they use the correct intersection, after using this one of course...
|
||||
+ private static boolean isBlockInSortof(final BoundingBox boundingBox, final BlockPos pos) {
|
||||
+ return pos.getX() >= boundingBox.getMinX() && pos.getX() < boundingBox.getMaxX() && pos.getZ() >= boundingBox.getMinZ() && pos.getZ() < boundingBox.getMaxZ();
|
||||
+ return pos.getX() >= boundingBox.minX() && pos.getX() < boundingBox.maxX() && pos.getZ() >= boundingBox.minZ() && pos.getZ() < boundingBox.maxZ();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<TickNextTickData<T>> getEntriesInBoundingBox(final BoundingBox structureboundingbox, final boolean removeReturned, final boolean excludeTicked) {
|
||||
+ if (structureboundingbox.getMinX() == structureboundingbox.getMaxX() || structureboundingbox.getMinZ() == structureboundingbox.getMaxZ()) {
|
||||
+ public List<TickNextTickData<T>> fetchTicksInArea(final BoundingBox structureboundingbox, final boolean removeReturned, final boolean excludeTicked) {
|
||||
+ if (structureboundingbox.minX() == structureboundingbox.maxX() || structureboundingbox.minZ() == structureboundingbox.maxZ()) {
|
||||
+ return Collections.emptyList(); // vanilla behaviour, check isBlockInSortof above
|
||||
+ }
|
||||
+
|
||||
+ final int lowerChunkX = structureboundingbox.getMinX() >> 4;
|
||||
+ final int upperChunkX = (structureboundingbox.getMaxX() - 1) >> 4; // subtract 1 since maxX is exclusive
|
||||
+ final int lowerChunkZ = structureboundingbox.getMinZ() >> 4;
|
||||
+ final int upperChunkZ = (structureboundingbox.getMaxZ() - 1) >> 4; // subtract 1 since maxZ is exclusive
|
||||
+ final int lowerChunkX = structureboundingbox.minX() >> 4;
|
||||
+ final int upperChunkX = (structureboundingbox.maxX() - 1) >> 4; // subtract 1 since maxX is exclusive
|
||||
+ final int lowerChunkZ = structureboundingbox.minZ() >> 4;
|
||||
+ final int upperChunkZ = (structureboundingbox.maxZ() - 1) >> 4; // subtract 1 since maxZ is exclusive
|
||||
+
|
||||
+ final int xChunksLength = (upperChunkX - lowerChunkX + 1);
|
||||
+ final int zChunksLength = (upperChunkZ - lowerChunkZ + 1);
|
||||
|
@ -579,7 +579,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ final int matchOne = (STATE_SCHEDULED | STATE_PENDING_TICK) | (excludeTicked ? 0 : (STATE_TICKING | STATE_TICKED));
|
||||
+
|
||||
+ MCUtil.mergeSortedSets((TickNextTickData<T> entry) -> {
|
||||
+ if (!isBlockInSortof(structureboundingbox, entry.getPosition())) {
|
||||
+ if (!isBlockInSortof(structureboundingbox, entry.pos)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ final int tickState = entry.tickState;
|
||||
|
@ -603,24 +603,24 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ @Override
|
||||
+ public void copy(BoundingBox structureboundingbox, BlockPos blockposition) {
|
||||
+ // start copy from TickListServer // TODO check on update
|
||||
+ List<TickNextTickData<T>> list = this.getEntriesInBoundingBox(structureboundingbox, false, false);
|
||||
+ List<TickNextTickData<T>> list = this.fetchTicksInArea(structureboundingbox, false, false);
|
||||
+ Iterator<TickNextTickData<T>> iterator = list.iterator();
|
||||
+
|
||||
+ while (iterator.hasNext()) {
|
||||
+ TickNextTickData<T> nextticklistentry = iterator.next();
|
||||
+
|
||||
+ if (structureboundingbox.hasPoint( nextticklistentry.getPosition())) {
|
||||
+ BlockPos blockposition1 = nextticklistentry.getPosition().add(blockposition);
|
||||
+ T t0 = nextticklistentry.getData();
|
||||
+ if (structureboundingbox.isInside( nextticklistentry.pos)) {
|
||||
+ BlockPos blockposition1 = nextticklistentry.pos.offset(blockposition);
|
||||
+ T t0 = nextticklistentry.getType();
|
||||
+
|
||||
+ this.schedule(new TickNextTickData<>(blockposition1, t0, nextticklistentry.getTargetTick(), nextticklistentry.getPriority()));
|
||||
+ this.schedule(new TickNextTickData<>(blockposition1, t0, nextticklistentry.triggerTick, nextticklistentry.priority));
|
||||
+ }
|
||||
+ }
|
||||
+ // end copy from TickListServer
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<TickNextTickData<T>> getEntriesInChunk(ChunkPos chunkPos, boolean removeReturned, boolean excludeTicked) {
|
||||
+ public List<TickNextTickData<T>> fetchTicksInChunk(ChunkPos chunkPos, boolean removeReturned, boolean excludeTicked) {
|
||||
+ // Vanilla DOES get the entries 2 blocks out of the chunk too, but that doesn't matter since we ignore chunks
|
||||
+ // not at ticking status, and ticking status requires neighbours loaded
|
||||
+ // so with this method we will reduce scheduler churning
|
||||
|
@ -651,16 +651,16 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ListTag serialize(ChunkPos chunkcoordintpair) {
|
||||
+ public ListTag save(ChunkPos chunkcoordintpair) {
|
||||
+ // start copy from TickListServer // TODO check on update
|
||||
+ List<TickNextTickData<T>> list = this.getEntriesInChunk(chunkcoordintpair, false, true);
|
||||
+ List<TickNextTickData<T>> list = this.fetchTicksInChunk(chunkcoordintpair, false, true);
|
||||
+
|
||||
+ return ServerTickList.serialize(this.getMinecraftKeyFrom, list, this.currentTick);
|
||||
+ return ServerTickList.saveTickList(this.getMinecraftKeyFrom, list, this.currentTick);
|
||||
+ // end copy from TickListServer
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTotalScheduledEntries() {
|
||||
+ public int size() {
|
||||
+ // good thing this is only used in debug reports // TODO check on update
|
||||
+ int ret = 0;
|
||||
+
|
||||
|
@ -695,7 +695,7 @@ index 0000000000000000000000000000000000000000..1ce556fb808a8c93106e26da7b24f9a2
|
|||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/server/ticklist/TickListServerInterval.java b/src/main/java/com/destroystokyo/paper/server/ticklist/TickListServerInterval.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..d40a7aff6c27883f3ae8ba878a94c97242619f2c
|
||||
index 0000000000000000000000000000000000000000..a1e6f49274a7ae8057a9112e0dd6597a8e58e6da
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/server/ticklist/TickListServerInterval.java
|
||||
@@ -0,0 +1,41 @@
|
||||
|
@ -713,7 +713,7 @@ index 0000000000000000000000000000000000000000..d40a7aff6c27883f3ae8ba878a94c972
|
|||
+ public static final Comparator<TickNextTickData<?>> ENTRY_COMPARATOR_BY_ID = (entry1, entry2) -> {
|
||||
+ return Long.compare(entry1.getId(), entry2.getId());
|
||||
+ };
|
||||
+ public static final Comparator<TickNextTickData<?>> ENTRY_COMPARATOR = (Comparator)TickNextTickData.comparator();
|
||||
+ public static final Comparator<TickNextTickData<?>> ENTRY_COMPARATOR = (Comparator)TickNextTickData.createTimeComparator();
|
||||
+
|
||||
+ // we do not record the interval, this class is meant to be used on a ring buffer
|
||||
+
|
||||
|
@ -727,11 +727,11 @@ index 0000000000000000000000000000000000000000..d40a7aff6c27883f3ae8ba878a94c972
|
|||
+ }
|
||||
+
|
||||
+ public void addEntryLast(final TickNextTickData<T> entry) {
|
||||
+ this.byPriority[entry.getPriority().ordinal()].addLast(entry);
|
||||
+ this.byPriority[entry.priority.ordinal()].addLast(entry);
|
||||
+ }
|
||||
+
|
||||
+ public void addEntryFirst(final TickNextTickData<T> entry) {
|
||||
+ this.byPriority[entry.getPriority().ordinal()].addFirst(entry);
|
||||
+ this.byPriority[entry.priority.ordinal()].addFirst(entry);
|
||||
+ }
|
||||
+
|
||||
+ public void clear() {
|
||||
|
@ -888,64 +888,63 @@ index 0000000000000000000000000000000000000000..118988c39e58f28e8a2851792b9c014f
|
|||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
index 3db77d9eda98eacb099135643aff5e94751f4c7c..595abf528a7862478100770987906af1b13439fe 100644
|
||||
--- a/src/main/java/net/minecraft/core/BlockPos.java
|
||||
+++ b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
@@ -111,6 +111,7 @@ public class BlockPos extends Vec3i {
|
||||
return x == 0 && y == 0 && z == 0 ? this : new BlockPos(this.getX() + x, this.getY() + y, this.getZ() + z);
|
||||
}
|
||||
|
||||
+ public final BlockPos add(Vec3i baseblockposition) { return this.offset(baseblockposition); } // Paper - OBFHELPER
|
||||
public BlockPos offset(Vec3i pos) {
|
||||
return this.offset(pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index 77d3969200ac6f88f3af9add05def0b627ce6db3..d12d5459c847d3f0d655c85e31d81c27b7a2face 100644
|
||||
index 995d7977233f0d7683c00a75c3833f9a1eba7f92..58369d70bcd8b2c25609b6f101d9cbe2031df352 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -495,7 +495,9 @@ public class ChunkHolder {
|
||||
@@ -86,6 +86,19 @@ public class ChunkHolder {
|
||||
return null;
|
||||
}
|
||||
// Paper end - no-tick view distance
|
||||
+ // Paper start
|
||||
+ public final boolean isEntityTickingReady() {
|
||||
+ return this.isEntityTickingReady;
|
||||
+ }
|
||||
+
|
||||
+ public final boolean isTickingReady() {
|
||||
+ return this.isTickingReady;
|
||||
+ }
|
||||
+
|
||||
+ public final boolean isFullChunkReady() {
|
||||
+ return this.isFullChunkReady;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public ChunkHolder(ChunkPos pos, int level, LevelHeightAccessor world, LevelLightEngine lightingProvider, ChunkHolder.LevelChangeListener levelUpdateListener, ChunkHolder.PlayerProvider playersWatchingChunkProvider) {
|
||||
this.futures = new AtomicReferenceArray(ChunkHolder.CHUNK_STATUSES.size());
|
||||
@@ -547,6 +560,10 @@ public class ChunkHolder {
|
||||
either.ifLeft(chunk -> {
|
||||
// note: Here is a very good place to add callbacks to logic waiting on this.
|
||||
ChunkHolder.this.isTickingReady = true;
|
||||
|
||||
|
||||
-
|
||||
+
|
||||
+ // Paper start - rewrite ticklistserver
|
||||
+ ChunkHolder.this.chunkMap.level.onChunkSetTicking(ChunkHolder.this.pos.x, ChunkHolder.this.pos.z);
|
||||
+ // Paper end - rewrite ticklistserver
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
// Paper end
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 3aeb8426b0461ec572c1499116be80f968bb4104..e2b1541042bceac965411e3176d08c61f217c07f 100644
|
||||
index 7cbd3db81c73d466a6e6012c1c91698b53a0cb86..382a68c76e8946840de62f05483870689de80278 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -21,6 +21,7 @@ import net.minecraft.Util;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
+import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
@@ -217,6 +218,13 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -220,6 +220,12 @@ public class ServerChunkCache extends ChunkSource {
|
||||
}, this.mainThreadProcessor);
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - rewrite ticklistserver
|
||||
+ public final boolean isTickingReadyMainThread(BlockPos pos) {
|
||||
+ ChunkHolder chunk = this.chunkMap.getUpdatingChunkIfPresent(MCUtil.getCoordinateKey(pos));
|
||||
+ ChunkHolder chunk = this.chunkMap.getUpdatingChunkIfPresent(net.minecraft.server.MCUtil.getCoordinateKey(pos));
|
||||
+ return chunk != null && chunk.isTickingReady();
|
||||
+ }
|
||||
+ // Paper end - rewrite ticklistserver
|
||||
+
|
||||
public ServerChunkCache(ServerLevel worldserver, LevelStorageSource.LevelStorageAccess convertable_conversionsession, DataFixer dataFixer, StructureManager structureManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, boolean flag, ChunkProgressListener worldloadlistener, Supplier<DimensionDataStorage> supplier) {
|
||||
this.level = worldserver;
|
||||
this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(worldserver);
|
||||
|
||||
public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureManager structureManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, boolean flag, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkstatusupdatelistener, Supplier<DimensionDataStorage> supplier) {
|
||||
this.level = world;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 5d85895456b5d65954889cadf932027ea23b400b..9da0d98bc2ed7876a00a734690ed42f01b9a9a9b 100644
|
||||
index ecb9c5a1958c89494417bdb3e6c6363f3fc84534..385b8e707406173ea5258aff87af719ce93aecf3 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -292,6 +292,15 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
@@ -286,6 +286,15 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
}
|
||||
// Paper end
|
||||
|
||||
|
@ -960,273 +959,127 @@ index 5d85895456b5d65954889cadf932027ea23b400b..9da0d98bc2ed7876a00a734690ed42f0
|
|||
+
|
||||
// Add env and gen to constructor, WorldData -> WorldDataServer
|
||||
public ServerLevel(MinecraftServer minecraftserver, Executor executor, LevelStorageSource.LevelStorageAccess convertable_conversionsession, ServerLevelData iworlddataserver, ResourceKey<net.minecraft.world.level.Level> resourcekey, DimensionType dimensionmanager, ChunkProgressListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<CustomSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
super(iworlddataserver, resourcekey, dimensionmanager, minecraftserver::getProfiler, false, flag, i, gen, env, executor); // Paper pass executor
|
||||
@@ -299,12 +308,21 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
convertable = convertable_conversionsession;
|
||||
uuid = WorldUUID.getUUID(convertable_conversionsession.levelPath.toFile());
|
||||
// CraftBukkit end
|
||||
- this.blockTicks = new ServerTickList<>(this, (block) -> {
|
||||
- return block == null || block.defaultBlockState().isAir();
|
||||
- }, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings
|
||||
- this.liquidTicks = new ServerTickList<>(this, (fluidtype) -> {
|
||||
- return fluidtype == null || fluidtype == Fluids.EMPTY;
|
||||
- }, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper - Timings
|
||||
// Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error
|
||||
@@ -302,13 +311,19 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
DefaultedRegistry registryblocks = Registry.BLOCK;
|
||||
|
||||
Objects.requireNonNull(registryblocks);
|
||||
- this.blockTicks = new ServerTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // CraftBukkit - decompile error // Paper - Timings
|
||||
+ // this.blockTicks = new ServerTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // CraftBukkit - decompile error // Paper - Timings // Paper - copied down
|
||||
Predicate<Fluid> predicate2 = (fluidtype) -> { // CraftBukkit - decompile error
|
||||
return fluidtype == null || fluidtype == Fluids.EMPTY;
|
||||
};
|
||||
registryblocks = Registry.FLUID;
|
||||
Objects.requireNonNull(registryblocks);
|
||||
+ if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) {
|
||||
+ this.blockTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> {
|
||||
+ return block == null || block.defaultBlockState().isAir();
|
||||
+ }, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings
|
||||
+ this.liquidTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (fluidtype) -> {
|
||||
+ return fluidtype == null || fluidtype == Fluids.EMPTY;
|
||||
+ }, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper - Timings
|
||||
+ this.blockTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings
|
||||
+ this.liquidTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, predicate2, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper timings
|
||||
+ } else {
|
||||
+ this.blockTicks = new ServerTickList<>(this, (block) -> {
|
||||
+ return block == null || block.defaultBlockState().isAir();
|
||||
+ }, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings
|
||||
+ this.liquidTicks = new ServerTickList<>(this, (fluidtype) -> {
|
||||
+ return fluidtype == null || fluidtype == Fluids.EMPTY;
|
||||
+ }, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper - Timings
|
||||
+ this.blockTicks = new ServerTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // CraftBukkit - decompile error // Paper - Timings & copied from above
|
||||
this.liquidTicks = new ServerTickList<>(this, predicate2, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // CraftBukkit - decompile error // Paper - Timings
|
||||
+ }
|
||||
this.navigations = Sets.newHashSet();
|
||||
this.navigatingMobs = new ObjectOpenHashSet();
|
||||
this.blockEvents = new ObjectLinkedOpenHashSet();
|
||||
this.tickTime = flag1;
|
||||
@@ -639,7 +657,9 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
this.dragonParts = new Int2ObjectOpenHashMap();
|
||||
@@ -629,7 +644,9 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
if (this.tickTime) {
|
||||
long i = this.levelData.getGameTime() + 1L;
|
||||
|
||||
- this.worldDataServer.setGameTime(i);
|
||||
+ this.worldDataServer.setGameTime(i); // Paper - diff on change, we want the below to be ran right after this
|
||||
- this.serverLevelData.setGameTime(i);
|
||||
+ this.serverLevelData.setGameTime(i); ; // Paper - diff on change, we want the below to be ran right after this
|
||||
+ this.blockTicks.nextTick(); // Paper
|
||||
+ this.liquidTicks.nextTick(); // Paper
|
||||
this.worldDataServer.getScheduledEvents().tick(this.server, i);
|
||||
this.serverLevelData.getScheduledEvents().tick(this.server, i);
|
||||
if (this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) {
|
||||
this.setDayTime(this.levelData.getDayTime() + 1L);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/ChunkTickList.java b/src/main/java/net/minecraft/world/level/ChunkTickList.java
|
||||
index 16757eb9c03c0dab51a7a1b569daff81cf9654f3..3008e0c42efe908e45dba1a1437928d4d4378f24 100644
|
||||
index 1a05edf041cf4aeee7c165fec564ce45adbdd5c7..febc837d324cbe2cd83aea6c1e0d298c70f45f78 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/ChunkTickList.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/ChunkTickList.java
|
||||
@@ -9,6 +9,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
@@ -15,7 +15,7 @@ public class ChunkTickList<T> implements TickList<T> {
|
||||
|
||||
public class ChunkTickList<T> implements TickList<T> {
|
||||
public ChunkTickList(Function<T, ResourceLocation> identifierProvider, List<TickNextTickData<T>> scheduledTicks, long startTime) {
|
||||
this(identifierProvider, scheduledTicks.stream().map((tickNextTickData) -> {
|
||||
- return new ChunkTickList.ScheduledTick(tickNextTickData.getType(), tickNextTickData.pos, (int)(tickNextTickData.triggerTick - startTime), tickNextTickData.priority);
|
||||
+ return new ChunkTickList.ScheduledTick<>(tickNextTickData.getType(), tickNextTickData.pos, (int)(tickNextTickData.triggerTick - startTime), tickNextTickData.priority); // Paper - decompile error
|
||||
}).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@@ -61,6 +62,8 @@ public class ChunkTickList<T> implements TickList<T> {
|
||||
return nbttaglist;
|
||||
@@ -56,6 +56,7 @@ public class ChunkTickList<T> implements TickList<T> {
|
||||
return listTag;
|
||||
}
|
||||
|
||||
+ private static final int MAX_TICK_DELAY = Integer.getInteger("paper.ticklist-max-tick-delay", -1).intValue(); // Paper - clean up broken entries
|
||||
+
|
||||
public static <T> ChunkTickList<T> create(ListTag ticks, Function<T, ResourceLocation> function, Function<ResourceLocation, T> function1) {
|
||||
public static <T> ChunkTickList<T> create(ListTag ticks, Function<T, ResourceLocation> function, Function<ResourceLocation, T> function2) {
|
||||
List<ChunkTickList.ScheduledTick<T>> list = Lists.newArrayList();
|
||||
|
||||
@@ -71,7 +74,14 @@ public class ChunkTickList<T> implements TickList<T> {
|
||||
if (t0 != null) {
|
||||
BlockPos blockposition = new BlockPos(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z"));
|
||||
|
||||
- list.add(new ChunkTickList.ScheduledTick<>(t0, blockposition, nbttagcompound.getInt("t"), TickPriority.byValue(nbttagcompound.getInt("p"))));
|
||||
@@ -64,7 +65,14 @@ public class ChunkTickList<T> implements TickList<T> {
|
||||
T object = function2.apply(new ResourceLocation(compoundTag.getString("i")));
|
||||
if (object != null) {
|
||||
BlockPos blockPos = new BlockPos(compoundTag.getInt("x"), compoundTag.getInt("y"), compoundTag.getInt("z"));
|
||||
- list.add(new ChunkTickList.ScheduledTick<>(object, blockPos, compoundTag.getInt("t"), TickPriority.byValue(compoundTag.getInt("p"))));
|
||||
+ // Paper start - clean up broken entries
|
||||
+ int delay = nbttagcompound.getInt("t");
|
||||
+ int delay = compoundTag.getInt("t");
|
||||
+ if (MAX_TICK_DELAY > 0 && delay > MAX_TICK_DELAY) {
|
||||
+ MinecraftServer.LOGGER.warn("Dropping tick for pos " + blockposition + ", tick delay " + delay);
|
||||
+ net.minecraft.server.MinecraftServer.LOGGER.warn("Dropping tick for pos " + blockPos + ", tick delay " + delay);
|
||||
+ continue;
|
||||
+ }
|
||||
+ list.add(new ChunkTickList.ScheduledTick<>(t0, blockposition, delay, TickPriority.byValue(nbttagcompound.getInt("p"))));
|
||||
+ // Paper end - clean up broken entries
|
||||
+ list.add(new ChunkTickList.ScheduledTick<>(object, blockPos, delay, TickPriority.byValue(compoundTag.getInt("p"))));
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/ServerTickList.java b/src/main/java/net/minecraft/world/level/ServerTickList.java
|
||||
index 10ac1ba0a3d192486f22c2127d5bc30353f0edb6..65b3a16f40a295c2916be2a9fd019b452fb65e4f 100644
|
||||
index 702203f4a4fa4fc03c35ec974a97e08ed0f3c67c..609c8ece9e9f151875bf8191cc671206ee1e5f68 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/ServerTickList.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/ServerTickList.java
|
||||
@@ -50,7 +50,16 @@ public class ServerTickList<T> implements TickList<T> {
|
||||
@@ -49,6 +49,9 @@ public class ServerTickList<T> implements TickList<T> {
|
||||
private final co.aikar.timings.Timing timingTicking; // Paper
|
||||
// Paper end
|
||||
|
||||
+ // Paper start
|
||||
+ public void nextTick() {}
|
||||
+ // Paper end
|
||||
+
|
||||
+ public void tick() {
|
||||
+ // Paper start - allow overriding
|
||||
+ this.tick();
|
||||
+ }
|
||||
public void tick() {
|
||||
+ // Paper end
|
||||
int i = this.tickNextTickList.size();
|
||||
|
||||
if (false) { // CraftBukkit
|
||||
@@ -118,28 +127,43 @@ public class ServerTickList<T> implements TickList<T> {
|
||||
|
||||
@Override
|
||||
public boolean willTickThisTick(BlockPos pos, T object) {
|
||||
- return this.currentlyTicking.contains(new TickNextTickData<>(pos, object));
|
||||
+ // Paper start - allow overriding
|
||||
+ return this.isPendingTickThisTick(pos, object);
|
||||
+ }
|
||||
+ public boolean isPendingTickThisTick(BlockPos blockposition, T t0) {
|
||||
+ // Paper end
|
||||
+ return this.currentlyTicking.contains(new TickNextTickData<>(blockposition, t0));
|
||||
@@ -190,7 +193,7 @@ public class ServerTickList<T> implements TickList<T> {
|
||||
return ServerTickList.saveTickList(this.toId, list, this.level.getGameTime());
|
||||
}
|
||||
|
||||
public List<TickNextTickData<T>> fetchTicksInChunk(ChunkPos chunkcoordintpair, boolean updateState, boolean getStaleTicks) {
|
||||
+ // Paper start - allow overriding
|
||||
+ return this.getEntriesInChunk(chunkcoordintpair, updateState, getStaleTicks);
|
||||
+ }
|
||||
+ public List<TickNextTickData<T>> getEntriesInChunk(ChunkPos chunkcoordintpair, boolean flag, boolean flag1) {
|
||||
+ // Paper end
|
||||
int i = (chunkcoordintpair.x << 4) - 2;
|
||||
int j = i + 16 + 2;
|
||||
int k = (chunkcoordintpair.z << 4) - 2;
|
||||
int l = k + 16 + 2;
|
||||
|
||||
- return this.fetchTicksInArea(new BoundingBox(i, 0, k, j, 256, l), updateState, getStaleTicks);
|
||||
+ return this.fetchTicksInArea(new BoundingBox(i, 0, k, j, 256, l), flag, flag1);
|
||||
}
|
||||
|
||||
public List<TickNextTickData<T>> fetchTicksInArea(BoundingBox bounds, boolean updateState, boolean getStaleTicks) {
|
||||
- List<TickNextTickData<T>> list = this.fetchTicksInArea((List) null, this.tickNextTickList, bounds, updateState);
|
||||
+ // Paper start - allow overriding
|
||||
+ return this.getEntriesInBoundingBox(bounds, updateState, getStaleTicks);
|
||||
+ }
|
||||
+ public List<TickNextTickData<T>> getEntriesInBoundingBox(BoundingBox structureboundingbox, boolean flag, boolean flag1) {
|
||||
+ // Paper end
|
||||
+ List<TickNextTickData<T>> list = this.fetchTicksInArea((List) null, this.tickNextTickList, structureboundingbox, flag);
|
||||
|
||||
- if (updateState && list != null) {
|
||||
+ if (flag && list != null) {
|
||||
this.tickNextTickSet.removeAll(list);
|
||||
}
|
||||
|
||||
- list = this.fetchTicksInArea(list, this.currentlyTicking, bounds, updateState);
|
||||
- if (!getStaleTicks) {
|
||||
- list = this.fetchTicksInArea(list, this.alreadyTicked, bounds, updateState);
|
||||
+ list = this.fetchTicksInArea(list, this.currentlyTicking, structureboundingbox, flag);
|
||||
+ if (!flag1) {
|
||||
+ list = this.fetchTicksInArea(list, this.alreadyTicked, structureboundingbox, flag);
|
||||
}
|
||||
|
||||
return list == null ? Collections.emptyList() : list;
|
||||
@@ -170,14 +194,19 @@ public class ServerTickList<T> implements TickList<T> {
|
||||
}
|
||||
|
||||
public void copy(BoundingBox box, BlockPos offset) {
|
||||
- List<TickNextTickData<T>> list = this.fetchTicksInArea(box, false, false);
|
||||
+ // Paper start - allow overriding
|
||||
+ this.copy(box, offset);
|
||||
+ }
|
||||
+ public void copy(BoundingBox structureboundingbox, BlockPos blockposition) {
|
||||
+ // Paper end
|
||||
+ List<TickNextTickData<T>> list = this.fetchTicksInArea(structureboundingbox, false, false);
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
TickNextTickData<T> nextticklistentry = (TickNextTickData) iterator.next();
|
||||
|
||||
- if (box.isInside((Vec3i) nextticklistentry.pos)) {
|
||||
- BlockPos blockposition1 = nextticklistentry.pos.offset((Vec3i) offset);
|
||||
+ if (structureboundingbox.isInside((Vec3i) nextticklistentry.pos)) {
|
||||
+ BlockPos blockposition1 = nextticklistentry.pos.offset((Vec3i) blockposition);
|
||||
T t0 = nextticklistentry.getType();
|
||||
|
||||
this.addTickData(new TickNextTickData<>(blockposition1, t0, nextticklistentry.triggerTick, nextticklistentry.priority));
|
||||
@@ -187,11 +216,17 @@ public class ServerTickList<T> implements TickList<T> {
|
||||
}
|
||||
|
||||
public ListTag save(ChunkPos chunkcoordintpair) {
|
||||
+ // Paper start - allow overriding
|
||||
+ return this.serialize(chunkcoordintpair);
|
||||
+ }
|
||||
+ public ListTag serialize(ChunkPos chunkcoordintpair) {
|
||||
+ // Paper end
|
||||
List<TickNextTickData<T>> list = this.fetchTicksInChunk(chunkcoordintpair, false, true);
|
||||
|
||||
return saveTickList(this.toId, list, this.level.getGameTime());
|
||||
}
|
||||
|
||||
+ public static <T> ListTag serialize(Function<T, ResourceLocation> function, Iterable<TickNextTickData<T>> iterable, long i) { return ServerTickList.saveTickList(function, iterable, i); } // Paper - OBFHELPER
|
||||
private static <T> ListTag saveTickList(Function<T, ResourceLocation> identifierProvider, Iterable<TickNextTickData<T>> scheduledTicks, long time) {
|
||||
- private static <T> ListTag saveTickList(Function<T, ResourceLocation> identifierProvider, Iterable<TickNextTickData<T>> scheduledTicks, long time) {
|
||||
+ public static <T> ListTag saveTickList(Function<T, ResourceLocation> identifierProvider, Iterable<TickNextTickData<T>> scheduledTicks, long time) { // Paper - private -> public
|
||||
ListTag nbttaglist = new ListTag();
|
||||
Iterator iterator = scheduledTicks.iterator();
|
||||
@@ -214,13 +249,23 @@ public class ServerTickList<T> implements TickList<T> {
|
||||
|
||||
@Override
|
||||
public boolean hasScheduledTick(BlockPos pos, T object) {
|
||||
- return this.tickNextTickSet.contains(new TickNextTickData<>(pos, object));
|
||||
+ // Paper start - allow overriding
|
||||
+ return this.isScheduledForTick(pos, object);
|
||||
+ }
|
||||
+ public boolean isScheduledForTick(BlockPos blockposition, T t0) {
|
||||
+ // Paper end
|
||||
+ return this.tickNextTickSet.contains(new TickNextTickData<>(blockposition, t0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleTick(BlockPos pos, T object, int delay, TickPriority priority) {
|
||||
- if (!this.ignore.test(object)) {
|
||||
- this.addTickData(new TickNextTickData<>(pos, object, (long) delay + this.level.getGameTime(), priority));
|
||||
+ // Paper start - allow overriding
|
||||
+ this.schedule(pos, object, delay, priority);
|
||||
+ }
|
||||
+ public void schedule(BlockPos blockposition, T t0, int i, TickPriority ticklistpriority) {
|
||||
+ // Paper end
|
||||
+ if (!this.ignore.test(t0)) {
|
||||
+ this.addTickData(new TickNextTickData<>(blockposition, t0, (long) i + this.level.getGameTime(), ticklistpriority));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -234,6 +279,11 @@ public class ServerTickList<T> implements TickList<T> {
|
||||
}
|
||||
|
||||
public int size() {
|
||||
+ // Paper start - allow overriding
|
||||
+ return this.getTotalScheduledEntries();
|
||||
+ }
|
||||
+ public int getTotalScheduledEntries() {
|
||||
+ // Paper end
|
||||
return this.tickNextTickSet.size();
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/TickNextTickData.java b/src/main/java/net/minecraft/world/level/TickNextTickData.java
|
||||
index 90833389022d7412bdda8868a356b84f62a00e03..61cdaf45368dcc40f3311e8b7f8637a6c93a2d76 100644
|
||||
index 3b8c04f6ffd7e6c197465aa1caf633ba92529472..6b4b7c290b623a9821734ef74a2e566343e3c5bd 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/TickNextTickData.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/TickNextTickData.java
|
||||
@@ -6,11 +6,13 @@ import net.minecraft.core.BlockPos;
|
||||
public class TickNextTickData<T> {
|
||||
|
||||
private static final java.util.concurrent.atomic.AtomicLong COUNTER = new java.util.concurrent.atomic.AtomicLong(); // Paper - async chunk loading
|
||||
- private final T type;
|
||||
- public final BlockPos pos;
|
||||
- public final long triggerTick;
|
||||
- public final TickPriority priority;
|
||||
@@ -9,7 +9,9 @@ public class TickNextTickData<T> {
|
||||
public final BlockPos pos;
|
||||
public final long triggerTick;
|
||||
public final TickPriority priority;
|
||||
- private final long c;
|
||||
+ private final T type; public final T getData() { return this.type; } // Paper - OBFHELPER
|
||||
+ public final BlockPos pos; public final BlockPos getPosition() { return this.pos; } // Paper - OBFHELPER
|
||||
+ public final long triggerTick; public final long getTargetTick() { return this.triggerTick; } // Paper - OBFHELPER
|
||||
+ public final TickPriority priority; public final TickPriority getPriority() { return this.priority; } // Paper - OBFHELPER
|
||||
+ private final long c; public final long getId() { return this.c; } // Paper - OBFHELPER
|
||||
+ private final int hash; // Paper
|
||||
+ public int tickState; // Paper
|
||||
|
||||
public TickNextTickData(BlockPos pos, T t) {
|
||||
this(pos, t, 0L, TickPriority.NORMAL);
|
||||
@@ -22,6 +24,7 @@ public class TickNextTickData<T> {
|
||||
@@ -21,6 +23,7 @@ public class TickNextTickData<T> {
|
||||
this.type = t;
|
||||
this.triggerTick = time;
|
||||
this.priority = priority;
|
||||
+ this.hash = this.computeHash(); // Paper
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
@@ -34,19 +37,31 @@ public class TickNextTickData<T> {
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@@ -35,17 +38,27 @@ public class TickNextTickData<T> {
|
||||
|
||||
+ // Paper start - optimize hashcode
|
||||
+ @Override
|
||||
@Override
|
||||
public int hashCode() {
|
||||
+ // Paper start - optimize hashcode
|
||||
+ return this.hash;
|
||||
+ }
|
||||
+ public final int computeHash() {
|
||||
|
@ -1234,68 +1087,26 @@ index 90833389022d7412bdda8868a356b84f62a00e03..61cdaf45368dcc40f3311e8b7f8637a6
|
|||
return this.pos.hashCode();
|
||||
}
|
||||
|
||||
- public static <T> Comparator<Object> createTimeComparator() { // Paper - decompile fix
|
||||
- return Comparator.comparingLong((nextticklistentry) -> {
|
||||
- return ((TickNextTickData<T>) nextticklistentry).triggerTick; // Paper - decompile fix
|
||||
- }).thenComparing((nextticklistentry) -> {
|
||||
- return ((TickNextTickData<T>) nextticklistentry).priority; // Paper - decompile fix
|
||||
- }).thenComparingLong((nextticklistentry) -> {
|
||||
- return ((TickNextTickData<T>) nextticklistentry).c; // Paper - decompile fix
|
||||
public static <T> Comparator<TickNextTickData<T>> createTimeComparator() {
|
||||
- return Comparator.<TickNextTickData<T>>comparingLong((tickNextTickData) -> { // Paper - decompile fix
|
||||
- return tickNextTickData.triggerTick;
|
||||
- }).thenComparing((tickNextTickData) -> {
|
||||
- return tickNextTickData.priority;
|
||||
- }).thenComparingLong((tickNextTickData) -> {
|
||||
- return tickNextTickData.c;
|
||||
- });
|
||||
+ // Paper start - let's not use more functional code for no reason.
|
||||
+ public static <T> Comparator<Object> comparator() { return TickNextTickData.createTimeComparator(); } // Paper - OBFHELPER
|
||||
+ public static <T> Comparator<Object> createTimeComparator() {
|
||||
+ return (Comparator)(Comparator<TickNextTickData>)(TickNextTickData nextticklistentry, TickNextTickData nextticklistentry1) -> {
|
||||
+ int i = Long.compare(nextticklistentry.getTargetTick(), nextticklistentry1.getTargetTick());
|
||||
+ // Paper start - let's not use more functional code for no reason.
|
||||
+ return (Comparator) (Comparator<TickNextTickData>) (TickNextTickData nextticklistentry, TickNextTickData nextticklistentry1) -> {
|
||||
+ int i = Long.compare(nextticklistentry.triggerTick, nextticklistentry1.triggerTick);
|
||||
+
|
||||
+ if (i != 0) {
|
||||
+ return i;
|
||||
+ } else {
|
||||
+ i = nextticklistentry.getPriority().compareTo(nextticklistentry1.getPriority());
|
||||
+ i = nextticklistentry.priority.compareTo(nextticklistentry1.priority);
|
||||
+ return i != 0 ? i : Long.compare(nextticklistentry.getId(), nextticklistentry1.getId());
|
||||
+ }
|
||||
+ };
|
||||
}
|
||||
+ // Paper end - let's not use more functional code for no reason.
|
||||
|
||||
public String toString() {
|
||||
return this.type + ": " + this.pos + ", " + this.triggerTick + ", " + this.priority + ", " + this.c;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/BoundingBox.java b/src/main/java/net/minecraft/world/level/levelgen/structure/BoundingBox.java
|
||||
index 76bea58d35d352ee6f3d4bd0d10af3b6d615ae2c..4288fa253668196e6c32a876f18ec496fb3abad6 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/BoundingBox.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/BoundingBox.java
|
||||
@@ -8,12 +8,12 @@ import net.minecraft.nbt.IntArrayTag;
|
||||
|
||||
public class BoundingBox {
|
||||
|
||||
- public int x0;
|
||||
- public int y0;
|
||||
- public int z0;
|
||||
- public int x1;
|
||||
- public int y1;
|
||||
- public int z1;
|
||||
+ public int x0; public final int getMinX() { return this.x0; } // Paper - OBFHELPER
|
||||
+ public int y0; public final int getMinY() { return this.y0; } // Paper - OBFHELPER
|
||||
+ public int z0; public final int getMinZ() { return this.z0; } // Paper - OBFHELPER
|
||||
+ public int x1; public final int getMaxX() { return this.x1; } // Paper - OBFHELPER
|
||||
+ public int y1; public final int getMaxY() { return this.y1; } // Paper - OBFHELPER
|
||||
+ public int z1; public final int getMaxZ() { return this.z1; } // Paper - OBFHELPER
|
||||
|
||||
public BoundingBox() {}
|
||||
|
||||
@@ -92,6 +92,7 @@ public class BoundingBox {
|
||||
this.y1 = 512;
|
||||
+ // Paper end - let's not use more functional code for no reason.
|
||||
}
|
||||
|
||||
+ public final boolean intersects(BoundingBox boundingBox) { return this.intersects(boundingBox); } // Paper - OBFHELPER
|
||||
public boolean intersects(BoundingBox other) {
|
||||
return this.x1 >= other.x0 && this.x0 <= other.x1 && this.z1 >= other.z0 && this.z0 <= other.z1 && this.y1 >= other.y0 && this.y0 <= other.y1;
|
||||
}
|
||||
@@ -126,6 +127,7 @@ public class BoundingBox {
|
||||
this.move(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
|
||||
}
|
||||
|
||||
+ public final boolean hasPoint(Vec3i baseblockposition) { return this.isInside(baseblockposition); } // Paper - OBFHELPER
|
||||
public boolean isInside(Vec3i vec) {
|
||||
return vec.getX() >= this.x0 && vec.getX() <= this.x1 && vec.getZ() >= this.z0 && vec.getZ() <= this.z1 && vec.getY() >= this.y0 && vec.getY() <= this.y1;
|
||||
}
|
||||
@Override
|
|
@ -10,10 +10,10 @@ When not per player it will use the Vanilla mechanic of one delay per
|
|||
world and the world age for the start day.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 525d702d78a609af987ebd2c32169b873e5c05ed..6c8e9d498c9a30a1aa88494ba09c3cae012a8fa1 100644
|
||||
index b57d9c84db5685b86cb077e3b42db7a8578d6f62..9664786d471b949880030f5c6271bf9c12529326 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -582,10 +582,21 @@ public class PaperWorldConfig {
|
||||
@@ -428,10 +428,21 @@ public class PaperWorldConfig {
|
||||
}
|
||||
|
||||
public boolean disablePillagerPatrols = false;
|
||||
|
@ -36,10 +36,10 @@ index 525d702d78a609af987ebd2c32169b873e5c05ed..6c8e9d498c9a30a1aa88494ba09c3cae
|
|||
private void entitiesTargetWithFollowRange() {
|
||||
entitiesTargetWithFollowRange = getBoolean("entities-target-with-follow-range", entitiesTargetWithFollowRange);
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 7f4e81ee3339e90b8525541dccf6dea187853cf7..a469016c43251f16913a365c4131b2448eaa4c48 100644
|
||||
index bffc897cb88a54c36432c98264f3416051aeab17..5b5a0c0db79452ee07c40bf7693b6701dbe0b615 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -213,6 +213,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
@@ -219,6 +219,7 @@ public class ServerPlayer extends Player {
|
||||
public boolean wonGame;
|
||||
private int containerUpdateDelay; // Paper
|
||||
public long loginTime; // Paper
|
||||
|
@ -47,20 +47,8 @@ index 7f4e81ee3339e90b8525541dccf6dea187853cf7..a469016c43251f16913a365c4131b244
|
|||
// Paper start - cancellable death event
|
||||
public boolean queueHealthUpdatePacket = false;
|
||||
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
diff --git a/src/main/java/net/minecraft/stats/StatType.java b/src/main/java/net/minecraft/stats/StatType.java
|
||||
index ba48795a7b7cbf4622e64273ab488e26d7a862e2..b85987910cf80b1d1a04a7b772e19200f4ce4372 100644
|
||||
--- a/src/main/java/net/minecraft/stats/StatType.java
|
||||
+++ b/src/main/java/net/minecraft/stats/StatType.java
|
||||
@@ -28,6 +28,7 @@ public class StatType<T> implements Iterable<Stat<T>> {
|
||||
return this.map.values().iterator();
|
||||
}
|
||||
|
||||
+ public final Stat<T> get(T t) { return this.get(t); }; // Paper - OBFHELPER
|
||||
public Stat<T> get(T key) {
|
||||
return this.get(key, StatFormatter.DEFAULT);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java
|
||||
index 48efe133d294bb1b17e8ac8b44eea8a29f15845f..dcbe74bdb1b6e07f7b8845182576ef544493d377 100644
|
||||
index 744b58d59a5f34ed3bd6f2d4a0f876acfa6a7135..d75a04e7a70b7fb2527fdd7d1a45a101d064824f 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java
|
||||
@@ -4,11 +4,12 @@ import java.util.Random;
|
||||
|
@ -127,7 +115,7 @@ index 48efe133d294bb1b17e8ac8b44eea8a29f15845f..dcbe74bdb1b6e07f7b8845182576ef54
|
|||
+ } else {
|
||||
+ long days;
|
||||
+ if (world.paperConfig.patrolPerPlayerStart) {
|
||||
+ days = entityhuman.getStats().getValue(Stats.CUSTOM.get(Stats.PLAY_ONE_MINUTE)) / 24000L; // PLAY_ONE_MINUTE is actually counting in ticks, a misnomer by Mojang
|
||||
+ days = entityhuman.getStats().getValue(Stats.CUSTOM.get(Stats.PLAY_TIME)) / 24000L; // PLAY_ONE_MINUTE is actually counting in ticks, a misnomer by Mojang
|
||||
+ } else {
|
||||
+ days = world.getDayTime() / 24000L;
|
||||
+ }
|
|
@ -6,10 +6,10 @@ Subject: [PATCH] Remote Connections shouldn't hold up shutdown
|
|||
Bugs in the connection logic appears to leave stale connections even, preventing shutdown
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 4862a9519d4ba5f05b634a0335837bea9812edee..f8ddc0aa98874c7879a51e76d1a629cbdaf58812 100644
|
||||
index 6f9b7c3cf22d0c44f31b81bcbfa3cb1f8c065083..0511f1921193b78cbf4d8426136bf1f79746f955 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -397,11 +397,11 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
@@ -439,11 +439,11 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
}
|
||||
|
||||
if (this.rconThread != null) {
|
|
@ -5,10 +5,10 @@ Subject: [PATCH] Do not allow bees to load chunks for beehives
|
|||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Bee.java b/src/main/java/net/minecraft/world/entity/animal/Bee.java
|
||||
index 9b68809b91910d2bbb82cafe23d1de5dfff4221c..81291a1174538d6d4073c6fa886b10e99b45d887 100644
|
||||
index b4cd490a1b2a2a118dc5f49bcb0fb755fbad853b..4aeffd9efe6f845007f35a3fd23fdfda2d1f20aa 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
|
||||
@@ -358,6 +358,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
@@ -404,6 +404,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
if (this.hivePos == null) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -16,7 +16,7 @@ index 9b68809b91910d2bbb82cafe23d1de5dfff4221c..81291a1174538d6d4073c6fa886b10e9
|
|||
BlockEntity tileentity = this.level.getBlockEntity(this.hivePos);
|
||||
|
||||
return tileentity instanceof BeehiveBlockEntity && ((BeehiveBlockEntity) tileentity).isFireNearby();
|
||||
@@ -390,6 +391,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
@@ -436,6 +437,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
}
|
||||
|
||||
private boolean doesHiveHaveSpace(BlockPos pos) {
|
||||
|
@ -24,7 +24,7 @@ index 9b68809b91910d2bbb82cafe23d1de5dfff4221c..81291a1174538d6d4073c6fa886b10e9
|
|||
BlockEntity tileentity = this.level.getBlockEntity(pos);
|
||||
|
||||
return tileentity instanceof BeehiveBlockEntity ? !((BeehiveBlockEntity) tileentity).isFull() : false;
|
||||
@@ -632,6 +634,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
@@ -909,6 +911,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
@Override
|
||||
public boolean canBeeUse() {
|
||||
if (Bee.this.hasHive() && Bee.this.wantsToEnterHive() && Bee.this.hivePos.closerThan((Position) Bee.this.position(), 2.0D)) {
|
||||
|
@ -32,7 +32,7 @@ index 9b68809b91910d2bbb82cafe23d1de5dfff4221c..81291a1174538d6d4073c6fa886b10e9
|
|||
BlockEntity tileentity = Bee.this.level.getBlockEntity(Bee.this.hivePos);
|
||||
|
||||
if (tileentity instanceof BeehiveBlockEntity) {
|
||||
@@ -655,6 +658,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
@@ -932,6 +935,7 @@ public class Bee extends Animal implements NeutralMob, FlyingAnimal {
|
||||
|
||||
@Override
|
||||
public void start() {
|
|
@ -7,10 +7,10 @@ Suspected case would be around the technique used in .stopRiding
|
|||
Stack will identify any causer of this and warn instead of crashing.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 6da406c8403797a1cd9276ac06577c3c080a8a22..e6eeca5834a164d87f5b0e564fe6237902edaa6a 100644
|
||||
index 273cd2e0fc38801a5ecb26579e4d0e9ee017bb3c..d06c6828180b7864bf4d3736a65ea0a2dc7804e2 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -1501,6 +1501,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -1445,6 +1445,14 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
protected void addEntity(Entity entity) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity track"); // Spigot
|
||||
|
@ -26,23 +26,23 @@ index 6da406c8403797a1cd9276ac06577c3c080a8a22..e6eeca5834a164d87f5b0e564fe62379
|
|||
EntityType<?> entitytypes = entity.getType();
|
||||
int i = entitytypes.clientTrackingRange() * 16;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index c5dc41a3cf499038bd33451a189913cd3978b230..5127bce423a83711cea94e387b3ae7866215ded5 100644
|
||||
index 385b8e707406173ea5258aff87af719ce93aecf3..5944c44eadca550671d7740af5756985afede39d 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1525,7 +1525,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
}
|
||||
@@ -2100,7 +2100,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
|
||||
public void onTrackingStart(Entity entity) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot
|
||||
- ServerLevel.this.getChunkSource().addEntity(entity);
|
||||
+ // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - moved down below valid=true
|
||||
if (entity instanceof ServerPlayer) {
|
||||
ServerLevel.this.players.add((ServerPlayer) entity);
|
||||
ServerLevel.this.updateSleepingPlayerList();
|
||||
@@ -2122,6 +2122,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
}
|
||||
|
||||
- this.getChunkSource().addEntity(entity);
|
||||
+ // this.getChunkProvider().addEntity(entity); // Paper - moved down below valid=true
|
||||
// CraftBukkit start - SPIGOT-5278
|
||||
if (entity instanceof Drowned) {
|
||||
this.navigations.add(((Drowned) entity).waterNavigation);
|
||||
@@ -1536,6 +1536,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
this.navigations.add(((Mob) entity).getNavigation());
|
||||
}
|
||||
entity.valid = true; // CraftBukkit
|
||||
+ this.getChunkSource().addEntity(entity); // Paper - from above to be below valid=true
|
||||
// Paper start - Set origin location when the entity is being added to the world
|
||||
if (entity.origin == null) {
|
||||
entity.origin = entity.getBukkitEntity().getLocation();
|
||||
+ ServerLevel.this.getChunkSource().addEntity(entity);
|
||||
}
|
||||
|
||||
public void onTrackingEnd(Entity entity) {
|
|
@ -0,0 +1,133 @@
|
|||
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 2730923bd0bf3b0f928765b9e09e2299fa9a393d..f98a1c32e0c209473cf7268cbd8245ab9c134d28 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -783,6 +783,7 @@ public abstract class PlayerList {
|
||||
entityplayer1.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
// CraftBukkit end
|
||||
|
||||
+ 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(entityplayer1) && entityplayer1.getY() < (double) worldserver1.getMaxBuildHeight()) {
|
||||
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 facb09e49d92d22dbcde7d187d4ba1c9a04202a9..85c0656ee8c91cab1e269daea631977c4284295f 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -172,6 +172,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
// Paper end
|
||||
|
||||
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
|
||||
+ public boolean collisionLoadChunks = false; // Paper
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
public CraftEntity getBukkitEntity() {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/CollisionGetter.java b/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
index b980c26ab5cac02e03525177a9dc4fb0b6a2f9f6..2a784a8342e708e0813c7076a2ca8e429446ffd3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
@@ -55,7 +55,9 @@ public interface CollisionGetter extends BlockGetter {
|
||||
}
|
||||
|
||||
default boolean noCollision(@Nullable Entity entity, AABB box, Predicate<Entity> filter) {
|
||||
+ try { if (entity != null) entity.collisionLoadChunks = true; // Paper
|
||||
return this.getCollisions(entity, box, filter).allMatch(VoxelShape::isEmpty);
|
||||
+ } finally { if (entity != null) entity.collisionLoadChunks = false; } // Paper
|
||||
}
|
||||
|
||||
Stream<VoxelShape> getEntityCollisions(@Nullable Entity entity, AABB box, 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 e6190bfb893de12e87e1da49001ebd963b3d6318..90039d01ef481ba206f2e952c99a755e94201ea3 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/CollisionSpliterator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/CollisionSpliterator.java
|
||||
@@ -21,13 +21,13 @@ 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;
|
||||
|
||||
@@ -64,21 +64,37 @@ public class CollisionSpliterator extends AbstractSpliterator<VoxelShape> {
|
||||
boolean collisionCheck(Consumer<? super VoxelShape> action) {
|
||||
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 blockGetter = this.getChunk(i, k);
|
||||
- if (blockGetter == null) {
|
||||
+ // Paper start - ensure we don't load chunks
|
||||
+ Entity entity = this.getEntity();
|
||||
+ BlockPos.MutableBlockPos blockposition_mutableblockposition = this.getMutablePos();
|
||||
+ boolean far = entity != null && net.minecraft.server.MCUtil.distanceSq(entity.getX(), y, entity.getZ(), x, y, z) > 14;
|
||||
+ blockposition_mutableblockposition.setValues(x, y, z);
|
||||
+
|
||||
+ boolean isRegionLimited = this.getCollisionAccess() instanceof net.minecraft.server.level.WorldGenRegion;
|
||||
+ BlockState blockState = isRegionLimited ? Blocks.VOID_AIR.defaultBlockState() : ((!far && entity instanceof net.minecraft.server.level.ServerPlayer) || (entity != null && entity.collisionLoadChunks)
|
||||
+ ? this.getCollisionAccess().getBlockState(blockposition_mutableblockposition)
|
||||
+ : this.getCollisionAccess().getTypeIfLoaded(blockposition_mutableblockposition)
|
||||
+ );
|
||||
+
|
||||
+ if (blockState == null) {
|
||||
+ if (!(entity instanceof net.minecraft.server.level.ServerPlayer) || entity.level.paperConfig.preventMovingIntoUnloadedChunks) {
|
||||
+ VoxelShape voxelshape3 = Shapes.create(far ? entity.getBoundingBox() : new AABB(new BlockPos(x, y, z)));
|
||||
+ action.accept(voxelshape3);
|
||||
+ return true;
|
||||
+ }
|
||||
continue;
|
||||
}
|
||||
+ // Paper - moved up
|
||||
+ // Paper end
|
||||
|
||||
- this.pos.set(i, j, k);
|
||||
- BlockState blockState = blockGetter.getBlockState(this.pos);
|
||||
if (!this.predicate.test(blockState, this.pos) || l == 1 && !blockState.hasLargeCollisionShape() || l == 2 && !blockState.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 5d4d953f197afc402248ab73daeb6ef59134f48f..95428f13dae909bb7de552aa65e4256bd4049c65 100644
|
||||
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
@@ -238,7 +238,8 @@ public final class Shapes {
|
||||
|
||||
if (s < 3) {
|
||||
mutableBlockPos.set(axisCycle, q, r, p);
|
||||
- BlockState blockState = world.getBlockState(mutableBlockPos);
|
||||
+ BlockState blockState = world.getTypeIfLoaded(mutableBlockPos); // Paper
|
||||
+ if (blockState == null) return 0.0D; // Paper
|
||||
if ((s != 1 || blockState.hasLargeCollisionShape()) && (s != 2 || blockState.is(Blocks.MOVING_PISTON))) {
|
||||
initial = blockState.getCollisionShape(world, mutableBlockPos, context).collide(axis3, box.move((double)(-mutableBlockPos.getX()), (double)(-mutableBlockPos.getY()), (double)(-mutableBlockPos.getZ())), initial);
|
||||
if (Math.abs(initial) < 1.0E-7D) {
|
|
@ -7,15 +7,15 @@ Causes sync chunk loads and who knows what all else.
|
|||
This is safe because Spectators are skipped in unloaded chunks too in vanilla.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index a469016c43251f16913a365c4131b2448eaa4c48..286b75a27103a084a9f9d79a90716ebcad65d813 100644
|
||||
index 5b5a0c0db79452ee07c40bf7693b6701dbe0b615..2822d493500dcd01c26ff5b205da83d8d356e119 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -606,7 +606,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
@@ -637,7 +637,7 @@ public class ServerPlayer extends Player {
|
||||
|
||||
public void doTick() {
|
||||
try {
|
||||
- if (!this.isSpectator() || this.level.hasChunkAt(this.blockPosition())) {
|
||||
+ if (valid && !this.isSpectator() || this.level.hasChunkAt(this.blockPosition())) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
|
||||
- if (!this.isSpectator() || !this.touchingUnloadedChunk()) {
|
||||
+ if (valid && !this.isSpectator() || !this.touchingUnloadedChunk()) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
|
||||
super.tick();
|
||||
}
|
||||
|
|
@ -7,15 +7,15 @@ This fixes a lot of game state issues where packets were delayed for processing
|
|||
due to 1.15's new queue but processed while dead.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0685920073a6a2b2c6a80018d0c9009b2ef860c4..32f1b180e82f41f3ce1b49ea7d67b7d55d2b9ca7 100644
|
||||
index 4c9261c68518ab7429325f0366dfb2930663288c..a3d31cec6d1b8de700b6cd2f7f51398debef5b6d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -1046,7 +1046,7 @@ public abstract class Player extends LivingEntity {
|
||||
@@ -1106,7 +1106,7 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
@Override
|
||||
protected boolean isImmobile() {
|
||||
- return super.isImmobile() || this.isSleeping();
|
||||
+ return super.isImmobile() || this.isSleeping() || removed || !valid; // Paper - player's who are dead or not in a world shouldn't move...
|
||||
+ return super.isImmobile() || this.isSleeping() || this.isRemoved() || !valid; // Paper - player's who are dead or not in a world shouldn't move...
|
||||
}
|
||||
|
||||
@Override
|
|
@ -57,10 +57,10 @@ index 0000000000000000000000000000000000000000..f6ff4d8132a95895680f5bc81f8f873e
|
|||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
|
||||
index 99c3337eec552ba47d3b8b2d8feaaa80acf2a86f..9abef8550a89df5e15ac28de1a5549d064f29122 100644
|
||||
index 9c88426ab1275ee5fb6e28be8b213533dc4ab859..87c9a5c1b43f6010898d72136b5eb9973299b723 100644
|
||||
--- a/src/main/java/net/minecraft/server/MCUtil.java
|
||||
+++ b/src/main/java/net/minecraft/server/MCUtil.java
|
||||
@@ -616,7 +616,7 @@ public final class MCUtil {
|
||||
@@ -614,7 +614,7 @@ public final class MCUtil {
|
||||
|
||||
ServerLevel world = ((org.bukkit.craftbukkit.CraftWorld)bukkitWorld).getHandle();
|
||||
ChunkMap chunkMap = world.getChunkSource().chunkMap;
|
||||
|
@ -70,15 +70,13 @@ index 99c3337eec552ba47d3b8b2d8feaaa80acf2a86f..9abef8550a89df5e15ac28de1a5549d0
|
|||
List<ChunkHolder> allChunks = new ArrayList<>(visibleChunks.values());
|
||||
List<ServerPlayer> players = world.players;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index e6eeca5834a164d87f5b0e564fe6237902edaa6a..99eee56d6e66b79dd48ecbd1eeebc08174003f4a 100644
|
||||
index d06c6828180b7864bf4d3736a65ea0a2dc7804e2..c304c57a572b7e154362b39065ab8cb30a7e112e 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -104,8 +104,33 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
@@ -107,9 +107,36 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
private static final int MIN_VIEW_DISTANCE = 3;
|
||||
public static final int MAX_VIEW_DISTANCE = 33;
|
||||
public static final int MAX_CHUNK_DISTANCE = 33 + ChunkStatus.maxDistance();
|
||||
- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap();
|
||||
- public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap;
|
||||
+ // Paper start - faster copying
|
||||
+ public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<>(); // Paper - faster copying
|
||||
+ public final Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap = new ProtectedVisibleChunksMap(); // Paper - faster copying
|
||||
|
@ -106,19 +104,24 @@ index e6eeca5834a164d87f5b0e564fe6237902edaa6a..99eee56d6e66b79dd48ecbd1eeebc081
|
|||
+ // Paper end
|
||||
+ public final com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<ChunkHolder> pendingVisibleChunks = new com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<ChunkHolder>(); // Paper - this is used if the visible chunks is updated while iterating only
|
||||
+ public transient com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<ChunkHolder> visibleChunksClone; // Paper - used for async access of visible chunks, clone and cache only when needed
|
||||
public static final int FORCED_TICKET_LEVEL = 31;
|
||||
- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap();
|
||||
- public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap;
|
||||
+ // public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap(); // Paper - moved up
|
||||
+ // public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap; // Paper - moved up
|
||||
private final Long2ObjectLinkedOpenHashMap<ChunkHolder> pendingUnloads;
|
||||
public final LongSet entitiesInLevel; // Paper - private -> public
|
||||
public final ServerLevel level;
|
||||
@@ -178,7 +203,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -231,7 +258,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
public ChunkMap(ServerLevel worldserver, LevelStorageSource.LevelStorageAccess convertable_conversionsession, DataFixer dataFixer, StructureManager definedstructuremanager, Executor workerExecutor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, Supplier<DimensionDataStorage> supplier, int i, boolean flag) {
|
||||
super(new File(convertable_conversionsession.getDimensionPath(worldserver.dimension()), "region"), dataFixer, flag);
|
||||
public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureManager structureManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) {
|
||||
super(new File(session.getDimensionPath(world.dimension()), "region"), dataFixer, dsync);
|
||||
- this.visibleChunkMap = this.updatingChunkMap.clone();
|
||||
+ //this.visibleChunks = this.updatingChunks.clone(); // Paper - no more cloning
|
||||
this.pendingUnloads = new Long2ObjectLinkedOpenHashMap();
|
||||
this.entitiesInLevel = new LongOpenHashSet();
|
||||
this.toDrop = new LongOpenHashSet();
|
||||
@@ -270,9 +295,52 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -350,9 +377,52 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
return (ChunkHolder) this.updatingChunkMap.get(pos);
|
||||
}
|
||||
|
||||
|
@ -159,7 +162,7 @@ index e6eeca5834a164d87f5b0e564fe6237902edaa6a..99eee56d6e66b79dd48ecbd1eeebc081
|
|||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
public ChunkHolder getVisibleChunkIfPresent(long pos) { // Paper - protected -> public
|
||||
public final ChunkHolder getVisibleChunkIfPresent(long pos) { // Paper - protected -> public
|
||||
- return (ChunkHolder) this.visibleChunkMap.get(pos);
|
||||
+ // Paper start - mt safe get
|
||||
+ if (Thread.currentThread() != this.level.thread) {
|
||||
|
@ -172,8 +175,8 @@ index e6eeca5834a164d87f5b0e564fe6237902edaa6a..99eee56d6e66b79dd48ecbd1eeebc081
|
|||
}
|
||||
|
||||
protected IntSupplier getChunkQueueLevel(long pos) {
|
||||
@@ -460,8 +528,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// Paper end
|
||||
@@ -509,8 +579,9 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
protected void saveAllChunks(boolean flush) {
|
||||
+ Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunks = this.getVisibleChunks(); // Paper remove clone of visible Chunks unless saving off main thread (watchdog kill)
|
||||
|
@ -183,7 +186,7 @@ index e6eeca5834a164d87f5b0e564fe6237902edaa6a..99eee56d6e66b79dd48ecbd1eeebc081
|
|||
MutableBoolean mutableboolean = new MutableBoolean();
|
||||
|
||||
do {
|
||||
@@ -489,7 +558,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -541,7 +612,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// this.i(); // Paper - nuke IOWorker
|
||||
ChunkMap.LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", this.storageFolder.getName());
|
||||
} else {
|
||||
|
@ -192,7 +195,7 @@ index e6eeca5834a164d87f5b0e564fe6237902edaa6a..99eee56d6e66b79dd48ecbd1eeebc081
|
|||
ChunkAccess ichunkaccess = (ChunkAccess) playerchunk.getChunkToSave().getNow(null); // CraftBukkit - decompile error
|
||||
|
||||
if (ichunkaccess instanceof ImposterProtoChunk || ichunkaccess instanceof LevelChunk) {
|
||||
@@ -660,7 +729,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -701,7 +772,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
if (!this.modified) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -214,7 +217,7 @@ index e6eeca5834a164d87f5b0e564fe6237902edaa6a..99eee56d6e66b79dd48ecbd1eeebc081
|
|||
this.modified = false;
|
||||
return true;
|
||||
}
|
||||
@@ -1139,12 +1221,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -1110,12 +1194,12 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
protected Iterable<ChunkHolder> getChunks() {
|
||||
|
@ -223,17 +226,17 @@ index e6eeca5834a164d87f5b0e564fe6237902edaa6a..99eee56d6e66b79dd48ecbd1eeebc081
|
|||
}
|
||||
|
||||
void dumpChunks(Writer writer) throws IOException {
|
||||
CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("entity_count").addColumn("block_entity_count").build(writer);
|
||||
CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").build(writer);
|
||||
- ObjectBidirectionalIterator objectbidirectionaliterator = this.visibleChunkMap.long2ObjectEntrySet().iterator();
|
||||
+ ObjectBidirectionalIterator objectbidirectionaliterator = this.getVisibleChunks().long2ObjectEntrySet().iterator(); // Paper
|
||||
|
||||
while (objectbidirectionaliterator.hasNext()) {
|
||||
Entry<ChunkHolder> entry = (Entry) objectbidirectionaliterator.next();
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index e2b1541042bceac965411e3176d08c61f217c07f..f5de878020be9465739fba07fd7dea46b0a3ae34 100644
|
||||
index 382a68c76e8946840de62f05483870689de80278..8523fbd66ed42cd5b959d57cab515fa4a774a575 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -782,7 +782,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -751,7 +751,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
};
|
||||
// Paper end
|
||||
this.level.timings.chunkTicks.startTiming(); // Paper
|
||||
|
@ -243,41 +246,43 @@ index e2b1541042bceac965411e3176d08c61f217c07f..f5de878020be9465739fba07fd7dea46
|
|||
|
||||
if (optional.isPresent()) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index fb74bdcf4c2935b56e92717cc5a1504fbc853d0a..1a839242e359fa32f32d0e571c6e918ac39642e9 100644
|
||||
index 1d22119b962840dff789a0619fd2188958f924d0..1023a0d5d1699b28d380e017b386a9b3986f1250 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -276,6 +276,7 @@ public class CraftWorld implements World {
|
||||
return ret;
|
||||
}
|
||||
@@ -286,6 +286,7 @@ public class CraftWorld implements World {
|
||||
|
||||
@Override
|
||||
public int getTileEntityCount() {
|
||||
+ return net.minecraft.server.MCUtil.ensureMain(() -> {
|
||||
// We don't use the full world tile entity list, so we must iterate chunks
|
||||
Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = world.getChunkSource().chunkMap.visibleChunkMap;
|
||||
int size = 0;
|
||||
@@ -287,11 +288,13 @@ public class CraftWorld implements World {
|
||||
@@ -297,6 +298,7 @@ public class CraftWorld implements World {
|
||||
size += chunk.blockEntities.size();
|
||||
}
|
||||
return size;
|
||||
+ });
|
||||
}
|
||||
public int getTickableTileEntityCount() {
|
||||
return world.tickableBlockEntities.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -306,6 +308,7 @@ public class CraftWorld implements World {
|
||||
|
||||
@Override
|
||||
public int getChunkCount() {
|
||||
+ return net.minecraft.server.MCUtil.ensureMain(() -> {
|
||||
int ret = 0;
|
||||
|
||||
for (ChunkHolder chunkHolder : world.getChunkSource().chunkMap.visibleChunkMap.values()) {
|
||||
@@ -300,7 +303,7 @@ public class CraftWorld implements World {
|
||||
@@ -314,7 +317,7 @@ public class CraftWorld implements World {
|
||||
}
|
||||
}
|
||||
|
||||
- return ret;
|
||||
+ return ret; });
|
||||
}
|
||||
public int getPlayerCount() {
|
||||
return world.players.size();
|
||||
@@ -425,6 +428,14 @@ public class CraftWorld implements World {
|
||||
|
||||
@Override
|
||||
@@ -441,6 +444,14 @@ public class CraftWorld implements World {
|
||||
|
||||
@Override
|
||||
public Chunk[] getLoadedChunks() {
|
||||
|
@ -289,6 +294,6 @@ index fb74bdcf4c2935b56e92717cc5a1504fbc853d0a..1a839242e359fa32f32d0e571c6e918a
|
|||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = world.getChunkSource().chunkMap.visibleChunkMap;
|
||||
Long2ObjectLinkedOpenHashMap<ChunkHolder> chunks = this.world.getChunkSource().chunkMap.visibleChunkMap;
|
||||
return chunks.values().stream().map(ChunkHolder::getFullChunk).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.LevelChunk::getBukkitChunk).toArray(Chunk[]::new);
|
||||
}
|
|
@ -30,10 +30,10 @@ In a view distance of 15, chunk loading performance was visually faster on the c
|
|||
Flying at high speed in spectator mode was able to keep up with chunk loading (as long as they are already generated)
|
||||
|
||||
diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java
|
||||
index be3a62f543a5fec4739c14821fe5a443c1fa3f5b..6bff5317939635b925bb41eb7a67d1fd95715078 100644
|
||||
index 72f9e1978394afb6e5cc1c0d085d41586d69b84e..aa0698508de8fba6e84c20ac4d3aebb99a075c25 100644
|
||||
--- a/src/main/java/co/aikar/timings/MinecraftTimings.java
|
||||
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
|
||||
@@ -17,6 +17,7 @@ import java.util.Map;
|
||||
@@ -16,6 +16,7 @@ import java.util.Map;
|
||||
public final class MinecraftTimings {
|
||||
|
||||
public static final Timing serverOversleep = Timings.ofSafe("Server Oversleep");
|
||||
|
@ -56,18 +56,18 @@ index da93d38fe63035e4ff198ada84a4431f52d97c01..ddbc8cb712c50038922eded75dd6ca85
|
|||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 11c6e8ce10c53dcb639145fbda32c5426eb6b3d9..087f31ac0cc7816b1cbeffc45be6927b174dee62 100644
|
||||
index 494a3afaaa0e3496d30e8d97edbab62b21610dfe..fa3a9d763f7072c68b126ce95fee191aab576e43 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1055,6 +1055,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1112,6 +1112,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Paper end
|
||||
tickSection = curTime;
|
||||
}
|
||||
+ midTickChunksTasksRan = 0; // Paper
|
||||
// Spigot end
|
||||
|
||||
//MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit // Paper - don't overwrite current tick time
|
||||
@@ -1124,7 +1125,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (this.debugCommandProfilerDelayStart) {
|
||||
@@ -1186,7 +1187,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@ index 11c6e8ce10c53dcb639145fbda32c5426eb6b3d9..087f31ac0cc7816b1cbeffc45be6927b
|
|||
// CraftBukkit start
|
||||
if (isOversleep) return canOversleep();// Paper - because of our changes, this logic is broken
|
||||
return this.forceTicks || this.runningTask() || Util.getMillis() < (this.mayHaveDelayedTasks ? this.delayedTasksMaxNextTickTime : this.nextTickTime);
|
||||
@@ -1154,6 +1155,23 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1216,6 +1217,23 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,7 @@ index 11c6e8ce10c53dcb639145fbda32c5426eb6b3d9..087f31ac0cc7816b1cbeffc45be6927b
|
|||
@Override
|
||||
public TickTask wrapRunnable(Runnable runnable) {
|
||||
return new TickTask(this.tickCount, runnable);
|
||||
@@ -1240,6 +1258,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1311,6 +1329,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
// Paper start - move oversleep into full server tick
|
||||
isOversleep = true;MinecraftTimings.serverOversleep.startTiming();
|
||||
this.managedBlock(() -> {
|
||||
|
@ -108,10 +108,10 @@ index 11c6e8ce10c53dcb639145fbda32c5426eb6b3d9..087f31ac0cc7816b1cbeffc45be6927b
|
|||
return !this.canOversleep();
|
||||
});
|
||||
isOversleep = false;MinecraftTimings.serverOversleep.stopTiming();
|
||||
@@ -1318,13 +1337,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1379,13 +1398,16 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
protected void tickChildren(BooleanSupplier shouldKeepTicking) {
|
||||
public void tickChildren(BooleanSupplier shouldKeepTicking) {
|
||||
+ midTickLoadChunks(); // Paper
|
||||
MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper
|
||||
this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit
|
||||
|
@ -125,8 +125,8 @@ index 11c6e8ce10c53dcb639145fbda32c5426eb6b3d9..087f31ac0cc7816b1cbeffc45be6927b
|
|||
this.profiler.popPush("levels");
|
||||
Iterator iterator = this.getAllLevels().iterator();
|
||||
|
||||
@@ -1335,7 +1357,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
processQueue.remove().run();
|
||||
@@ -1396,7 +1418,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.processQueue.remove().run();
|
||||
}
|
||||
MinecraftTimings.processQueueTimer.stopTiming(); // Spigot
|
||||
-
|
||||
|
@ -134,7 +134,7 @@ index 11c6e8ce10c53dcb639145fbda32c5426eb6b3d9..087f31ac0cc7816b1cbeffc45be6927b
|
|||
MinecraftTimings.timeUpdateTimer.startTiming(); // Spigot // Paper
|
||||
// Send time updates to everyone, it will get the right time from the world the player is in.
|
||||
// Paper start - optimize time updates
|
||||
@@ -1377,9 +1399,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -1438,9 +1460,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.profiler.push("tick");
|
||||
|
||||
try {
|
||||
|
@ -147,18 +147,10 @@ index 11c6e8ce10c53dcb639145fbda32c5426eb6b3d9..087f31ac0cc7816b1cbeffc45be6927b
|
|||
// Spigot Start
|
||||
CrashReport crashreport;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index f5de878020be9465739fba07fd7dea46b0a3ae34..3744cce8611ac01b1b6c76cd3c4890795c1f06a2 100644
|
||||
index 8523fbd66ed42cd5b959d57cab515fa4a774a575..751454ad5a2c374c01ff360535428db36c0aa1b3 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -22,6 +22,7 @@ import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.server.MCUtil;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.progress.ChunkProgressListener;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
@@ -719,6 +720,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -703,6 +703,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
this.level.getProfiler().push("purge");
|
||||
this.level.timings.doChunkMap.startTiming(); // Spigot
|
||||
this.distanceManager.purgeStaleTickets();
|
||||
|
@ -166,15 +158,15 @@ index f5de878020be9465739fba07fd7dea46b0a3ae34..3744cce8611ac01b1b6c76cd3c489079
|
|||
this.runDistanceManagerUpdates();
|
||||
this.level.timings.doChunkMap.stopTiming(); // Spigot
|
||||
this.level.getProfiler().popPush("chunks");
|
||||
@@ -728,6 +730,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -712,6 +713,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
this.level.timings.doChunkUnload.startTiming(); // Spigot
|
||||
this.level.getProfiler().popPush("unload");
|
||||
this.chunkMap.tick(shouldKeepTicking);
|
||||
this.chunkMap.tick(booleansupplier);
|
||||
+ this.level.getServer().midTickLoadChunks(); // Paper
|
||||
this.level.timings.doChunkUnload.stopTiming(); // Spigot
|
||||
this.level.getProfiler().pop();
|
||||
this.clearCache();
|
||||
@@ -782,7 +785,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -751,7 +753,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
};
|
||||
// Paper end
|
||||
this.level.timings.chunkTicks.startTiming(); // Paper
|
||||
|
@ -183,15 +175,15 @@ index f5de878020be9465739fba07fd7dea46b0a3ae34..3744cce8611ac01b1b6c76cd3c489079
|
|||
Optional<LevelChunk> optional = ((Either) playerchunk.getTickingChunkFuture().getNow(ChunkHolder.UNLOADED_LEVEL_CHUNK)).left();
|
||||
|
||||
if (optional.isPresent()) {
|
||||
@@ -806,6 +809,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
//this.world.timings.chunkTicks.startTiming(); // Spigot // Paper
|
||||
this.level.tickChunk(chunk, k);
|
||||
//this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper
|
||||
@@ -768,6 +770,7 @@ public class ServerChunkCache extends ChunkSource {
|
||||
chunk.setInhabitedTime(chunk.getInhabitedTime() + j);
|
||||
if (flag1 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunk.getPos()) && !this.chunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot
|
||||
NaturalSpawner.spawnForChunk(this.level, chunk, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag2);
|
||||
+ if (chunksTicked[0]++ % 10 == 0) this.level.getServer().midTickLoadChunks(); // Paper
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -963,6 +967,41 @@ public class ServerChunkCache extends ChunkSource {
|
||||
|
||||
// this.level.timings.doTickTiles.startTiming(); // Spigot // Paper
|
||||
@@ -935,6 +938,41 @@ public class ServerChunkCache extends ChunkSource {
|
||||
super.doRunTask(task);
|
||||
}
|
||||
|
||||
|
@ -210,7 +202,7 @@ index f5de878020be9465739fba07fd7dea46b0a3ae34..3744cce8611ac01b1b6c76cd3c489079
|
|||
+ return false;
|
||||
+ }
|
||||
+ public void midTickLoadChunks() {
|
||||
+ MinecraftServer server = ServerChunkCache.this.level.getServer();
|
||||
+ net.minecraft.server.MinecraftServer server = ServerChunkCache.this.level.getServer();
|
||||
+ // always try to load chunks, restrain generation/other updates only. don't count these towards tick count
|
||||
+ //noinspection StatementWithEmptyBody
|
||||
+ while (pollChunkLoadTasks()) {}
|
||||
|
@ -231,13 +223,13 @@ index f5de878020be9465739fba07fd7dea46b0a3ae34..3744cce8611ac01b1b6c76cd3c489079
|
|||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
protected boolean pollTask() {
|
||||
// CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task
|
||||
public boolean pollTask() {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 5127bce423a83711cea94e387b3ae7866215ded5..4e75cc5e52a5295e32ccadb371702a405bb518bb 100644
|
||||
index 5944c44eadca550671d7740af5756985afede39d..fd3159f7767faaa55ed49eba237e30a2dbd4fa92 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -565,6 +565,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
@@ -578,6 +578,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
}
|
||||
timings.scheduledBlocks.stopTiming(); // Paper
|
||||
|
||||
|
@ -245,27 +237,24 @@ index 5127bce423a83711cea94e387b3ae7866215ded5..4e75cc5e52a5295e32ccadb371702a40
|
|||
gameprofilerfiller.popPush("raid");
|
||||
this.timings.raids.startTiming(); // Paper - timings
|
||||
this.raids.tick();
|
||||
@@ -573,6 +574,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
@@ -586,6 +587,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
timings.doSounds.startTiming(); // Spigot
|
||||
this.runBlockEvents();
|
||||
timings.doSounds.stopTiming(); // Spigot
|
||||
+ this.getServer().midTickLoadChunks(); // Paper
|
||||
this.handlingTick = false;
|
||||
gameprofilerfiller.popPush("entities");
|
||||
gameprofilerfiller.pop();
|
||||
boolean flag3 = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players
|
||||
@@ -639,6 +641,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
@@ -632,10 +634,12 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
timings.entityTick.stopTiming(); // Spigot
|
||||
|
||||
this.tickingEntities = false;
|
||||
+ this.getServer().midTickLoadChunks(); // Paper
|
||||
|
||||
Entity entity2;
|
||||
|
||||
@@ -648,6 +651,7 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
}
|
||||
|
||||
timings.tickEntities.stopTiming(); // Spigot
|
||||
gameprofilerfiller.pop();
|
||||
+ this.getServer().midTickLoadChunks(); // Paper
|
||||
this.tickBlockEntities();
|
||||
}
|
||||
|
||||
gameprofilerfiller.push("entityManagement");
|
||||
+ this.getServer().midTickLoadChunks(); // Paper
|
||||
this.entityManager.tick();
|
||||
gameprofilerfiller.pop();
|
||||
}
|
|
@ -10,28 +10,29 @@ larger than the keep loaded range.
|
|||
By skipping this, we avoid potential for a large spike on server start.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 286b75a27103a084a9f9d79a90716ebcad65d813..162b1a8c6ab57aafa4f6deefc842755a8e14208e 100644
|
||||
index 2822d493500dcd01c26ff5b205da83d8d356e119..bfa91166c18110877f751a5325e59623a05325d0 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -251,7 +251,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
@@ -309,7 +309,7 @@ public class ServerPlayer extends Player {
|
||||
this.stats = server.getPlayerList().getStatisticManager(this);
|
||||
this.advancements = server.getPlayerList().getPlayerAdvancements(this);
|
||||
this.maxUpStep = 1.0F;
|
||||
- this.fudgeSpawnLocation(world);
|
||||
+ //this.c(worldserver); // Paper - don't move to spawn on login, only first join
|
||||
this.textFilter = server.createTextFilterForPlayer(this);
|
||||
|
||||
this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
|
||||
@@ -303,6 +303,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
|
||||
@@ -359,7 +359,7 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ public final void moveToSpawn(ServerLevel worldserver) { fudgeSpawnLocation(worldserver); } // Paper - OBFHELPER
|
||||
private void fudgeSpawnLocation(ServerLevel world) {
|
||||
BlockPos blockposition = world.getSpawn();
|
||||
- private void fudgeSpawnLocation(ServerLevel world) {
|
||||
+ public void fudgeSpawnLocation(ServerLevel world) { // Paper - private -> public
|
||||
BlockPos blockposition = world.getSharedSpawnPos();
|
||||
|
||||
@@ -480,7 +481,7 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
position = Vec3.atCenterOf(((ServerLevel) world).getSpawn());
|
||||
if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit
|
||||
@@ -527,7 +527,7 @@ public class ServerPlayer extends Player {
|
||||
position = Vec3.atCenterOf(((ServerLevel) world).getSharedSpawnPos());
|
||||
}
|
||||
this.level = world;
|
||||
- this.setPos(position.x(), position.y(), position.z());
|
||||
|
@ -40,15 +41,15 @@ index 286b75a27103a084a9f9d79a90716ebcad65d813..162b1a8c6ab57aafa4f6deefc842755a
|
|||
this.gameMode.setLevel((ServerLevel) world);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 86c5549196a4e9011c5240e7918b466c299be4a3..30666fca36b683158ff60302684b5093f5536e24 100644
|
||||
index f98a1c32e0c209473cf7268cbd8245ab9c134d28..18485689bcbf7818c3ca5b82086acef51888603b 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -204,6 +204,8 @@ public abstract class PlayerList {
|
||||
@@ -207,6 +207,8 @@ public abstract class PlayerList {
|
||||
worldserver1 = worldserver;
|
||||
}
|
||||
|
||||
+ if (nbttagcompound == null) player.moveToSpawn(worldserver1); // Paper - only move to spawn on first login, otherwise, stay where you are....
|
||||
+ if (nbttagcompound == null) player.fudgeSpawnLocation(worldserver1); // Paper - only move to spawn on first login, otherwise, stay where you are....
|
||||
+
|
||||
player.setLevel(worldserver1);
|
||||
player.gameMode.setLevel((ServerLevel) player.level);
|
||||
String s1 = "local";
|
||||
|
Loading…
Reference in New Issue