MOAR PATCHES

This commit is contained in:
Jake Potrebic 2021-06-13 15:05:18 -07:00
parent 7dd2ea0897
commit 3ee043dc0c
33 changed files with 384 additions and 843 deletions

View file

@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
@@ -0,0 +0,0 @@ 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);

View file

@ -1,79 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 29 Mar 2020 18:26:14 -0400
Subject: [PATCH] Ensure Entity is never double registered
If something calls register twice, and the world is ticking, it could be
enqueued to add twice.
Vs behavior of non ticking of just overwriting state.
We will now simply log a warning when this happens instead of crashing the server.
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
Entity entity2;
while ((entity2 = (Entity) this.toAddAfterTick.poll()) != null) {
+ if (!entity2.isQueuedForRegister) continue; // Paper - ignore cancelled registers
this.add(entity2);
}
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
public void onEntityRemoved(Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot
+ // Paper start - fix entity registration issues
+ if (entity instanceof EnderDragonPart) {
+ // Usually this is a no-op for complex parts, and ID's should be removed, but go ahead and remove it anyways
+ // Dragon parts are handled special in register. they don't receive a valid = true or register by UUID etc.
+ this.entitiesById.remove(entity.getId(), entity);
+ return;
+ }
+ if (!entity.valid) {
+ // Someone called remove before we ever got added, cancel the add.
+ entity.isQueuedForRegister = false;
+ return;
+ }
+ // Paper end
// Spigot start
if ( entity instanceof Player )
{
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
private void add(Entity entity) {
org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot
+ // Paper start - don't double enqueue entity registration
+ //noinspection ObjectEquality
+ if (this.entitiesById.get(entity.getId()) == entity) {
+ LOGGER.error(entity + " was already registered!");
+ new Throwable().printStackTrace();
+ return;
+ }
+ // Paper end
if (this.tickingEntities) {
- this.toAddAfterTick.add(entity);
+ if (!entity.isQueuedForRegister) { // Paper
+ this.toAddAfterTick.add(entity);
+ entity.isQueuedForRegister = true; // Paper
+ }
} else {
+ entity.isQueuedForRegister = false; // Paper
this.entitiesById.put(entity.getId(), entity);
if (entity instanceof EnderDragon) {
EnderDragonPart[] aentitycomplexpart = ((EnderDragon) entity).getSubEntities();
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s
}
// Paper start
+ public boolean isQueuedForRegister = false;
public static Random SHARED_RANDOM = new Random() {
private boolean locked = false;
@Override

View file

@ -1,32 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Tue, 31 Mar 2020 03:01:45 -0400
Subject: [PATCH] Fix unregistering entities from unloading chunks
CraftBukkit caused a regression here by making unloading chunks not
have a ticket added and returning unloaded future.
This caused entities who were killed in same tick their chunk is unloading
to not be able to be removed from the chunk.
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"
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
}
private void removeFromChunk(Entity entity) {
- ChunkAccess ichunkaccess = chunkSource.getChunkUnchecked(entity.xChunk, entity.zChunk); // CraftBukkit - SPIGOT-5228: getChunkAt won't find the entity's chunk if it has already been unloaded (i.e. if it switched to state INACCESSIBLE).
+ LevelChunk ichunkaccess = entity.getCurrentChunk(); // Paper - getChunkAt(x,z,full,false) is broken by CraftBukkit as it won't return an unloading chunk. Use our current chunk reference as this points to what chunk they need to be removed from anyways
- if (ichunkaccess instanceof LevelChunk) {
+ if (ichunkaccess != null) { // Paper
((LevelChunk) ichunkaccess).removeEntity(entity);
}

View file

@ -22,8 +22,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ hatching = event.isHatching(); + hatching = event.isHatching();
+ hatchingType = event.getHatchingType(); + hatchingType = event.getHatchingType();
+ // Paper end + // Paper end
+
+
if (hatching) { if (hatching) {
for (int i = 0; i < b0; ++i) { 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());

View file

@ -9,20 +9,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -0,0 +0,0 @@ public class PaperWorldConfig {
disableHopperMoveEvents = getBoolean("hopper.disable-move-event", disableHopperMoveEvents);
log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled")); log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled"));
} }
+
+ public boolean nerfNetherPortalPigmen = false; + public boolean nerfNetherPortalPigmen = false;
+ private void nerfNetherPortalPigmen() { + private void nerfNetherPortalPigmen() {
+ nerfNetherPortalPigmen = getBoolean("game-mechanics.nerf-pigmen-from-nether-portals", 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 diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
public long activatedTick = Integer.MIN_VALUE; public long activatedTick = Integer.MIN_VALUE;
public boolean isTemporarilyActive = false; // Paper public boolean isTemporarilyActive = false; // Paper
public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
@ -30,42 +32,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected int numCollisions = 0; // Paper protected int numCollisions = 0; // Paper
public void inactiveTick() { } public void inactiveTick() { }
// Spigot end // Spigot end
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
if (spawnedViaMobSpawner) { if (spawnedViaMobSpawner) {
tag.putBoolean("Paper.FromMobSpawner", true); nbt.putBoolean("Paper.FromMobSpawner", true);
} }
+ if (fromNetherPortal) { + if (fromNetherPortal) {
+ tag.putBoolean("Paper.FromNetherPortal", true); + nbt.putBoolean("Paper.FromNetherPortal", true);
+ } + }
// Paper end // Paper end
return tag; return nbt;
} catch (Throwable throwable) { } catch (Throwable throwable) {
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
} }
spawnedViaMobSpawner = tag.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
+ fromNetherPortal = tag.getBoolean("Paper.FromNetherPortal"); + fromNetherPortal = nbt.getBoolean("Paper.FromNetherPortal");
if (tag.contains("Paper.SpawnReason")) { if (nbt.contains("Paper.SpawnReason")) {
String spawnReasonName = tag.getString("Paper.SpawnReason"); String spawnReasonName = nbt.getString("Paper.SpawnReason");
try { 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 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java --- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -0,0 +0,0 @@ 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;
@@ -0,0 +0,0 @@ public class NetherPortalBlock extends Block { @@ -0,0 +0,0 @@ public class NetherPortalBlock extends Block {
if (entity != null) { if (entity != null) {
entity.setPortalCooldown(); entity.setPortalCooldown();
+ entity.fromNetherPortal = true; // Paper + 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
} }
} }
} }

View file

@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/Main.java --- a/src/main/java/org/bukkit/craftbukkit/Main.java
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java
@@ -0,0 +0,0 @@ public class Main { @@ -0,0 +0,0 @@ public class Main {
float javaVersion = Float.parseFloat(System.getProperty("java.class.version")); }
if (javaVersion > 60.0) { if (javaVersion > 60.0) {
System.err.println("Unsupported Java detected (" + javaVersion + "). Only up to Java 16 is supported."); System.err.println("Unsupported Java detected (" + javaVersion + "). Only up to Java 16 is supported.");
- return; - return;

View file

@ -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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Bee.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Bee.java
@@ -0,0 +0,0 @@ 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);

View file

@ -12,33 +12,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java --- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java +++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -0,0 +0,0 @@ public class PaperWorldConfig { @@ -0,0 +0,0 @@ public class PaperWorldConfig {
private void nerfNetherPortalPigmen() {
nerfNetherPortalPigmen = getBoolean("game-mechanics.nerf-pigmen-from-nether-portals", nerfNetherPortalPigmen); nerfNetherPortalPigmen = getBoolean("game-mechanics.nerf-pigmen-from-nether-portals", nerfNetherPortalPigmen);
} }
+
+ public double zombieVillagerInfectionChance = -1.0; + public double zombieVillagerInfectionChance = -1.0;
+ private void zombieVillagerInfectionChance() { + private void zombieVillagerInfectionChance() {
+ zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", 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 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java --- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java +++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
@@ -0,0 +0,0 @@ public class Zombie extends Monster { @@ -0,0 +0,0 @@ public class Zombie extends Monster {
@Override @Override
public void killed(ServerLevel worldserver, LivingEntity entityliving) { public void killed(ServerLevel world, LivingEntity other) {
super.killed(worldserver, entityliving); super.killed(world, other);
- if ((worldserver.getDifficulty() == Difficulty.NORMAL || worldserver.getDifficulty() == Difficulty.HARD) && entityliving instanceof Villager) { - if ((world.getDifficulty() == Difficulty.NORMAL || world.getDifficulty() == Difficulty.HARD) && other instanceof Villager) {
- if (worldserver.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) { - if (world.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
+ // Paper start + 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 != 0.0 && (level.paperConfig.zombieVillagerInfectionChance != -1.0 || worldserver.getDifficulty() == Difficulty.NORMAL || worldserver.getDifficulty() == Difficulty.HARD) && entityliving instanceof Villager) { + if (level.paperConfig.zombieVillagerInfectionChance == -1.0 && world.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
+ if (level.paperConfig.zombieVillagerInfectionChance == -1.0 && worldserver.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
return; return;
} }
+ if (level.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > level.paperConfig.zombieVillagerInfectionChance) { + if (level.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > level.paperConfig.zombieVillagerInfectionChance) {
+ return; + return;
+ } // Paper end + } // Paper end
Villager entityvillager = (Villager) entityliving; Villager entityvillager = (Villager) other;
// CraftBukkit start // CraftBukkit start

View file

@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@Override @Override
protected boolean isImmobile() { protected boolean isImmobile() {
- return super.isImmobile() || this.isSleeping(); - 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 @Override

View file

@ -13,25 +13,26 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
this.stats = server.getPlayerList().getStatisticManager(this); this.stats = server.getPlayerList().getStatisticManager(this);
this.advancements = server.getPlayerList().getPlayerAdvancements(this); this.advancements = server.getPlayerList().getPlayerAdvancements(this);
this.maxUpStep = 1.0F; this.maxUpStep = 1.0F;
- this.fudgeSpawnLocation(world); - this.fudgeSpawnLocation(world);
+ //this.c(worldserver); // Paper - don't move to spawn on login, only first join + //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 this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
} }
// CraftBukkit end // CraftBukkit end
+ public final void moveToSpawn(ServerLevel worldserver) { fudgeSpawnLocation(worldserver); } // Paper - OBFHELPER - private void fudgeSpawnLocation(ServerLevel world) {
private void fudgeSpawnLocation(ServerLevel world) { + public void fudgeSpawnLocation(ServerLevel world) { // Paper - private -> public
BlockPos blockposition = world.getSpawn(); BlockPos blockposition = world.getSharedSpawnPos();
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit
position = Vec3.atCenterOf(((ServerLevel) world).getSpawn()); @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
position = Vec3.atCenterOf(((ServerLevel) world).getSharedSpawnPos());
} }
this.level = world; this.level = world;
- this.setPos(position.x(), position.y(), position.z()); - this.setPos(position.x(), position.y(), position.z());
@ -47,8 +48,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
worldserver1 = worldserver; 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.setLevel(worldserver1);
player.gameMode.setLevel((ServerLevel) player.level);
String s1 = "local"; String s1 = "local";

View file

@ -10,12 +10,12 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
public void doTick() { public void doTick() {
try { try {
- if (!this.isSpectator() || this.level.hasChunkAt(this.blockPosition())) { - if (!this.isSpectator() || !this.touchingUnloadedChunk()) {
+ 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 (valid && !this.isSpectator() || !this.touchingUnloadedChunk()) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
super.tick(); super.tick();
} }

View file

@ -16,13 +16,13 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java --- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java +++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, CommandSource, net.minecraft.s @@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
BlockPos blockposition1; BlockPos blockposition1;
if (flag1) { if (flag1) {
+ // Paper start - Ensure spawn chunk is always loaded before calculating Y coordinate + // 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 + // Paper end
blockposition1 = ServerLevel.END_SPAWN_POINT; blockposition1 = ServerLevel.END_SPAWN_POINT;
} else { } else {
blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSpawn()); blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSharedSpawnPos());

View file

@ -149,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return new Dimension(350, 200); + return new Dimension(350, 200);
+ } + }
+ +
+ public void stop() { a(); } public void a() { + public void close() {
+ timer.stop(); + timer.stop();
+ ramGraph.stop(); + ramGraph.stop();
+ } + }
@ -176,7 +176,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import java.util.Vector; +import java.util.Vector;
+ +
+public class RAMDetails extends JList<String> { +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))); + -> format.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)));
+ +
+ private final MinecraftServer server; + private final MinecraftServer server;
@ -221,7 +221,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ Vector<String> vector = new Vector<>(); + Vector<String> vector = new Vector<>();
+ vector.add("Memory use: " + (data.getUsedMem() / 1024L / 1024L) + " mb (" + (data.getFree() * 100L / data.getMax()) + "% free)"); + 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("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); + setListData(vector);
+ } + }
+ +
@ -383,31 +383,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ timer.stop(); + timer.stop();
+ } + }
+} +}
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -0,0 +0,0 @@ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -0,0 +0,0 @@ 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 diff --git a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java b/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java --- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
@ -418,22 +393,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
JPanel jpanel = new JPanel(new BorderLayout()); JPanel jpanel = new JPanel(new BorderLayout());
- StatsComponent guistatscomponent = new StatsComponent(this.server); - StatsComponent guistatscomponent = new StatsComponent(this.server);
+ com.destroystokyo.paper.gui.GuiStatsComponent guistatscomponent = new com.destroystokyo.paper.gui.GuiStatsComponent(this.server); // Paper + 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); Objects.requireNonNull(guistatscomponent);
+ 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/gui/StatsComponent.java
+++ b/src/main/java/net/minecraft/server/gui/StatsComponent.java
@@ -0,0 +0,0 @@ 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];

View file

@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ midTickChunksTasksRan = 0; // Paper + midTickChunksTasksRan = 0; // Paper
// Spigot end // Spigot end
//MinecraftServer.currentTick = (int) (System.currentTimeMillis() / 50); // CraftBukkit // Paper - don't overwrite current tick time if (this.debugCommandProfilerDelayStart) {
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} }
@ -111,7 +111,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
} }
protected void tickChildren(BooleanSupplier shouldKeepTicking) { public void tickChildren(BooleanSupplier shouldKeepTicking) {
+ midTickLoadChunks(); // Paper + midTickLoadChunks(); // Paper
MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper
this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit
@ -126,7 +126,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
Iterator iterator = this.getAllLevels().iterator(); Iterator iterator = this.getAllLevels().iterator();
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa @@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
processQueue.remove().run(); this.processQueue.remove().run();
} }
MinecraftTimings.processQueueTimer.stopTiming(); // Spigot MinecraftTimings.processQueueTimer.stopTiming(); // Spigot
- -
@ -150,14 +150,6 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/sr
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -0,0 +0,0 @@ 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;
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
this.level.getProfiler().push("purge"); this.level.getProfiler().push("purge");
this.level.timings.doChunkMap.startTiming(); // Spigot this.level.timings.doChunkMap.startTiming(); // Spigot
@ -169,7 +161,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
this.level.timings.doChunkUnload.startTiming(); // Spigot this.level.timings.doChunkUnload.startTiming(); // Spigot
this.level.getProfiler().popPush("unload"); this.level.getProfiler().popPush("unload");
this.chunkMap.tick(shouldKeepTicking); this.chunkMap.tick(booleansupplier);
+ this.level.getServer().midTickLoadChunks(); // Paper + this.level.getServer().midTickLoadChunks(); // Paper
this.level.timings.doChunkUnload.stopTiming(); // Spigot this.level.timings.doChunkUnload.stopTiming(); // Spigot
this.level.getProfiler().pop(); this.level.getProfiler().pop();
@ -184,13 +176,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (optional.isPresent()) { if (optional.isPresent()) {
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
//this.world.timings.chunkTicks.startTiming(); // Spigot // Paper chunk.setInhabitedTime(chunk.getInhabitedTime() + j);
this.level.tickChunk(chunk, k); if (flag1 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunk.getPos()) && !this.chunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot
//this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper NaturalSpawner.spawnForChunk(this.level, chunk, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag2);
+ if (chunksTicked[0]++ % 10 == 0) this.level.getServer().midTickLoadChunks(); // Paper + if (chunksTicked[0]++ % 10 == 0) this.level.getServer().midTickLoadChunks(); // Paper
} }
}
} // this.level.timings.doTickTiles.startTiming(); // Spigot // Paper
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
super.doRunTask(task); super.doRunTask(task);
} }
@ -210,7 +202,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return false; + return false;
+ } + }
+ public void midTickLoadChunks() { + 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 + // always try to load chunks, restrain generation/other updates only. don't count these towards tick count
+ //noinspection StatementWithEmptyBody + //noinspection StatementWithEmptyBody
+ while (pollChunkLoadTasks()) {} + while (pollChunkLoadTasks()) {}
@ -231,8 +223,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end + // Paper end
+ +
@Override @Override
protected boolean pollTask() {
// CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task // 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 diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
@ -251,21 +243,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
timings.doSounds.stopTiming(); // Spigot timings.doSounds.stopTiming(); // Spigot
+ this.getServer().midTickLoadChunks(); // Paper + this.getServer().midTickLoadChunks(); // Paper
this.handlingTick = false; 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 boolean flag3 = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl @@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
timings.entityTick.stopTiming(); // Spigot timings.entityTick.stopTiming(); // Spigot
this.tickingEntities = false;
+ this.getServer().midTickLoadChunks(); // Paper
Entity entity2;
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
}
timings.tickEntities.stopTiming(); // Spigot timings.tickEntities.stopTiming(); // Spigot
gameprofilerfiller.pop();
+ this.getServer().midTickLoadChunks(); // Paper + this.getServer().midTickLoadChunks(); // Paper
this.tickBlockEntities(); this.tickBlockEntities();
} }
gameprofilerfiller.push("entityManagement");
+ this.getServer().midTickLoadChunks(); // Paper
this.entityManager.tick();
gameprofilerfiller.pop();
}

View file

@ -16,14 +16,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public FluidState getFluidState(int x, int y, int z) { public FluidState getFluidState(int x, int y, int z) {
- try { - try {
- if (y >= 0 && y >> 4 < this.sections.length) { - int l = this.getSectionIndex(y);
- LevelChunkSection chunksection = this.sections[y >> 4]; -
- if (l >= 0 && l < this.sections.length) {
- LevelChunkSection chunksection = this.sections[l];
- -
- if (!LevelChunkSection.isEmpty(chunksection)) { - if (!LevelChunkSection.isEmpty(chunksection)) {
- return chunksection.getFluidState(x & 15, y & 15, z & 15); - 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 + // 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) { + if (index >= 0 && index < this.sections.length) {
+ LevelChunkSection chunksection = this.sections[index]; + LevelChunkSection chunksection = this.sections[index];
+ +
@ -34,17 +36,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
return Fluids.EMPTY.defaultFluidState(); return Fluids.EMPTY.defaultFluidState();
- } catch (Throwable throwable) { + /* // Paper - remove try catch
- CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting fluid state"); } catch (Throwable throwable) {
- CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being got"); CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting fluid state");
+ /*} catch (Throwable throwable) { // Paper - remove try catch CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being got");
+ CrashReport crashreport = CrashReport.a(throwable, "Getting fluid state"); @@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
+ 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);
}); });
throw new ReportedException(crashreport); throw new ReportedException(crashreport);
} }
@ -60,8 +56,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
public FluidState getFluidState(int x, int y, int z) { public FluidState getFluidState(int x, int y, int z) {
- return ((BlockState) this.states.get(x, y, z)).getFluidState(); - return 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(); // 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() { public void acquire() {

View file

@ -168,7 +168,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ private void queueEntryForTick(final TickNextTickData<T> entry, final ServerChunkCache chunkProvider) { + private void queueEntryForTick(final TickNextTickData<T> entry, final ServerChunkCache chunkProvider) {
+ if (entry.tickState == STATE_SCHEDULED) { + if (entry.tickState == STATE_SCHEDULED) {
+ if (chunkProvider.isTickingReadyMainThread(entry.getPosition())) { + if (chunkProvider.isTickingReadyMainThread(entry.pos)) {
+ this.toTickThisTick.add(entry); + this.toTickThisTick.add(entry);
+ entry.tickState = STATE_PENDING_TICK; + entry.tickState = STATE_PENDING_TICK;
+ } else { + } else {
@ -179,13 +179,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ private void addToNotTickingReady(final TickNextTickData<T> entry) { + 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<>(); + return new ArrayList<>();
+ }).add(entry); + }).add(entry);
+ } + }
+ +
+ private void addToSchedule(final TickNextTickData<T> 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 < SHORT_SCHEDULE_TICK_THRESHOLD) {
+ if (delay < 0) { + if (delay < 0) {
+ // longScheduled orders by tick time, short scheduled does not + // longScheduled orders by tick time, short scheduled does not
@ -202,7 +202,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ entry.tickState = STATE_CANCELLED_TICK; + entry.tickState = STATE_CANCELLED_TICK;
+ // short/long scheduled will skip the entry + // short/long scheduled will skip the entry
+ +
+ final BlockPos pos = entry.getPosition(); + final BlockPos pos = entry.pos;
+ final long blockKey = MCUtil.getBlockKey(pos); + final long blockKey = MCUtil.getBlockKey(pos);
+ +
+ final ArrayList<TickNextTickData<T>> currentEntries = this.entriesByBlock.get(blockKey); + final ArrayList<TickNextTickData<T>> currentEntries = this.entriesByBlock.get(blockKey);
@ -221,7 +221,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ +
+ final long chunkKey = MCUtil.getCoordinateKey(entry.getPosition()); + final long chunkKey = MCUtil.getCoordinateKey(entry.pos);
+ +
+ ObjectRBTreeSet<TickNextTickData<T>> set = this.entriesByChunk.get(chunkKey); + ObjectRBTreeSet<TickNextTickData<T>> set = this.entriesByChunk.get(chunkKey);
+ +
@ -246,7 +246,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ +
+ long delay = entry.getTargetTick() - (this.currentTick + 1); + long delay = entry.triggerTick - (this.currentTick + 1);
+ if (delay >= SHORT_SCHEDULE_TICK_THRESHOLD) { + if (delay >= SHORT_SCHEDULE_TICK_THRESHOLD) {
+ this.longScheduled.remove(entry); + this.longScheduled.remove(entry);
+ } + }
@ -274,7 +274,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ // we don't remove items from shortScheduled (but do from longScheduled) because they're cleared at the end of + // we don't remove items from shortScheduled (but do from longScheduled) because they're cleared at the end of
+ // this tick + // 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 + // nothing in longScheduled to worry about
+ final TickListServerInterval<T> interval = this.shortScheduled[this.shortScheduledIndex]; + final TickListServerInterval<T> interval = this.shortScheduled[this.shortScheduledIndex];
+ for (int i = 0, len = interval.byPriority.length; i < len; ++i) { + for (int i = 0, len = interval.byPriority.length; i < len; ++i) {
@ -300,7 +300,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ longScheduledIterator.remove(); + longScheduledIterator.remove();
+ if (longScheduledIterator.hasNext()) { + if (longScheduledIterator.hasNext()) {
+ longCurrent = longScheduledIterator.next(); + longCurrent = longScheduledIterator.next();
+ if (longCurrent.getTargetTick() > currentTick) { + if (longCurrent.triggerTick > currentTick) {
+ longCurrent = null; + longCurrent = null;
+ break; + break;
+ } + }
@ -316,7 +316,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ // add remaining from long scheduled + // add remaining from long scheduled
+ for (;;) { + for (;;) {
+ if (longCurrent == null || longCurrent.getTargetTick() > currentTick) { + if (longCurrent == null || longCurrent.triggerTick > currentTick) {
+ break; + break;
+ } + }
+ longScheduledIterator.remove(); + longScheduledIterator.remove();
@ -368,7 +368,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ continue; + continue;
+ } + }
+ try { + try {
+ if (chunkProvider.isTickingReadyMainThread(toTick.getPosition())) { + if (chunkProvider.isTickingReadyMainThread(toTick.pos)) {
+ toTick.tickState = STATE_TICKING; + toTick.tickState = STATE_TICKING;
+ this.tickFunction.accept(toTick); + this.tickFunction.accept(toTick);
+ if (toTick.tickState == STATE_TICKING) { + if (toTick.tickState == STATE_TICKING) {
@ -384,7 +384,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ CrashReport crashreport = CrashReport.forThrowable(thr, "Exception while ticking"); + CrashReport crashreport = CrashReport.forThrowable(thr, "Exception while ticking");
+ CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being ticked"); + 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); + throw new ReportedException(crashreport);
+ // end copy from TickListServer + // end copy from TickListServer
+ } + }
@ -413,7 +413,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ entry.tickState = STATE_UNSCHEDULED; + entry.tickState = STATE_UNSCHEDULED;
+ +
+ final BlockPos pos = entry.getPosition(); + final BlockPos pos = entry.pos;
+ final long blockKey = MCUtil.getBlockKey(pos); + final long blockKey = MCUtil.getBlockKey(pos);
+ +
+ final ArrayList<TickNextTickData<T>> currentEntries = this.entriesByBlock.get(blockKey); + final ArrayList<TickNextTickData<T>> currentEntries = this.entriesByBlock.get(blockKey);
@ -432,7 +432,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ +
+ final long chunkKey = MCUtil.getCoordinateKey(entry.getPosition()); + final long chunkKey = MCUtil.getCoordinateKey(entry.pos);
+ +
+ ObjectRBTreeSet<TickNextTickData<T>> set = this.entriesByChunk.get(chunkKey); + ObjectRBTreeSet<TickNextTickData<T>> set = this.entriesByChunk.get(chunkKey);
+ +
@ -446,7 +446,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @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)); + final ArrayList<TickNextTickData<T>> entries = this.entriesByBlock.get(MCUtil.getBlockKey(blockposition));
+ +
+ if (entries == null) { + if (entries == null) {
@ -455,7 +455,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ for (int i = 0, size = entries.size(); i < size; ++i) { + for (int i = 0, size = entries.size(); i < size; ++i) {
+ final TickNextTickData<T> entry = entries.get(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; + return true;
+ } + }
+ } + }
@ -464,7 +464,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @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)); + final ArrayList<TickNextTickData<T>> entries = this.entriesByBlock.get(MCUtil.getBlockKey(blockposition));
+ +
+ if (entries == null) { + if (entries == null) {
@ -473,7 +473,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ for (int i = 0, size = entries.size(); i < size; ++i) { + for (int i = 0, size = entries.size(); i < size; ++i) {
+ final TickNextTickData<T> entry = entries.get(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; + return true;
+ } + }
+ } + }
@ -482,22 +482,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @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); + this.schedule(blockPosition, t, i + this.currentTick, tickListPriority);
+ } + }
+ +
+ public void schedule(final TickNextTickData<T> entry) { + 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) { + 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); + final TickNextTickData<T> entry = new TickNextTickData<>(pos, data, targetTick, priority);
+ if (this.excludeFromScheduling.test(entry.getData())) { + if (this.excludeFromScheduling.test(entry.getType())) {
+ return; + return;
+ } + }
+ +
+ if (WARN_ON_EXCESSIVE_DELAY) { + if (WARN_ON_EXCESSIVE_DELAY) {
+ final long delay = entry.getTargetTick() - this.currentTick; + final long delay = entry.triggerTick - this.currentTick;
+ if (delay >= EXCESSIVE_DELAY_THRESHOLD) { + if (delay >= EXCESSIVE_DELAY_THRESHOLD) {
+ MinecraftServer.LOGGER.warn("Entry " + entry.toString() + " has been scheduled with an excessive delay of: " + delay, new Throwable()); + MinecraftServer.LOGGER.warn("Entry " + entry.toString() + " has been scheduled with an excessive delay of: " + delay, new Throwable());
+ } + }
@ -514,7 +514,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final TickNextTickData<T> currentEntry = currentEntries.get(i); + 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) + // 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 + // can't add
+ return; + return;
+ } + }
@ -524,7 +524,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ entry.tickState = STATE_SCHEDULED; + 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); + return new ObjectRBTreeSet<>(TickListServerInterval.ENTRY_COMPARATOR);
+ }).add(entry); + }).add(entry);
+ +
@ -541,19 +541,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // i.e the y value is ignored? the x, z calc isn't correct? + // 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... + // 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) { + 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 + @Override
+ public List<TickNextTickData<T>> getEntriesInBoundingBox(final BoundingBox structureboundingbox, final boolean removeReturned, final boolean excludeTicked) { + public List<TickNextTickData<T>> fetchTicksInArea(final BoundingBox structureboundingbox, final boolean removeReturned, final boolean excludeTicked) {
+ if (structureboundingbox.getMinX() == structureboundingbox.getMaxX() || structureboundingbox.getMinZ() == structureboundingbox.getMaxZ()) { + if (structureboundingbox.minX() == structureboundingbox.maxX() || structureboundingbox.minZ() == structureboundingbox.maxZ()) {
+ return Collections.emptyList(); // vanilla behaviour, check isBlockInSortof above + return Collections.emptyList(); // vanilla behaviour, check isBlockInSortof above
+ } + }
+ +
+ final int lowerChunkX = structureboundingbox.getMinX() >> 4; + final int lowerChunkX = structureboundingbox.minX() >> 4;
+ final int upperChunkX = (structureboundingbox.getMaxX() - 1) >> 4; // subtract 1 since maxX is exclusive + final int upperChunkX = (structureboundingbox.maxX() - 1) >> 4; // subtract 1 since maxX is exclusive
+ final int lowerChunkZ = structureboundingbox.getMinZ() >> 4; + final int lowerChunkZ = structureboundingbox.minZ() >> 4;
+ final int upperChunkZ = (structureboundingbox.getMaxZ() - 1) >> 4; // subtract 1 since maxZ is exclusive + final int upperChunkZ = (structureboundingbox.maxZ() - 1) >> 4; // subtract 1 since maxZ is exclusive
+ +
+ final int xChunksLength = (upperChunkX - lowerChunkX + 1); + final int xChunksLength = (upperChunkX - lowerChunkX + 1);
+ final int zChunksLength = (upperChunkZ - lowerChunkZ + 1); + final int zChunksLength = (upperChunkZ - lowerChunkZ + 1);
@ -579,7 +579,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final int matchOne = (STATE_SCHEDULED | STATE_PENDING_TICK) | (excludeTicked ? 0 : (STATE_TICKING | STATE_TICKED)); + final int matchOne = (STATE_SCHEDULED | STATE_PENDING_TICK) | (excludeTicked ? 0 : (STATE_TICKING | STATE_TICKED));
+ +
+ MCUtil.mergeSortedSets((TickNextTickData<T> entry) -> { + MCUtil.mergeSortedSets((TickNextTickData<T> entry) -> {
+ if (!isBlockInSortof(structureboundingbox, entry.getPosition())) { + if (!isBlockInSortof(structureboundingbox, entry.pos)) {
+ return; + return;
+ } + }
+ final int tickState = entry.tickState; + final int tickState = entry.tickState;
@ -603,24 +603,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ @Override + @Override
+ public void copy(BoundingBox structureboundingbox, BlockPos blockposition) { + public void copy(BoundingBox structureboundingbox, BlockPos blockposition) {
+ // start copy from TickListServer // TODO check on update + // 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(); + Iterator<TickNextTickData<T>> iterator = list.iterator();
+ +
+ while (iterator.hasNext()) { + while (iterator.hasNext()) {
+ TickNextTickData<T> nextticklistentry = iterator.next(); + TickNextTickData<T> nextticklistentry = iterator.next();
+ +
+ if (structureboundingbox.hasPoint( nextticklistentry.getPosition())) { + if (structureboundingbox.isInside( nextticklistentry.pos)) {
+ BlockPos blockposition1 = nextticklistentry.getPosition().add(blockposition); + BlockPos blockposition1 = nextticklistentry.pos.offset(blockposition);
+ T t0 = nextticklistentry.getData(); + 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 + // end copy from TickListServer
+ } + }
+ +
+ @Override + @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 + // 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 + // not at ticking status, and ticking status requires neighbours loaded
+ // so with this method we will reduce scheduler churning + // so with this method we will reduce scheduler churning
@ -651,16 +651,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ @Override + @Override
+ public ListTag serialize(ChunkPos chunkcoordintpair) { + public ListTag save(ChunkPos chunkcoordintpair) {
+ // start copy from TickListServer // TODO check on update + // 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 + // end copy from TickListServer
+ } + }
+ +
+ @Override + @Override
+ public int getTotalScheduledEntries() { + public int size() {
+ // good thing this is only used in debug reports // TODO check on update + // good thing this is only used in debug reports // TODO check on update
+ int ret = 0; + int ret = 0;
+ +
@ -713,7 +713,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public static final Comparator<TickNextTickData<?>> ENTRY_COMPARATOR_BY_ID = (entry1, entry2) -> { + public static final Comparator<TickNextTickData<?>> ENTRY_COMPARATOR_BY_ID = (entry1, entry2) -> {
+ return Long.compare(entry1.getId(), entry2.getId()); + 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 + // we do not record the interval, this class is meant to be used on a ring buffer
+ +
@ -727,11 +727,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ +
+ public void addEntryLast(final TickNextTickData<T> entry) { + 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) { + public void addEntryFirst(final TickNextTickData<T> entry) {
+ this.byPriority[entry.getPriority().ordinal()].addFirst(entry); + this.byPriority[entry.priority.ordinal()].addFirst(entry);
+ } + }
+ +
+ public void clear() { + public void clear() {
@ -888,59 +888,58 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+} +}
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/core/BlockPos.java
+++ b/src/main/java/net/minecraft/core/BlockPos.java
@@ -0,0 +0,0 @@ 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 diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java --- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java +++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -0,0 +0,0 @@ public class ChunkHolder { @@ -0,0 +0,0 @@ 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());
@@ -0,0 +0,0 @@ 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; ChunkHolder.this.isTickingReady = true;
+
-
+ // Paper start - rewrite ticklistserver + // Paper start - rewrite ticklistserver
+ ChunkHolder.this.chunkMap.level.onChunkSetTicking(ChunkHolder.this.pos.x, ChunkHolder.this.pos.z); + ChunkHolder.this.chunkMap.level.onChunkSetTicking(ChunkHolder.this.pos.x, ChunkHolder.this.pos.z);
+ // Paper end - rewrite ticklistserver + // 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 diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java --- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java +++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
@@ -0,0 +0,0 @@ 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;
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource { @@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
}, this.mainThreadProcessor);
} }
// Paper end // Paper end
+ // Paper start - rewrite ticklistserver + // Paper start - rewrite ticklistserver
+ public final boolean isTickingReadyMainThread(BlockPos pos) { + 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(); + return chunk != null && chunk.isTickingReady();
+ } + }
+ // Paper end - rewrite ticklistserver + // 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) { 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 = worldserver; this.level = world;
this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(worldserver);
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
@ -960,80 +959,73 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
// Add env and gen to constructor, WorldData -> WorldDataServer // 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) { 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 // Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl @@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
convertable = convertable_conversionsession; DefaultedRegistry registryblocks = Registry.BLOCK;
uuid = WorldUUID.getUUID(convertable_conversionsession.levelPath.toFile());
// CraftBukkit end Objects.requireNonNull(registryblocks);
- this.blockTicks = new ServerTickList<>(this, (block) -> { - this.blockTicks = new ServerTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // CraftBukkit - decompile error // Paper - Timings
- return block == null || block.defaultBlockState().isAir(); + // this.blockTicks = new ServerTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // CraftBukkit - decompile error // Paper - Timings // Paper - copied down
- }, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings Predicate<Fluid> predicate2 = (fluidtype) -> { // CraftBukkit - decompile error
- this.liquidTicks = new ServerTickList<>(this, (fluidtype) -> { return fluidtype == null || fluidtype == Fluids.EMPTY;
- return fluidtype == null || fluidtype == Fluids.EMPTY; };
- }, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper - Timings registryblocks = Registry.FLUID;
Objects.requireNonNull(registryblocks);
+ if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) { + if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) {
+ this.blockTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { + this.blockTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings
+ return block == null || block.defaultBlockState().isAir(); + this.liquidTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, predicate2, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper timings
+ }, 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
+ } else { + } else {
+ this.blockTicks = new ServerTickList<>(this, (block) -> { + this.blockTicks = new ServerTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // CraftBukkit - decompile error // Paper - Timings & copied from above
+ return block == null || block.defaultBlockState().isAir(); this.liquidTicks = new ServerTickList<>(this, predicate2, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // CraftBukkit - decompile error // Paper - Timings
+ }, 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.navigations = Sets.newHashSet(); this.navigatingMobs = new ObjectOpenHashSet();
this.blockEvents = new ObjectLinkedOpenHashSet(); this.blockEvents = new ObjectLinkedOpenHashSet();
this.tickTime = flag1; this.dragonParts = new Int2ObjectOpenHashMap();
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl @@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
if (this.tickTime) { if (this.tickTime) {
long i = this.levelData.getGameTime() + 1L; long i = this.levelData.getGameTime() + 1L;
- this.worldDataServer.setGameTime(i); - this.serverLevelData.setGameTime(i);
+ this.worldDataServer.setGameTime(i); // Paper - diff on change, we want the below to be ran right after this + this.serverLevelData.setGameTime(i); ; // Paper - diff on change, we want the below to be ran right after this
+ this.blockTicks.nextTick(); // Paper + this.blockTicks.nextTick(); // Paper
+ this.liquidTicks.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)) { if (this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) {
this.setDayTime(this.levelData.getDayTime() + 1L); 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 diff --git a/src/main/java/net/minecraft/world/level/ChunkTickList.java b/src/main/java/net/minecraft/world/level/ChunkTickList.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/ChunkTickList.java --- a/src/main/java/net/minecraft/world/level/ChunkTickList.java
+++ b/src/main/java/net/minecraft/world/level/ChunkTickList.java +++ b/src/main/java/net/minecraft/world/level/ChunkTickList.java
@@ -0,0 +0,0 @@ import net.minecraft.core.BlockPos; @@ -0,0 +0,0 @@ public class ChunkTickList<T> implements TickList<T> {
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.resources.ResourceLocation;
+import net.minecraft.server.MinecraftServer;
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()));
}
@@ -0,0 +0,0 @@ public class ChunkTickList<T> implements TickList<T> { @@ -0,0 +0,0 @@ public class ChunkTickList<T> implements TickList<T> {
return nbttaglist; return listTag;
} }
+ private static final int MAX_TICK_DELAY = Integer.getInteger("paper.ticklist-max-tick-delay", -1).intValue(); // Paper - clean up broken entries + 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> function2) {
public static <T> ChunkTickList<T> create(ListTag ticks, Function<T, ResourceLocation> function, Function<ResourceLocation, T> function1) {
List<ChunkTickList.ScheduledTick<T>> list = Lists.newArrayList(); List<ChunkTickList.ScheduledTick<T>> list = Lists.newArrayList();
@@ -0,0 +0,0 @@ public class ChunkTickList<T> implements TickList<T> { @@ -0,0 +0,0 @@ public class ChunkTickList<T> implements TickList<T> {
if (t0 != null) { T object = function2.apply(new ResourceLocation(compoundTag.getString("i")));
BlockPos blockposition = new BlockPos(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z")); if (object != null) {
BlockPos blockPos = new BlockPos(compoundTag.getInt("x"), compoundTag.getInt("y"), compoundTag.getInt("z"));
- list.add(new ChunkTickList.ScheduledTick<>(t0, blockposition, nbttagcompound.getInt("t"), TickPriority.byValue(nbttagcompound.getInt("p")))); - list.add(new ChunkTickList.ScheduledTick<>(object, blockPos, compoundTag.getInt("t"), TickPriority.byValue(compoundTag.getInt("p"))));
+ // Paper start - clean up broken entries + // 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) { + 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; + continue;
+ } + }
+ list.add(new ChunkTickList.ScheduledTick<>(t0, blockposition, delay, TickPriority.byValue(nbttagcompound.getInt("p"))));
+ // Paper end - clean up broken entries + // Paper end - clean up broken entries
+ list.add(new ChunkTickList.ScheduledTick<>(object, blockPos, delay, TickPriority.byValue(compoundTag.getInt("p"))));
} }
} }
@ -1048,164 +1040,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start + // Paper start
+ public void nextTick() {} + public void nextTick() {}
+ // Paper end + // Paper end
+
+ public void tick() {
+ // Paper start - allow overriding
+ this.tick();
+ }
public void tick() { public void tick() {
+ // Paper end
int i = this.tickNextTickList.size(); int i = this.tickNextTickList.size();
if (false) { // CraftBukkit
@@ -0,0 +0,0 @@ public class ServerTickList<T> implements TickList<T> { @@ -0,0 +0,0 @@ public class ServerTickList<T> implements TickList<T> {
return ServerTickList.saveTickList(this.toId, list, this.level.getGameTime());
@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));
} }
public List<TickNextTickData<T>> fetchTicksInChunk(ChunkPos chunkcoordintpair, boolean updateState, boolean getStaleTicks) { - private static <T> ListTag saveTickList(Function<T, ResourceLocation> identifierProvider, Iterable<TickNextTickData<T>> scheduledTicks, long time) {
+ // Paper start - allow overriding + public static <T> ListTag saveTickList(Function<T, ResourceLocation> identifierProvider, Iterable<TickNextTickData<T>> scheduledTicks, long time) { // Paper - private -> public
+ 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;
@@ -0,0 +0,0 @@ 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));
@@ -0,0 +0,0 @@ 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) {
ListTag nbttaglist = new ListTag(); ListTag nbttaglist = new ListTag();
Iterator iterator = scheduledTicks.iterator(); Iterator iterator = scheduledTicks.iterator();
@@ -0,0 +0,0 @@ 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));
}
}
@@ -0,0 +0,0 @@ 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 diff --git a/src/main/java/net/minecraft/world/level/TickNextTickData.java b/src/main/java/net/minecraft/world/level/TickNextTickData.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/TickNextTickData.java --- a/src/main/java/net/minecraft/world/level/TickNextTickData.java
+++ b/src/main/java/net/minecraft/world/level/TickNextTickData.java +++ b/src/main/java/net/minecraft/world/level/TickNextTickData.java
@@ -0,0 +0,0 @@ import net.minecraft.core.BlockPos; @@ -0,0 +0,0 @@ public class TickNextTickData<T> {
public class TickNextTickData<T> { public final BlockPos pos;
public final long triggerTick;
private static final java.util.concurrent.atomic.AtomicLong COUNTER = new java.util.concurrent.atomic.AtomicLong(); // Paper - async chunk loading public final TickPriority priority;
- private final T type;
- public final BlockPos pos;
- public final long triggerTick;
- public final TickPriority priority;
- private final long c; - 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 long c; public final long getId() { return this.c; } // Paper - OBFHELPER
+ private final int hash; // Paper + private final int hash; // Paper
+ public int tickState; // Paper + public int tickState; // Paper
@ -1219,14 +1074,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ this.hash = this.computeHash(); // Paper + this.hash = this.computeHash(); // Paper
} }
public boolean equals(Object object) { @Override
@@ -0,0 +0,0 @@ public class TickNextTickData<T> { @@ -0,0 +0,0 @@ public class TickNextTickData<T> {
}
}
+ // Paper start - optimize hashcode @Override
+ @Override
public int hashCode() { public int hashCode() {
+ // Paper start - optimize hashcode
+ return this.hash; + return this.hash;
+ } + }
+ public final int computeHash() { + public final int computeHash() {
@ -1234,68 +1087,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return this.pos.hashCode(); return this.pos.hashCode();
} }
- public static <T> Comparator<Object> createTimeComparator() { // Paper - decompile fix public static <T> Comparator<TickNextTickData<T>> createTimeComparator() {
- return Comparator.comparingLong((nextticklistentry) -> { - return Comparator.<TickNextTickData<T>>comparingLong((tickNextTickData) -> { // Paper - decompile fix
- return ((TickNextTickData<T>) nextticklistentry).triggerTick; // Paper - decompile fix - return tickNextTickData.triggerTick;
- }).thenComparing((nextticklistentry) -> { - }).thenComparing((tickNextTickData) -> {
- return ((TickNextTickData<T>) nextticklistentry).priority; // Paper - decompile fix - return tickNextTickData.priority;
- }).thenComparingLong((nextticklistentry) -> { - }).thenComparingLong((tickNextTickData) -> {
- return ((TickNextTickData<T>) nextticklistentry).c; // Paper - decompile fix - return tickNextTickData.c;
- }); - });
+ // Paper start - let's not use more functional code for no reason. + // Paper start - let's not use more functional code for no reason.
+ public static <T> Comparator<Object> comparator() { return TickNextTickData.createTimeComparator(); } // Paper - OBFHELPER + return (Comparator) (Comparator<TickNextTickData>) (TickNextTickData nextticklistentry, TickNextTickData nextticklistentry1) -> {
+ public static <T> Comparator<Object> createTimeComparator() { + int i = Long.compare(nextticklistentry.triggerTick, nextticklistentry1.triggerTick);
+ return (Comparator)(Comparator<TickNextTickData>)(TickNextTickData nextticklistentry, TickNextTickData nextticklistentry1) -> {
+ int i = Long.compare(nextticklistentry.getTargetTick(), nextticklistentry1.getTargetTick());
+ +
+ if (i != 0) { + if (i != 0) {
+ return i; + return i;
+ } else { + } else {
+ i = nextticklistentry.getPriority().compareTo(nextticklistentry1.getPriority()); + i = nextticklistentry.priority.compareTo(nextticklistentry1.priority);
+ return i != 0 ? i : Long.compare(nextticklistentry.getId(), nextticklistentry1.getId()); + return i != 0 ? i : Long.compare(nextticklistentry.getId(), nextticklistentry1.getId());
+ } + }
+ }; + };
} + // Paper end - let's not use more functional code for no reason.
+ // 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 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
@@ -0,0 +0,0 @@ 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() {}
@@ -0,0 +0,0 @@ public class BoundingBox {
this.y1 = 512;
} }
+ public final boolean intersects(BoundingBox boundingBox) { return this.intersects(boundingBox); } // Paper - OBFHELPER @Override
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;
}
@@ -0,0 +0,0 @@ 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;
}

View file

@ -70,18 +70,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return fastRandomBounded(this.next(32) & 0xFFFFFFFFL, bound); + 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/core/BlockPos.java
+++ b/src/main/java/net/minecraft/core/BlockPos.java
@@ -0,0 +0,0 @@ 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 diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
@ -108,11 +96,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final BlockPos.MutableBlockPos blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change + 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 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 = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
+ blockposition.setValues(this.findLightingTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper + blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper
if (this.isRainingAt(blockposition)) { if (this.isRainingAt(blockposition)) {
DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition); DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * paperConfig.skeleHorseSpawnChance; // Paper 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
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl @@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
} }
@ -129,7 +117,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end + // Paper end
Biome biomebase = this.getBiome(blockposition); 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 - org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition1, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
+ // Paper start - optimise chunk ticking + // Paper start - optimise chunk ticking
+ blockposition.setY(downY); + blockposition.setY(downY);
@ -138,18 +126,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end + // Paper end
} }
+ blockposition.setY(normalY); // Paper if (flag) {
if (flag && biomebase.shouldSnow(this, blockposition)) { + blockposition.setY(normalY); // Paper
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.defaultBlockState(), null); // CraftBukkit 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) { - BlockState iblockdata = this.getBlockState(blockposition1);
- this.getBlockState(blockposition1).getBlock().handleRain((net.minecraft.world.level.Level) this, blockposition1); + blockposition.setY(downY); // Paper
+ // Paper start - optimise chunk ticking + BlockState iblockdata = this.getBlockState(blockposition); // Paper
+ blockposition.setY(downY); Biome.Precipitation biomebase_precipitation = this.getBiome(blockposition).getPrecipitation();
+ if (flag && this.getBiome(blockposition).getPrecipitation() == Biome.Precipitation.RAIN) {
+ chunk.getBlockState(blockposition).getBlock().handleRain((net.minecraft.world.level.Level) this, blockposition); - if (biomebase_precipitation == Biome.Precipitation.RAIN && biomebase.isColdEnoughToSnow(blockposition1)) {
+ // Paper end + 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 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (randomTickSpeed > 0) { if (randomTickSpeed > 0) {
- LevelChunkSection[] achunksection = chunk.getSections(); - LevelChunkSection[] achunksection = chunk.getSections();
- int l = achunksection.length; - int l = achunksection.length;
-
- for (int i1 = 0; i1 < l; ++i1) {
- LevelChunkSection chunksection = achunksection[i1];
+ gameprofilerfiller.push("randomTick"); + gameprofilerfiller.push("randomTick");
+ timings.chunkTicksBlocks.startTiming(); // Paper + 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()) { - if (chunksection != LevelChunk.EMPTY_SECTION && chunksection.isRandomlyTicking()) {
- int j1 = chunksection.bottomBlockY(); - 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) { + for (int sectionIndex = 0; sectionIndex < 16; ++sectionIndex) {
+ LevelChunkSection section = sections[sectionIndex]; + LevelChunkSection section = sections[sectionIndex];
+ if (section == null || section.tickingList.size() == 0) { + if (section == null || section.tickingList.size() == 0) {
+ continue; + continue;
+ } + }
- for (int k1 = 0; k1 < randomTickSpeed; ++k1) {
- BlockPos blockposition2 = this.getBlockRandomPos(j, j1, k, 15);
+ int yPos = sectionIndex << 4;
- gameprofilerfiller.push("randomTick"); - 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) { + for (int a = 0; a < randomTickSpeed1; ++a) {
+ int tickingBlocks = section.tickingList.size(); + int tickingBlocks = section.tickingList.size();
+ int index = this.randomTickRandom.nextInt(16 * 16 * 16); + int index = this.randomTickRandom.nextInt(16 * 16 * 16);
@ -188,8 +182,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ continue; + continue;
+ } + }
- if (iblockdata.isRandomlyTicking()) { - if (iblockdata1.isRandomlyTicking()) {
- iblockdata.randomTick(this, blockposition2, this.random); - iblockdata1.randomTick(this, blockposition2, this.random);
- } - }
+ long raw = section.tickingList.getRaw(index); + long raw = section.tickingList.getRaw(index);
+ int location = com.destroystokyo.paper.util.maplist.IBlockDataList.getLocationFromRaw(raw); + int location = com.destroystokyo.paper.util.maplist.IBlockDataList.getLocationFromRaw(raw);
@ -197,7 +191,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ int randomY = ((location >>> (4 + 4)) & 255) | yPos; + int randomY = ((location >>> (4 + 4)) & 255) | yPos;
+ int randomZ = (location >>> 4) & 15; + int randomZ = (location >>> 4) & 15;
- FluidState fluid = iblockdata.getFluidState(); - FluidState fluid = iblockdata1.getFluidState();
+ BlockPos blockposition2 = blockposition.setValues(j + randomX, randomY, k + randomZ); + BlockPos blockposition2 = blockposition.setValues(j + randomX, randomY, k + randomZ);
+ BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw); + BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
@ -220,7 +214,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- gameprofilerfiller.pop(); - 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 diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/util/BitStorage.java --- a/src/main/java/net/minecraft/util/BitStorage.java
@ -300,23 +294,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess { @@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
this.entities.remove(entity); // Paper @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 + 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; 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 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java --- a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java +++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
@@ -0,0 +0,0 @@ import net.minecraft.world.level.material.FluidState; @@ -0,0 +0,0 @@ public class LevelChunkSection {
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()); public static final Palette<BlockState> GLOBAL_BLOCKSTATE_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState());
- private final int bottomBlockY; - private final int bottomBlockY;
+ final int bottomBlockY; // Paper - private -> package-private + final int bottomBlockY; // Paper - private -> package-private
@ -325,15 +316,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ short tickingBlockCount; // Paper - private -> package-private + short tickingBlockCount; // Paper - private -> package-private
private short tickingFluidCount; private short tickingFluidCount;
final PalettedContainer<BlockState> states; // Paper - package-private final PalettedContainer<BlockState> states; // Paper - package-private
+ public final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper + public final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper
+
// Paper start - Anti-Xray - Add parameters public LevelChunkSection(int yOffset) {
@Deprecated public LevelChunkSection(int yOffset) { this(yOffset, null, null, true); } // Notice for updates: Please make sure this constructor isn't used anywhere this(yOffset, (short)0, (short)0, (short)0);
public LevelChunkSection(int i, ChunkAccess chunk, Level world, boolean initializeBlocks) {
@@ -0,0 +0,0 @@ public class LevelChunkSection { @@ -0,0 +0,0 @@ public class LevelChunkSection {
--this.nonEmptyBlockCount; --this.nonEmptyBlockCount;
if (iblockdata1.isRandomlyTicking()) { if (blockState.isRandomlyTicking()) {
--this.tickingBlockCount; --this.tickingBlockCount;
+ // Paper start + // Paper start
+ this.tickingList.remove(x, y, z); + this.tickingList.remove(x, y, z);
@ -361,28 +350,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.nonEmptyBlockCount = 0; this.nonEmptyBlockCount = 0;
this.tickingBlockCount = 0; this.tickingBlockCount = 0;
this.tickingFluidCount = 0; this.tickingFluidCount = 0;
- this.states.count((iblockdata, i) -> { - this.states.count((state, count) -> {
+ this.states.forEachLocation((iblockdata, location) -> { // Paper + this.states.forEachLocation((state, location) -> { // Paper
FluidState fluid = iblockdata.getFluidState(); FluidState fluidState = state.getFluidState();
if (!state.isAir()) {
if (!iblockdata.isAir()) { - this.nonEmptyBlockCount = (short)(this.nonEmptyBlockCount + count);
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i); + this.nonEmptyBlockCount = (short)(this.nonEmptyBlockCount + 1); // Paper
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); if (state.isRandomlyTicking()) {
if (iblockdata.isRandomlyTicking()) { - this.tickingBlockCount = (short)(this.tickingBlockCount + count);
- this.tickingBlockCount = (short) (this.tickingBlockCount + i);
+ this.tickingBlockCount = (short) (this.tickingBlockCount + 1);
+ // Paper start + // Paper start
+ this.tickingList.add(location, iblockdata); + this.tickingBlockCount = (short)(this.tickingBlockCount + 1);
+ this.tickingList.add(location, state);
+ // Paper end + // Paper end
} }
} }
if (!fluid.isEmpty()) { if (!fluidState.isEmpty()) {
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i); - this.nonEmptyBlockCount = (short)(this.nonEmptyBlockCount + count);
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); + this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); // Paper
if (fluid.isRandomlyTicking()) { if (fluidState.isRandomlyTicking()) {
- this.tickingFluidCount = (short) (this.tickingFluidCount + i); - this.tickingFluidCount = (short)(this.tickingFluidCount + count);
+ this.tickingFluidCount = (short) (this.tickingFluidCount + 1); + this.tickingFluidCount = (short) (this.tickingFluidCount + 1); // Paper
} }
} }
@ -404,4 +392,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
@FunctionalInterface @FunctionalInterface
public interface CountConsumer<T> { public interface CountConsumer<T> {
void accept(T object, int count);

View file

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

View file

@ -74,11 +74,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private static final int MIN_VIEW_DISTANCE = 3;
private static final Logger LOGGER = LogManager.getLogger(); public static final int MAX_VIEW_DISTANCE = 33;
public static final int MAX_CHUNK_DISTANCE = 33 + ChunkStatus.maxDistance(); 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 + // Paper start - faster copying
+ public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<>(); // Paper - 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 + public final Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap = new ProtectedVisibleChunksMap(); // Paper - faster copying
@ -106,13 +104,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end + // 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 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 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; private final Long2ObjectLinkedOpenHashMap<ChunkHolder> pendingUnloads;
public final LongSet entitiesInLevel; // Paper - private -> public public final LongSet entitiesInLevel; // Paper - private -> public
public final ServerLevel level; public final ServerLevel level;
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -0,0 +0,0 @@ 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) { 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(convertable_conversionsession.getDimensionPath(worldserver.dimension()), "region"), dataFixer, flag); super(new File(session.getDimensionPath(world.dimension()), "region"), dataFixer, dsync);
- this.visibleChunkMap = this.updatingChunkMap.clone(); - this.visibleChunkMap = this.updatingChunkMap.clone();
+ //this.visibleChunks = this.updatingChunks.clone(); // Paper - no more cloning + //this.visibleChunks = this.updatingChunks.clone(); // Paper - no more cloning
this.pendingUnloads = new Long2ObjectLinkedOpenHashMap(); this.pendingUnloads = new Long2ObjectLinkedOpenHashMap();
@ -159,7 +162,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end + // Paper end
+ +
@Nullable @Nullable
public ChunkHolder getVisibleChunkIfPresent(long pos) { // Paper - protected -> public public final ChunkHolder getVisibleChunkIfPresent(long pos) { // Paper - protected -> public
- return (ChunkHolder) this.visibleChunkMap.get(pos); - return (ChunkHolder) this.visibleChunkMap.get(pos);
+ // Paper start - mt safe get + // Paper start - mt safe get
+ if (Thread.currentThread() != this.level.thread) { + if (Thread.currentThread() != this.level.thread) {
@ -173,7 +176,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
protected IntSupplier getChunkQueueLevel(long pos) { protected IntSupplier getChunkQueueLevel(long pos) {
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
// Paper end }
protected void saveAllChunks(boolean flush) { protected void saveAllChunks(boolean flush) {
+ Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunks = this.getVisibleChunks(); // Paper remove clone of visible Chunks unless saving off main thread (watchdog kill) + Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunks = this.getVisibleChunks(); // Paper remove clone of visible Chunks unless saving off main thread (watchdog kill)
@ -223,7 +226,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
void dumpChunks(Writer writer) throws IOException { 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.visibleChunkMap.long2ObjectEntrySet().iterator();
+ ObjectBidirectionalIterator objectbidirectionaliterator = this.getVisibleChunks().long2ObjectEntrySet().iterator(); // Paper + ObjectBidirectionalIterator objectbidirectionaliterator = this.getVisibleChunks().long2ObjectEntrySet().iterator(); // Paper
@ -247,8 +250,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -0,0 +0,0 @@ public class CraftWorld implements World { @@ -0,0 +0,0 @@ public class CraftWorld implements World {
return ret;
} @Override
public int getTileEntityCount() { public int getTileEntityCount() {
+ return net.minecraft.server.MCUtil.ensureMain(() -> { + return net.minecraft.server.MCUtil.ensureMain(() -> {
// We don't use the full world tile entity list, so we must iterate chunks // We don't use the full world tile entity list, so we must iterate chunks
@ -260,9 +263,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return size; return size;
+ }); + });
} }
public int getTickableTileEntityCount() {
return world.tickableBlockEntities.size(); @Override
} @@ -0,0 +0,0 @@ public class CraftWorld implements World {
@Override
public int getChunkCount() { public int getChunkCount() {
+ return net.minecraft.server.MCUtil.ensureMain(() -> { + return net.minecraft.server.MCUtil.ensureMain(() -> {
int ret = 0; int ret = 0;
@ -275,8 +280,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- return ret; - return ret;
+ return ret; }); + return ret; });
} }
public int getPlayerCount() {
return world.players.size(); @Override
@@ -0,0 +0,0 @@ public class CraftWorld implements World { @@ -0,0 +0,0 @@ public class CraftWorld implements World {
@Override @Override
@ -289,6 +294,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ } + }
+ // Paper end + // 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); return chunks.values().stream().map(ChunkHolder::getFullChunk).filter(Objects::nonNull).map(net.minecraft.world.level.chunk.LevelChunk::getBukkitChunk).toArray(Chunk[]::new);
} }

View file

@ -39,7 +39,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java --- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java +++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener { @@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
public boolean wonGame; public boolean wonGame;
private int containerUpdateDelay; // Paper private int containerUpdateDelay; // Paper
public long loginTime; // Paper public long loginTime; // Paper
@ -47,18 +47,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
// Paper start - cancellable death event // Paper start - cancellable death event
public boolean queueHealthUpdatePacket = false; public boolean queueHealthUpdatePacket = false;
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket; 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/stats/StatType.java
+++ b/src/main/java/net/minecraft/stats/StatType.java
@@ -0,0 +0,0 @@ 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 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java --- a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java
@ -127,7 +115,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } else { + } else {
+ long days; + long days;
+ if (world.paperConfig.patrolPerPlayerStart) { + 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 { + } else {
+ days = world.getDayTime() / 24000L; + days = world.getDayTime() / 24000L;
+ } + }

View file

@ -30,19 +30,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java --- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java +++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl @@ -0,0 +0,0 @@ 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();
@@ -0,0 +0,0 @@ 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);
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
this.navigations.add(((Mob) entity).getNavigation());
}
entity.valid = true; // CraftBukkit entity.valid = true; // CraftBukkit
+ this.getChunkSource().addEntity(entity); // Paper - from above to be below valid=true + ServerLevel.this.getChunkSource().addEntity(entity);
// Paper start - Set origin location when the entity is being added to the world }
if (entity.origin == null) {
entity.origin = entity.getBukkitEntity().getLocation(); public void onTrackingEnd(Entity entity) {

View file

@ -8,12 +8,12 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerGamePacketListener { @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
} }
private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<ClientboundPlayerPositionPacket.RelativeArgument> set) { private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<ClientboundPlayerPositionPacket.RelativeArgument> set, boolean flag) {
+ if (player.removed) { + if (player.isRemoved()) {
+ LOGGER.info("Attempt to teleport dead player {} restricted", player.getScoreboardName()); + LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
+ return; + return;
+ } + }
// CraftBukkit start // CraftBukkit start

View file

@ -11,7 +11,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/j
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java +++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -0,0 +0,0 @@ Sections go from 0..16. Now whenever a section is not empty, it can potentially
while (iterator.hasNext()) { while (iterator.hasNext()) {
Entity entity = (Entity) iterator.next(); Entity entity = (Entity) iterator.next();
int j = entity.getType().clientTrackingRange() * 16; int j = entity.getType().clientTrackingRange() * 16;