mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 07:20:24 +01:00
MOAR PATCHES
This commit is contained in:
parent
7dd2ea0897
commit
3ee043dc0c
33 changed files with 384 additions and 843 deletions
|
@ -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);
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -22,8 +22,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ hatching = event.isHatching();
|
||||
+ hatchingType = event.getHatchingType();
|
||||
+ // Paper end
|
||||
+
|
||||
+
|
||||
if (hatching) {
|
||||
for (int i = 0; i < b0; ++i) {
|
||||
Entity entity = level.getWorld().createEntity(new org.bukkit.Location(level.getWorld(), this.getX(), this.getY(), this.getZ(), this.yRot, 0.0F), hatchingType.getEntityClass());
|
||||
Entity entity = level.getWorld().createEntity(new org.bukkit.Location(level.getWorld(), this.getX(), this.getY(), this.getZ(), this.getYRot(), 0.0F), hatchingType.getEntityClass());
|
|
@ -9,20 +9,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
|
||||
disableHopperMoveEvents = getBoolean("hopper.disable-move-event", disableHopperMoveEvents);
|
||||
log("Hopper Move Item Events: " + (disableHopperMoveEvents ? "disabled" : "enabled"));
|
||||
}
|
||||
+
|
||||
|
||||
+ public boolean nerfNetherPortalPigmen = false;
|
||||
+ private void nerfNetherPortalPigmen() {
|
||||
+ nerfNetherPortalPigmen = getBoolean("game-mechanics.nerf-pigmen-from-nether-portals", nerfNetherPortalPigmen);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
public int lightQueueSize = 20;
|
||||
private void lightQueueSize() {
|
||||
lightQueueSize = getInt("light-queue-size", lightQueueSize);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 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
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
public long activatedTick = Integer.MIN_VALUE;
|
||||
public boolean isTemporarilyActive = false; // Paper
|
||||
public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
|
||||
|
@ -30,42 +32,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
protected int numCollisions = 0; // Paper
|
||||
public void inactiveTick() { }
|
||||
// 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) {
|
||||
tag.putBoolean("Paper.FromMobSpawner", true);
|
||||
nbt.putBoolean("Paper.FromMobSpawner", true);
|
||||
}
|
||||
+ if (fromNetherPortal) {
|
||||
+ tag.putBoolean("Paper.FromNetherPortal", true);
|
||||
+ nbt.putBoolean("Paper.FromNetherPortal", true);
|
||||
+ }
|
||||
// Paper end
|
||||
return tag;
|
||||
return nbt;
|
||||
} catch (Throwable throwable) {
|
||||
@@ -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
|
||||
+ fromNetherPortal = tag.getBoolean("Paper.FromNetherPortal");
|
||||
if (tag.contains("Paper.SpawnReason")) {
|
||||
String spawnReasonName = tag.getString("Paper.SpawnReason");
|
||||
spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
|
||||
+ fromNetherPortal = nbt.getBoolean("Paper.FromNetherPortal");
|
||||
if (nbt.contains("Paper.SpawnReason")) {
|
||||
String spawnReasonName = nbt.getString("Paper.SpawnReason");
|
||||
try {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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 {
|
||||
|
||||
if (entity != null) {
|
||||
entity.setPortalCooldown();
|
||||
+ entity.fromNetherPortal = true; // Paper
|
||||
+ if (world.paperConfig.nerfNetherPortalPigmen) ((Mob) entity).aware = false; // Paper
|
||||
+ if (world.paperConfig.nerfNetherPortalPigmen) ((net.minecraft.world.entity.Mob) entity).aware = false; // Paper
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -0,0 +0,0 @@ public class Main {
|
||||
float javaVersion = Float.parseFloat(System.getProperty("java.class.version"));
|
||||
}
|
||||
if (javaVersion > 60.0) {
|
||||
System.err.println("Unsupported Java detected (" + javaVersion + "). Only up to Java 16 is supported.");
|
||||
- return;
|
|
@ -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);
|
|
@ -12,33 +12,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
|
||||
private void nerfNetherPortalPigmen() {
|
||||
nerfNetherPortalPigmen = getBoolean("game-mechanics.nerf-pigmen-from-nether-portals", nerfNetherPortalPigmen);
|
||||
}
|
||||
+
|
||||
|
||||
+ public double zombieVillagerInfectionChance = -1.0;
|
||||
+ private void zombieVillagerInfectionChance() {
|
||||
+ zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance);
|
||||
+ }
|
||||
}
|
||||
+
|
||||
public int lightQueueSize = 20;
|
||||
private void lightQueueSize() {
|
||||
lightQueueSize = getInt("light-queue-size", lightQueueSize);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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 {
|
||||
@Override
|
||||
public void killed(ServerLevel worldserver, LivingEntity entityliving) {
|
||||
super.killed(worldserver, entityliving);
|
||||
- if ((worldserver.getDifficulty() == Difficulty.NORMAL || worldserver.getDifficulty() == Difficulty.HARD) && entityliving instanceof Villager) {
|
||||
- if (worldserver.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
|
||||
+ // Paper start
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance != 0.0 && (level.paperConfig.zombieVillagerInfectionChance != -1.0 || worldserver.getDifficulty() == Difficulty.NORMAL || worldserver.getDifficulty() == Difficulty.HARD) && entityliving instanceof Villager) {
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance == -1.0 && worldserver.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
|
||||
public void killed(ServerLevel world, LivingEntity other) {
|
||||
super.killed(world, other);
|
||||
- if ((world.getDifficulty() == Difficulty.NORMAL || world.getDifficulty() == Difficulty.HARD) && other instanceof Villager) {
|
||||
- if (world.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance != 0.0 && (level.paperConfig.zombieVillagerInfectionChance != -1.0 || world.getDifficulty() == Difficulty.NORMAL || world.getDifficulty() == Difficulty.HARD) && other instanceof Villager) {
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance == -1.0 && world.getDifficulty() != Difficulty.HARD && this.random.nextBoolean()) {
|
||||
return;
|
||||
}
|
||||
+ if (level.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > level.paperConfig.zombieVillagerInfectionChance) {
|
||||
+ return;
|
||||
+ } // Paper end
|
||||
|
||||
Villager entityvillager = (Villager) entityliving;
|
||||
Villager entityvillager = (Villager) other;
|
||||
// CraftBukkit start
|
|
@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@Override
|
||||
protected boolean isImmobile() {
|
||||
- return super.isImmobile() || this.isSleeping();
|
||||
+ return super.isImmobile() || this.isSleeping() || removed || !valid; // Paper - player's who are dead or not in a world shouldn't move...
|
||||
+ return super.isImmobile() || this.isSleeping() || this.isRemoved() || !valid; // Paper - player's who are dead or not in a world shouldn't move...
|
||||
}
|
||||
|
||||
@Override
|
|
@ -13,25 +13,26 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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.advancements = server.getPlayerList().getPlayerAdvancements(this);
|
||||
this.maxUpStep = 1.0F;
|
||||
- this.fudgeSpawnLocation(world);
|
||||
+ //this.c(worldserver); // Paper - don't move to spawn on login, only first join
|
||||
this.textFilter = server.createTextFilterForPlayer(this);
|
||||
|
||||
this.cachedSingleHashSet = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<>(this); // Paper
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ public final void moveToSpawn(ServerLevel worldserver) { fudgeSpawnLocation(worldserver); } // Paper - OBFHELPER
|
||||
private void fudgeSpawnLocation(ServerLevel world) {
|
||||
BlockPos blockposition = world.getSpawn();
|
||||
- private void fudgeSpawnLocation(ServerLevel world) {
|
||||
+ public void fudgeSpawnLocation(ServerLevel world) { // Paper - private -> public
|
||||
BlockPos blockposition = world.getSharedSpawnPos();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player implements ContainerListener {
|
||||
position = Vec3.atCenterOf(((ServerLevel) world).getSpawn());
|
||||
if (world.dimensionType().hasSkyLight() && world.serverLevelData.getGameType() != GameType.ADVENTURE) { // CraftBukkit
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
position = Vec3.atCenterOf(((ServerLevel) world).getSharedSpawnPos());
|
||||
}
|
||||
this.level = world;
|
||||
- this.setPos(position.x(), position.y(), position.z());
|
||||
|
@ -47,8 +48,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
worldserver1 = worldserver;
|
||||
}
|
||||
|
||||
+ if (nbttagcompound == null) player.moveToSpawn(worldserver1); // Paper - only move to spawn on first login, otherwise, stay where you are....
|
||||
+ if (nbttagcompound == null) player.fudgeSpawnLocation(worldserver1); // Paper - only move to spawn on first login, otherwise, stay where you are....
|
||||
+
|
||||
player.setLevel(worldserver1);
|
||||
player.gameMode.setLevel((ServerLevel) player.level);
|
||||
String s1 = "local";
|
||||
|
|
@ -10,12 +10,12 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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() {
|
||||
try {
|
||||
- if (!this.isSpectator() || this.level.hasChunkAt(this.blockPosition())) {
|
||||
+ if (valid && !this.isSpectator() || this.level.hasChunkAt(this.blockPosition())) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
|
||||
- if (!this.isSpectator() || !this.touchingUnloadedChunk()) {
|
||||
+ if (valid && !this.isSpectator() || !this.touchingUnloadedChunk()) { // Paper - don't tick dead players that are not in the world currently (pending respawn)
|
||||
super.tick();
|
||||
}
|
||||
|
|
@ -16,13 +16,13 @@ diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/jav
|
|||
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
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
|
||||
BlockPos blockposition1;
|
||||
|
||||
if (flag1) {
|
||||
+ // Paper start - Ensure spawn chunk is always loaded before calculating Y coordinate
|
||||
+ this.level.getChunkAt(this.level.getSpawn());
|
||||
+ this.level.getChunkAt(this.level.getSharedSpawnPos());
|
||||
+ // Paper end
|
||||
blockposition1 = ServerLevel.END_SPAWN_POINT;
|
||||
} else {
|
||||
blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSpawn());
|
||||
blockposition1 = destination.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, destination.getSharedSpawnPos());
|
|
@ -149,7 +149,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return new Dimension(350, 200);
|
||||
+ }
|
||||
+
|
||||
+ public void stop() { a(); } public void a() {
|
||||
+ public void close() {
|
||||
+ timer.stop();
|
||||
+ ramGraph.stop();
|
||||
+ }
|
||||
|
@ -176,7 +176,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+import java.util.Vector;
|
||||
+
|
||||
+public class RAMDetails extends JList<String> {
|
||||
+ public static final DecimalFormat DECIMAL_FORMAT = Util.peek(new DecimalFormat("########0.000"), (format)
|
||||
+ public static final DecimalFormat DECIMAL_FORMAT = Util.make(new DecimalFormat("########0.000"), (format)
|
||||
+ -> format.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)));
|
||||
+
|
||||
+ private final MinecraftServer server;
|
||||
|
@ -221,7 +221,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ Vector<String> vector = new Vector<>();
|
||||
+ vector.add("Memory use: " + (data.getUsedMem() / 1024L / 1024L) + " mb (" + (data.getFree() * 100L / data.getMax()) + "% free)");
|
||||
+ vector.add("Heap: " + (data.getTotal() / 1024L / 1024L) + " / " + (data.getMax() / 1024L / 1024L) + " mb");
|
||||
+ vector.add("Avg tick: " + DECIMAL_FORMAT.format(getAverage(server.getTickTimes())) + " ms");
|
||||
+ vector.add("Avg tick: " + DECIMAL_FORMAT.format(getAverage(server.tickTimes)) + " ms");
|
||||
+ setListData(vector);
|
||||
+ }
|
||||
+
|
||||
|
@ -383,31 +383,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ 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
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/gui/MinecraftServerGui.java
|
||||
|
@ -418,22 +393,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
JPanel jpanel = new JPanel(new BorderLayout());
|
||||
- StatsComponent guistatscomponent = new StatsComponent(this.server);
|
||||
+ com.destroystokyo.paper.gui.GuiStatsComponent guistatscomponent = new com.destroystokyo.paper.gui.GuiStatsComponent(this.server); // Paper
|
||||
Collection<Runnable> collection = this.finalizers; // CraftBukkit - decompile error
|
||||
|
||||
- this.finalizers.add(guistatscomponent::close);
|
||||
+ this.finalizers.add(guistatscomponent::a);
|
||||
jpanel.add(guistatscomponent, "North");
|
||||
jpanel.add(this.buildPlayerPanel(), "Center");
|
||||
jpanel.setBorder(new TitledBorder(new EtchedBorder(), "Stats"));
|
||||
diff --git a/src/main/java/net/minecraft/server/gui/StatsComponent.java b/src/main/java/net/minecraft/server/gui/StatsComponent.java
|
||||
index 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];
|
||||
Objects.requireNonNull(guistatscomponent);
|
|
@ -66,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ midTickChunksTasksRan = 0; // Paper
|
||||
// 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
|
||||
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
protected void tickChildren(BooleanSupplier shouldKeepTicking) {
|
||||
public void tickChildren(BooleanSupplier shouldKeepTicking) {
|
||||
+ midTickLoadChunks(); // Paper
|
||||
MinecraftTimings.bukkitSchedulerTimer.startTiming(); // Spigot // Paper
|
||||
this.server.getScheduler().mainThreadHeartbeat(this.tickCount); // CraftBukkit
|
||||
|
@ -126,7 +126,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
Iterator iterator = this.getAllLevels().iterator();
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
processQueue.remove().run();
|
||||
this.processQueue.remove().run();
|
||||
}
|
||||
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
|
||||
--- a/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 {
|
||||
this.level.getProfiler().push("purge");
|
||||
this.level.timings.doChunkMap.startTiming(); // Spigot
|
||||
|
@ -169,7 +161,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
|
||||
this.level.timings.doChunkUnload.startTiming(); // Spigot
|
||||
this.level.getProfiler().popPush("unload");
|
||||
this.chunkMap.tick(shouldKeepTicking);
|
||||
this.chunkMap.tick(booleansupplier);
|
||||
+ this.level.getServer().midTickLoadChunks(); // Paper
|
||||
this.level.timings.doChunkUnload.stopTiming(); // Spigot
|
||||
this.level.getProfiler().pop();
|
||||
|
@ -184,13 +176,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
if (optional.isPresent()) {
|
||||
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
|
||||
//this.world.timings.chunkTicks.startTiming(); // Spigot // Paper
|
||||
this.level.tickChunk(chunk, k);
|
||||
//this.world.timings.chunkTicks.stopTiming(); // Spigot // Paper
|
||||
chunk.setInhabitedTime(chunk.getInhabitedTime() + j);
|
||||
if (flag1 && (this.spawnEnemies || this.spawnFriendlies) && this.level.getWorldBorder().isWithinBounds(chunk.getPos()) && !this.chunkMap.isOutsideOfRange(chunkcoordintpair, true)) { // Spigot
|
||||
NaturalSpawner.spawnForChunk(this.level, chunk, spawnercreature_d, this.spawnFriendlies, this.spawnEnemies, flag2);
|
||||
+ if (chunksTicked[0]++ % 10 == 0) this.level.getServer().midTickLoadChunks(); // Paper
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// this.level.timings.doTickTiles.startTiming(); // Spigot // Paper
|
||||
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
|
||||
super.doRunTask(task);
|
||||
}
|
||||
|
@ -210,7 +202,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return false;
|
||||
+ }
|
||||
+ public void midTickLoadChunks() {
|
||||
+ MinecraftServer server = ServerChunkCache.this.level.getServer();
|
||||
+ net.minecraft.server.MinecraftServer server = ServerChunkCache.this.level.getServer();
|
||||
+ // always try to load chunks, restrain generation/other updates only. don't count these towards tick count
|
||||
+ //noinspection StatementWithEmptyBody
|
||||
+ while (pollChunkLoadTasks()) {}
|
||||
|
@ -231,8 +223,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
protected boolean pollTask() {
|
||||
// CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task
|
||||
public boolean pollTask() {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
|
@ -251,21 +243,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
timings.doSounds.stopTiming(); // Spigot
|
||||
+ this.getServer().midTickLoadChunks(); // Paper
|
||||
this.handlingTick = false;
|
||||
gameprofilerfiller.popPush("entities");
|
||||
gameprofilerfiller.pop();
|
||||
boolean flag3 = true || !this.players.isEmpty() || !this.getForcedChunks().isEmpty(); // CraftBukkit - this prevents entity cleanup, other issues on servers with no players
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
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
|
||||
gameprofilerfiller.pop();
|
||||
+ this.getServer().midTickLoadChunks(); // Paper
|
||||
this.tickBlockEntities();
|
||||
}
|
||||
|
||||
gameprofilerfiller.push("entityManagement");
|
||||
+ this.getServer().midTickLoadChunks(); // Paper
|
||||
this.entityManager.tick();
|
||||
gameprofilerfiller.pop();
|
||||
}
|
|
@ -16,14 +16,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
public FluidState getFluidState(int x, int y, int z) {
|
||||
- try {
|
||||
- if (y >= 0 && y >> 4 < this.sections.length) {
|
||||
- LevelChunkSection chunksection = this.sections[y >> 4];
|
||||
- int l = this.getSectionIndex(y);
|
||||
-
|
||||
- if (l >= 0 && l < this.sections.length) {
|
||||
- LevelChunkSection chunksection = this.sections[l];
|
||||
-
|
||||
- if (!LevelChunkSection.isEmpty(chunksection)) {
|
||||
- return chunksection.getFluidState(x & 15, y & 15, z & 15);
|
||||
+ //try { // Paper - remove try catch
|
||||
+ // try { // Paper - remove try catch
|
||||
+ // Paper start - reduce the number of ops in this call
|
||||
+ int index = y >> 4;
|
||||
+ int index = this.getSectionIndex(y);
|
||||
+ if (index >= 0 && index < this.sections.length) {
|
||||
+ LevelChunkSection chunksection = this.sections[index];
|
||||
+
|
||||
|
@ -34,17 +36,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
return Fluids.EMPTY.defaultFluidState();
|
||||
- } catch (Throwable throwable) {
|
||||
- CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting fluid state");
|
||||
- CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being got");
|
||||
+ /*} catch (Throwable throwable) { // Paper - remove try catch
|
||||
+ CrashReport crashreport = CrashReport.a(throwable, "Getting fluid state");
|
||||
+ CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Block being got");
|
||||
|
||||
- crashreportsystemdetails.setDetail("Location", () -> {
|
||||
- return CrashReportCategory.formatLocation(x, y, z);
|
||||
+ crashreportsystemdetails.a("Location", () -> {
|
||||
+ return CrashReportSystemDetails.a(i, j, k);
|
||||
+ /* // Paper - remove try catch
|
||||
} catch (Throwable throwable) {
|
||||
CrashReport crashreport = CrashReport.forThrowable(throwable, "Getting fluid state");
|
||||
CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being got");
|
||||
@@ -0,0 +0,0 @@ public class LevelChunk implements ChunkAccess {
|
||||
});
|
||||
throw new ReportedException(crashreport);
|
||||
}
|
||||
|
@ -60,8 +56,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
public FluidState getFluidState(int x, int y, int z) {
|
||||
- return ((BlockState) this.states.get(x, y, z)).getFluidState();
|
||||
+ return ((BlockState) this.states.get(x, y, z)).getFluidState(); // Paper - diff on change - we expect this to be effectively just getType(x, y, z).getFluid(). If this changes we need to check other patches that use IBlockData#getFluid.
|
||||
- return this.states.get(x, y, z).getFluidState();
|
||||
+ return this.states.get(x, y, z).getFluidState(); // Paper - diff on change - we expect this to be effectively just getType(x, y, z).getFluid(). If this changes we need to check other patches that use IBlockData#getFluid.
|
||||
}
|
||||
|
||||
public void acquire() {
|
|
@ -168,7 +168,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
+ private void queueEntryForTick(final TickNextTickData<T> entry, final ServerChunkCache chunkProvider) {
|
||||
+ if (entry.tickState == STATE_SCHEDULED) {
|
||||
+ if (chunkProvider.isTickingReadyMainThread(entry.getPosition())) {
|
||||
+ if (chunkProvider.isTickingReadyMainThread(entry.pos)) {
|
||||
+ this.toTickThisTick.add(entry);
|
||||
+ entry.tickState = STATE_PENDING_TICK;
|
||||
+ } else {
|
||||
|
@ -179,13 +179,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ private void addToNotTickingReady(final TickNextTickData<T> entry) {
|
||||
+ this.pendingChunkTickLoad.computeIfAbsent(MCUtil.getCoordinateKey(entry.getPosition()), (long keyInMap) -> {
|
||||
+ this.pendingChunkTickLoad.computeIfAbsent(MCUtil.getCoordinateKey(entry.pos), (long keyInMap) -> {
|
||||
+ return new ArrayList<>();
|
||||
+ }).add(entry);
|
||||
+ }
|
||||
+
|
||||
+ private void addToSchedule(final TickNextTickData<T> entry) {
|
||||
+ long delay = entry.getTargetTick() - (this.currentTick + 1);
|
||||
+ long delay = entry.triggerTick - (this.currentTick + 1);
|
||||
+ if (delay < SHORT_SCHEDULE_TICK_THRESHOLD) {
|
||||
+ if (delay < 0) {
|
||||
+ // longScheduled orders by tick time, short scheduled does not
|
||||
|
@ -202,7 +202,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ entry.tickState = STATE_CANCELLED_TICK;
|
||||
+ // short/long scheduled will skip the entry
|
||||
+
|
||||
+ final BlockPos pos = entry.getPosition();
|
||||
+ final BlockPos pos = entry.pos;
|
||||
+ final long blockKey = MCUtil.getBlockKey(pos);
|
||||
+
|
||||
+ final ArrayList<TickNextTickData<T>> currentEntries = this.entriesByBlock.get(blockKey);
|
||||
|
@ -221,7 +221,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final long chunkKey = MCUtil.getCoordinateKey(entry.getPosition());
|
||||
+ final long chunkKey = MCUtil.getCoordinateKey(entry.pos);
|
||||
+
|
||||
+ ObjectRBTreeSet<TickNextTickData<T>> set = this.entriesByChunk.get(chunkKey);
|
||||
+
|
||||
|
@ -246,7 +246,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
+ long delay = entry.getTargetTick() - (this.currentTick + 1);
|
||||
+ long delay = entry.triggerTick - (this.currentTick + 1);
|
||||
+ if (delay >= SHORT_SCHEDULE_TICK_THRESHOLD) {
|
||||
+ this.longScheduled.remove(entry);
|
||||
+ }
|
||||
|
@ -274,7 +274,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
+ // we don't remove items from shortScheduled (but do from longScheduled) because they're cleared at the end of
|
||||
+ // this tick
|
||||
+ if (this.longScheduled.isEmpty() || this.longScheduled.first().getTargetTick() > currentTick) {
|
||||
+ if (this.longScheduled.isEmpty() || this.longScheduled.first().triggerTick > currentTick) {
|
||||
+ // nothing in longScheduled to worry about
|
||||
+ final TickListServerInterval<T> interval = this.shortScheduled[this.shortScheduledIndex];
|
||||
+ for (int i = 0, len = interval.byPriority.length; i < len; ++i) {
|
||||
|
@ -300,7 +300,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ longScheduledIterator.remove();
|
||||
+ if (longScheduledIterator.hasNext()) {
|
||||
+ longCurrent = longScheduledIterator.next();
|
||||
+ if (longCurrent.getTargetTick() > currentTick) {
|
||||
+ if (longCurrent.triggerTick > currentTick) {
|
||||
+ longCurrent = null;
|
||||
+ break;
|
||||
+ }
|
||||
|
@ -316,7 +316,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
+ // add remaining from long scheduled
|
||||
+ for (;;) {
|
||||
+ if (longCurrent == null || longCurrent.getTargetTick() > currentTick) {
|
||||
+ if (longCurrent == null || longCurrent.triggerTick > currentTick) {
|
||||
+ break;
|
||||
+ }
|
||||
+ longScheduledIterator.remove();
|
||||
|
@ -368,7 +368,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ continue;
|
||||
+ }
|
||||
+ try {
|
||||
+ if (chunkProvider.isTickingReadyMainThread(toTick.getPosition())) {
|
||||
+ if (chunkProvider.isTickingReadyMainThread(toTick.pos)) {
|
||||
+ toTick.tickState = STATE_TICKING;
|
||||
+ this.tickFunction.accept(toTick);
|
||||
+ if (toTick.tickState == STATE_TICKING) {
|
||||
|
@ -384,7 +384,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ CrashReport crashreport = CrashReport.forThrowable(thr, "Exception while ticking");
|
||||
+ CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Block being ticked");
|
||||
+
|
||||
+ CrashReportCategory.populateBlockDetails(crashreportsystemdetails, toTick.getPosition(), (BlockState) null);
|
||||
+ CrashReportCategory.populateBlockDetails(crashreportsystemdetails, this.world, toTick.pos, (BlockState) null);
|
||||
+ throw new ReportedException(crashreport);
|
||||
+ // end copy from TickListServer
|
||||
+ }
|
||||
|
@ -413,7 +413,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ entry.tickState = STATE_UNSCHEDULED;
|
||||
+
|
||||
+ final BlockPos pos = entry.getPosition();
|
||||
+ final BlockPos pos = entry.pos;
|
||||
+ final long blockKey = MCUtil.getBlockKey(pos);
|
||||
+
|
||||
+ final ArrayList<TickNextTickData<T>> currentEntries = this.entriesByBlock.get(blockKey);
|
||||
|
@ -432,7 +432,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
+ final long chunkKey = MCUtil.getCoordinateKey(entry.getPosition());
|
||||
+ final long chunkKey = MCUtil.getCoordinateKey(entry.pos);
|
||||
+
|
||||
+ ObjectRBTreeSet<TickNextTickData<T>> set = this.entriesByChunk.get(chunkKey);
|
||||
+
|
||||
|
@ -446,7 +446,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isPendingTickThisTick(final BlockPos blockposition, final T data) {
|
||||
+ public boolean willTickThisTick(final BlockPos blockposition, final T data) {
|
||||
+ final ArrayList<TickNextTickData<T>> entries = this.entriesByBlock.get(MCUtil.getBlockKey(blockposition));
|
||||
+
|
||||
+ if (entries == null) {
|
||||
|
@ -455,7 +455,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
+ for (int i = 0, size = entries.size(); i < size; ++i) {
|
||||
+ final TickNextTickData<T> entry = entries.get(i);
|
||||
+ if (entry.getData() == data && entry.tickState == STATE_PENDING_TICK) {
|
||||
+ if (entry.getType() == data && entry.tickState == STATE_PENDING_TICK) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
|
@ -464,7 +464,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isScheduledForTick(final BlockPos blockposition, final T data) {
|
||||
+ public boolean hasScheduledTick(final BlockPos blockposition, final T data) {
|
||||
+ final ArrayList<TickNextTickData<T>> entries = this.entriesByBlock.get(MCUtil.getBlockKey(blockposition));
|
||||
+
|
||||
+ if (entries == null) {
|
||||
|
@ -473,7 +473,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
+ for (int i = 0, size = entries.size(); i < size; ++i) {
|
||||
+ final TickNextTickData<T> entry = entries.get(i);
|
||||
+ if (entry.getData() == data && entry.tickState == STATE_SCHEDULED) {
|
||||
+ if (entry.getType() == data && entry.tickState == STATE_SCHEDULED) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
|
@ -482,22 +482,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void schedule(BlockPos blockPosition, T t, int i, TickPriority tickListPriority) {
|
||||
+ public void scheduleTick(BlockPos blockPosition, T t, int i, TickPriority tickListPriority) {
|
||||
+ this.schedule(blockPosition, t, i + this.currentTick, tickListPriority);
|
||||
+ }
|
||||
+
|
||||
+ public void schedule(final TickNextTickData<T> entry) {
|
||||
+ this.schedule(entry.getPosition(), entry.getData(), entry.getTargetTick(), entry.getPriority());
|
||||
+ this.schedule(entry.pos, entry.getType(), entry.triggerTick, entry.priority);
|
||||
+ }
|
||||
+
|
||||
+ public void schedule(final BlockPos pos, final T data, final long targetTick, final TickPriority priority) {
|
||||
+ final TickNextTickData<T> entry = new TickNextTickData<>(pos, data, targetTick, priority);
|
||||
+ if (this.excludeFromScheduling.test(entry.getData())) {
|
||||
+ if (this.excludeFromScheduling.test(entry.getType())) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (WARN_ON_EXCESSIVE_DELAY) {
|
||||
+ final long delay = entry.getTargetTick() - this.currentTick;
|
||||
+ final long delay = entry.triggerTick - this.currentTick;
|
||||
+ if (delay >= EXCESSIVE_DELAY_THRESHOLD) {
|
||||
+ MinecraftServer.LOGGER.warn("Entry " + entry.toString() + " has been scheduled with an excessive delay of: " + delay, new Throwable());
|
||||
+ }
|
||||
|
@ -514,7 +514,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ final TickNextTickData<T> currentEntry = currentEntries.get(i);
|
||||
+
|
||||
+ // entries are only blocked from scheduling if currentEntry.equals(toSchedule) && currentEntry is scheduled to tick (NOT including pending)
|
||||
+ if (currentEntry.getData() == entry.getData() && currentEntry.tickState == STATE_SCHEDULED) {
|
||||
+ if (currentEntry.getType() == entry.getType() && currentEntry.tickState == STATE_SCHEDULED) {
|
||||
+ // can't add
|
||||
+ return;
|
||||
+ }
|
||||
|
@ -524,7 +524,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
+ entry.tickState = STATE_SCHEDULED;
|
||||
+
|
||||
+ this.entriesByChunk.computeIfAbsent(MCUtil.getCoordinateKey(entry.getPosition()), (final long keyInMap) -> {
|
||||
+ this.entriesByChunk.computeIfAbsent(MCUtil.getCoordinateKey(entry.pos), (final long keyInMap) -> {
|
||||
+ return new ObjectRBTreeSet<>(TickListServerInterval.ENTRY_COMPARATOR);
|
||||
+ }).add(entry);
|
||||
+
|
||||
|
@ -541,19 +541,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // i.e the y value is ignored? the x, z calc isn't correct?
|
||||
+ // however for the copy op they use the correct intersection, after using this one of course...
|
||||
+ private static boolean isBlockInSortof(final BoundingBox boundingBox, final BlockPos pos) {
|
||||
+ return pos.getX() >= boundingBox.getMinX() && pos.getX() < boundingBox.getMaxX() && pos.getZ() >= boundingBox.getMinZ() && pos.getZ() < boundingBox.getMaxZ();
|
||||
+ return pos.getX() >= boundingBox.minX() && pos.getX() < boundingBox.maxX() && pos.getZ() >= boundingBox.minZ() && pos.getZ() < boundingBox.maxZ();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<TickNextTickData<T>> getEntriesInBoundingBox(final BoundingBox structureboundingbox, final boolean removeReturned, final boolean excludeTicked) {
|
||||
+ if (structureboundingbox.getMinX() == structureboundingbox.getMaxX() || structureboundingbox.getMinZ() == structureboundingbox.getMaxZ()) {
|
||||
+ public List<TickNextTickData<T>> fetchTicksInArea(final BoundingBox structureboundingbox, final boolean removeReturned, final boolean excludeTicked) {
|
||||
+ if (structureboundingbox.minX() == structureboundingbox.maxX() || structureboundingbox.minZ() == structureboundingbox.maxZ()) {
|
||||
+ return Collections.emptyList(); // vanilla behaviour, check isBlockInSortof above
|
||||
+ }
|
||||
+
|
||||
+ final int lowerChunkX = structureboundingbox.getMinX() >> 4;
|
||||
+ final int upperChunkX = (structureboundingbox.getMaxX() - 1) >> 4; // subtract 1 since maxX is exclusive
|
||||
+ final int lowerChunkZ = structureboundingbox.getMinZ() >> 4;
|
||||
+ final int upperChunkZ = (structureboundingbox.getMaxZ() - 1) >> 4; // subtract 1 since maxZ is exclusive
|
||||
+ final int lowerChunkX = structureboundingbox.minX() >> 4;
|
||||
+ final int upperChunkX = (structureboundingbox.maxX() - 1) >> 4; // subtract 1 since maxX is exclusive
|
||||
+ final int lowerChunkZ = structureboundingbox.minZ() >> 4;
|
||||
+ final int upperChunkZ = (structureboundingbox.maxZ() - 1) >> 4; // subtract 1 since maxZ is exclusive
|
||||
+
|
||||
+ final int xChunksLength = (upperChunkX - lowerChunkX + 1);
|
||||
+ final int zChunksLength = (upperChunkZ - lowerChunkZ + 1);
|
||||
|
@ -579,7 +579,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ final int matchOne = (STATE_SCHEDULED | STATE_PENDING_TICK) | (excludeTicked ? 0 : (STATE_TICKING | STATE_TICKED));
|
||||
+
|
||||
+ MCUtil.mergeSortedSets((TickNextTickData<T> entry) -> {
|
||||
+ if (!isBlockInSortof(structureboundingbox, entry.getPosition())) {
|
||||
+ if (!isBlockInSortof(structureboundingbox, entry.pos)) {
|
||||
+ return;
|
||||
+ }
|
||||
+ final int tickState = entry.tickState;
|
||||
|
@ -603,24 +603,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ @Override
|
||||
+ public void copy(BoundingBox structureboundingbox, BlockPos blockposition) {
|
||||
+ // start copy from TickListServer // TODO check on update
|
||||
+ List<TickNextTickData<T>> list = this.getEntriesInBoundingBox(structureboundingbox, false, false);
|
||||
+ List<TickNextTickData<T>> list = this.fetchTicksInArea(structureboundingbox, false, false);
|
||||
+ Iterator<TickNextTickData<T>> iterator = list.iterator();
|
||||
+
|
||||
+ while (iterator.hasNext()) {
|
||||
+ TickNextTickData<T> nextticklistentry = iterator.next();
|
||||
+
|
||||
+ if (structureboundingbox.hasPoint( nextticklistentry.getPosition())) {
|
||||
+ BlockPos blockposition1 = nextticklistentry.getPosition().add(blockposition);
|
||||
+ T t0 = nextticklistentry.getData();
|
||||
+ if (structureboundingbox.isInside( nextticklistentry.pos)) {
|
||||
+ BlockPos blockposition1 = nextticklistentry.pos.offset(blockposition);
|
||||
+ T t0 = nextticklistentry.getType();
|
||||
+
|
||||
+ this.schedule(new TickNextTickData<>(blockposition1, t0, nextticklistentry.getTargetTick(), nextticklistentry.getPriority()));
|
||||
+ this.schedule(new TickNextTickData<>(blockposition1, t0, nextticklistentry.triggerTick, nextticklistentry.priority));
|
||||
+ }
|
||||
+ }
|
||||
+ // end copy from TickListServer
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<TickNextTickData<T>> getEntriesInChunk(ChunkPos chunkPos, boolean removeReturned, boolean excludeTicked) {
|
||||
+ public List<TickNextTickData<T>> fetchTicksInChunk(ChunkPos chunkPos, boolean removeReturned, boolean excludeTicked) {
|
||||
+ // Vanilla DOES get the entries 2 blocks out of the chunk too, but that doesn't matter since we ignore chunks
|
||||
+ // not at ticking status, and ticking status requires neighbours loaded
|
||||
+ // so with this method we will reduce scheduler churning
|
||||
|
@ -651,16 +651,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public ListTag serialize(ChunkPos chunkcoordintpair) {
|
||||
+ public ListTag save(ChunkPos chunkcoordintpair) {
|
||||
+ // start copy from TickListServer // TODO check on update
|
||||
+ List<TickNextTickData<T>> list = this.getEntriesInChunk(chunkcoordintpair, false, true);
|
||||
+ List<TickNextTickData<T>> list = this.fetchTicksInChunk(chunkcoordintpair, false, true);
|
||||
+
|
||||
+ return ServerTickList.serialize(this.getMinecraftKeyFrom, list, this.currentTick);
|
||||
+ return ServerTickList.saveTickList(this.getMinecraftKeyFrom, list, this.currentTick);
|
||||
+ // end copy from TickListServer
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getTotalScheduledEntries() {
|
||||
+ public int size() {
|
||||
+ // good thing this is only used in debug reports // TODO check on update
|
||||
+ int ret = 0;
|
||||
+
|
||||
|
@ -713,7 +713,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ public static final Comparator<TickNextTickData<?>> ENTRY_COMPARATOR_BY_ID = (entry1, entry2) -> {
|
||||
+ return Long.compare(entry1.getId(), entry2.getId());
|
||||
+ };
|
||||
+ public static final Comparator<TickNextTickData<?>> ENTRY_COMPARATOR = (Comparator)TickNextTickData.comparator();
|
||||
+ public static final Comparator<TickNextTickData<?>> ENTRY_COMPARATOR = (Comparator)TickNextTickData.createTimeComparator();
|
||||
+
|
||||
+ // we do not record the interval, this class is meant to be used on a ring buffer
|
||||
+
|
||||
|
@ -727,11 +727,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ public void addEntryLast(final TickNextTickData<T> entry) {
|
||||
+ this.byPriority[entry.getPriority().ordinal()].addLast(entry);
|
||||
+ this.byPriority[entry.priority.ordinal()].addLast(entry);
|
||||
+ }
|
||||
+
|
||||
+ public void addEntryFirst(final TickNextTickData<T> entry) {
|
||||
+ this.byPriority[entry.getPriority().ordinal()].addFirst(entry);
|
||||
+ this.byPriority[entry.priority.ordinal()].addFirst(entry);
|
||||
+ }
|
||||
+
|
||||
+ public void clear() {
|
||||
|
@ -888,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
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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 {
|
||||
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;
|
||||
|
||||
|
||||
-
|
||||
+
|
||||
+ // Paper start - rewrite ticklistserver
|
||||
+ ChunkHolder.this.chunkMap.level.onChunkSetTicking(ChunkHolder.this.pos.x, ChunkHolder.this.pos.z);
|
||||
+ // Paper end - rewrite ticklistserver
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
// Paper end
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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 {
|
||||
}, this.mainThreadProcessor);
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - rewrite ticklistserver
|
||||
+ public final boolean isTickingReadyMainThread(BlockPos pos) {
|
||||
+ ChunkHolder chunk = this.chunkMap.getUpdatingChunkIfPresent(MCUtil.getCoordinateKey(pos));
|
||||
+ ChunkHolder chunk = this.chunkMap.getUpdatingChunkIfPresent(net.minecraft.server.MCUtil.getCoordinateKey(pos));
|
||||
+ return chunk != null && chunk.isTickingReady();
|
||||
+ }
|
||||
+ // Paper end - rewrite ticklistserver
|
||||
+
|
||||
public ServerChunkCache(ServerLevel worldserver, LevelStorageSource.LevelStorageAccess convertable_conversionsession, DataFixer dataFixer, StructureManager structureManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, boolean flag, ChunkProgressListener worldloadlistener, Supplier<DimensionDataStorage> supplier) {
|
||||
this.level = worldserver;
|
||||
this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(worldserver);
|
||||
|
||||
public ServerChunkCache(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureManager structureManager, Executor workerExecutor, ChunkGenerator chunkGenerator, int viewDistance, boolean flag, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkstatusupdatelistener, Supplier<DimensionDataStorage> supplier) {
|
||||
this.level = world;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- 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
|
||||
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
|
||||
convertable = convertable_conversionsession;
|
||||
uuid = WorldUUID.getUUID(convertable_conversionsession.levelPath.toFile());
|
||||
// CraftBukkit end
|
||||
- this.blockTicks = new ServerTickList<>(this, (block) -> {
|
||||
- return block == null || block.defaultBlockState().isAir();
|
||||
- }, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings
|
||||
- this.liquidTicks = new ServerTickList<>(this, (fluidtype) -> {
|
||||
- return fluidtype == null || fluidtype == Fluids.EMPTY;
|
||||
- }, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper - Timings
|
||||
DefaultedRegistry registryblocks = Registry.BLOCK;
|
||||
|
||||
Objects.requireNonNull(registryblocks);
|
||||
- this.blockTicks = new ServerTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // CraftBukkit - decompile error // Paper - Timings
|
||||
+ // this.blockTicks = new ServerTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // CraftBukkit - decompile error // Paper - Timings // Paper - copied down
|
||||
Predicate<Fluid> predicate2 = (fluidtype) -> { // CraftBukkit - decompile error
|
||||
return fluidtype == null || fluidtype == Fluids.EMPTY;
|
||||
};
|
||||
registryblocks = Registry.FLUID;
|
||||
Objects.requireNonNull(registryblocks);
|
||||
+ if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) {
|
||||
+ this.blockTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> {
|
||||
+ return block == null || block.defaultBlockState().isAir();
|
||||
+ }, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings
|
||||
+ this.liquidTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (fluidtype) -> {
|
||||
+ return fluidtype == null || fluidtype == Fluids.EMPTY;
|
||||
+ }, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper - Timings
|
||||
+ this.blockTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings
|
||||
+ this.liquidTicks = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, predicate2, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper timings
|
||||
+ } else {
|
||||
+ this.blockTicks = new ServerTickList<>(this, (block) -> {
|
||||
+ return block == null || block.defaultBlockState().isAir();
|
||||
+ }, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // Paper - Timings
|
||||
+ this.liquidTicks = new ServerTickList<>(this, (fluidtype) -> {
|
||||
+ return fluidtype == null || fluidtype == Fluids.EMPTY;
|
||||
+ }, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // Paper - Timings
|
||||
+ this.blockTicks = new ServerTickList<>(this, predicate, Registry.BLOCK::getKey, this::tickBlock, "Blocks"); // CraftBukkit - decompile error // Paper - Timings & copied from above
|
||||
this.liquidTicks = new ServerTickList<>(this, predicate2, Registry.FLUID::getKey, this::tickLiquid, "Fluids"); // CraftBukkit - decompile error // Paper - Timings
|
||||
+ }
|
||||
this.navigations = Sets.newHashSet();
|
||||
this.navigatingMobs = new ObjectOpenHashSet();
|
||||
this.blockEvents = new ObjectLinkedOpenHashSet();
|
||||
this.tickTime = flag1;
|
||||
this.dragonParts = new Int2ObjectOpenHashMap();
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends net.minecraft.world.level.Level implements Worl
|
||||
if (this.tickTime) {
|
||||
long i = this.levelData.getGameTime() + 1L;
|
||||
|
||||
- this.worldDataServer.setGameTime(i);
|
||||
+ this.worldDataServer.setGameTime(i); // Paper - diff on change, we want the below to be ran right after this
|
||||
- this.serverLevelData.setGameTime(i);
|
||||
+ this.serverLevelData.setGameTime(i); ; // Paper - diff on change, we want the below to be ran right after this
|
||||
+ this.blockTicks.nextTick(); // Paper
|
||||
+ this.liquidTicks.nextTick(); // Paper
|
||||
this.worldDataServer.getScheduledEvents().tick(this.server, i);
|
||||
this.serverLevelData.getScheduledEvents().tick(this.server, i);
|
||||
if (this.levelData.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)) {
|
||||
this.setDayTime(this.levelData.getDayTime() + 1L);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/ChunkTickList.java b/src/main/java/net/minecraft/world/level/ChunkTickList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.ListTag;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
@@ -0,0 +0,0 @@ public class ChunkTickList<T> implements TickList<T> {
|
||||
|
||||
public class ChunkTickList<T> implements TickList<T> {
|
||||
public ChunkTickList(Function<T, ResourceLocation> identifierProvider, List<TickNextTickData<T>> scheduledTicks, long startTime) {
|
||||
this(identifierProvider, scheduledTicks.stream().map((tickNextTickData) -> {
|
||||
- return new ChunkTickList.ScheduledTick(tickNextTickData.getType(), tickNextTickData.pos, (int)(tickNextTickData.triggerTick - startTime), tickNextTickData.priority);
|
||||
+ return new ChunkTickList.ScheduledTick<>(tickNextTickData.getType(), tickNextTickData.pos, (int)(tickNextTickData.triggerTick - startTime), tickNextTickData.priority); // Paper - decompile error
|
||||
}).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
+
|
||||
public static <T> ChunkTickList<T> create(ListTag ticks, Function<T, ResourceLocation> function, Function<ResourceLocation, T> function1) {
|
||||
public static <T> ChunkTickList<T> create(ListTag ticks, Function<T, ResourceLocation> function, Function<ResourceLocation, T> function2) {
|
||||
List<ChunkTickList.ScheduledTick<T>> list = Lists.newArrayList();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ChunkTickList<T> implements TickList<T> {
|
||||
if (t0 != null) {
|
||||
BlockPos blockposition = new BlockPos(nbttagcompound.getInt("x"), nbttagcompound.getInt("y"), nbttagcompound.getInt("z"));
|
||||
|
||||
- list.add(new ChunkTickList.ScheduledTick<>(t0, blockposition, nbttagcompound.getInt("t"), TickPriority.byValue(nbttagcompound.getInt("p"))));
|
||||
T object = function2.apply(new ResourceLocation(compoundTag.getString("i")));
|
||||
if (object != null) {
|
||||
BlockPos blockPos = new BlockPos(compoundTag.getInt("x"), compoundTag.getInt("y"), compoundTag.getInt("z"));
|
||||
- list.add(new ChunkTickList.ScheduledTick<>(object, blockPos, compoundTag.getInt("t"), TickPriority.byValue(compoundTag.getInt("p"))));
|
||||
+ // Paper start - clean up broken entries
|
||||
+ int delay = nbttagcompound.getInt("t");
|
||||
+ int delay = compoundTag.getInt("t");
|
||||
+ if (MAX_TICK_DELAY > 0 && delay > MAX_TICK_DELAY) {
|
||||
+ MinecraftServer.LOGGER.warn("Dropping tick for pos " + blockposition + ", tick delay " + delay);
|
||||
+ net.minecraft.server.MinecraftServer.LOGGER.warn("Dropping tick for pos " + blockPos + ", tick delay " + delay);
|
||||
+ continue;
|
||||
+ }
|
||||
+ list.add(new ChunkTickList.ScheduledTick<>(t0, blockposition, delay, TickPriority.byValue(nbttagcompound.getInt("p"))));
|
||||
+ // Paper end - clean up broken entries
|
||||
+ list.add(new ChunkTickList.ScheduledTick<>(object, blockPos, delay, TickPriority.byValue(compoundTag.getInt("p"))));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1048,164 +1040,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper start
|
||||
+ public void nextTick() {}
|
||||
+ // Paper end
|
||||
+
|
||||
+ public void tick() {
|
||||
+ // Paper start - allow overriding
|
||||
+ this.tick();
|
||||
+ }
|
||||
public void tick() {
|
||||
+ // Paper end
|
||||
int i = this.tickNextTickList.size();
|
||||
|
||||
if (false) { // CraftBukkit
|
||||
@@ -0,0 +0,0 @@ public class ServerTickList<T> implements TickList<T> {
|
||||
|
||||
@Override
|
||||
public boolean willTickThisTick(BlockPos pos, T object) {
|
||||
- return this.currentlyTicking.contains(new TickNextTickData<>(pos, object));
|
||||
+ // Paper start - allow overriding
|
||||
+ return this.isPendingTickThisTick(pos, object);
|
||||
+ }
|
||||
+ public boolean isPendingTickThisTick(BlockPos blockposition, T t0) {
|
||||
+ // Paper end
|
||||
+ return this.currentlyTicking.contains(new TickNextTickData<>(blockposition, t0));
|
||||
return ServerTickList.saveTickList(this.toId, list, this.level.getGameTime());
|
||||
}
|
||||
|
||||
public List<TickNextTickData<T>> fetchTicksInChunk(ChunkPos chunkcoordintpair, boolean updateState, boolean getStaleTicks) {
|
||||
+ // Paper start - allow overriding
|
||||
+ return this.getEntriesInChunk(chunkcoordintpair, updateState, getStaleTicks);
|
||||
+ }
|
||||
+ public List<TickNextTickData<T>> getEntriesInChunk(ChunkPos chunkcoordintpair, boolean flag, boolean flag1) {
|
||||
+ // Paper end
|
||||
int i = (chunkcoordintpair.x << 4) - 2;
|
||||
int j = i + 16 + 2;
|
||||
int k = (chunkcoordintpair.z << 4) - 2;
|
||||
int l = k + 16 + 2;
|
||||
|
||||
- return this.fetchTicksInArea(new BoundingBox(i, 0, k, j, 256, l), updateState, getStaleTicks);
|
||||
+ return this.fetchTicksInArea(new BoundingBox(i, 0, k, j, 256, l), flag, flag1);
|
||||
}
|
||||
|
||||
public List<TickNextTickData<T>> fetchTicksInArea(BoundingBox bounds, boolean updateState, boolean getStaleTicks) {
|
||||
- List<TickNextTickData<T>> list = this.fetchTicksInArea((List) null, this.tickNextTickList, bounds, updateState);
|
||||
+ // Paper start - allow overriding
|
||||
+ return this.getEntriesInBoundingBox(bounds, updateState, getStaleTicks);
|
||||
+ }
|
||||
+ public List<TickNextTickData<T>> getEntriesInBoundingBox(BoundingBox structureboundingbox, boolean flag, boolean flag1) {
|
||||
+ // Paper end
|
||||
+ List<TickNextTickData<T>> list = this.fetchTicksInArea((List) null, this.tickNextTickList, structureboundingbox, flag);
|
||||
|
||||
- if (updateState && list != null) {
|
||||
+ if (flag && list != null) {
|
||||
this.tickNextTickSet.removeAll(list);
|
||||
}
|
||||
|
||||
- list = this.fetchTicksInArea(list, this.currentlyTicking, bounds, updateState);
|
||||
- if (!getStaleTicks) {
|
||||
- list = this.fetchTicksInArea(list, this.alreadyTicked, bounds, updateState);
|
||||
+ list = this.fetchTicksInArea(list, this.currentlyTicking, structureboundingbox, flag);
|
||||
+ if (!flag1) {
|
||||
+ list = this.fetchTicksInArea(list, this.alreadyTicked, structureboundingbox, flag);
|
||||
}
|
||||
|
||||
return list == null ? Collections.emptyList() : list;
|
||||
@@ -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) {
|
||||
- private static <T> ListTag saveTickList(Function<T, ResourceLocation> identifierProvider, Iterable<TickNextTickData<T>> scheduledTicks, long time) {
|
||||
+ public static <T> ListTag saveTickList(Function<T, ResourceLocation> identifierProvider, Iterable<TickNextTickData<T>> scheduledTicks, long time) { // Paper - private -> public
|
||||
ListTag nbttaglist = new ListTag();
|
||||
Iterator iterator = scheduledTicks.iterator();
|
||||
@@ -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
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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;
|
||||
public class TickNextTickData<T> {
|
||||
|
||||
private static final java.util.concurrent.atomic.AtomicLong COUNTER = new java.util.concurrent.atomic.AtomicLong(); // Paper - async chunk loading
|
||||
- private final T type;
|
||||
- public final BlockPos pos;
|
||||
- public final long triggerTick;
|
||||
- public final TickPriority priority;
|
||||
@@ -0,0 +0,0 @@ public class TickNextTickData<T> {
|
||||
public final BlockPos pos;
|
||||
public final long triggerTick;
|
||||
public final TickPriority priority;
|
||||
- private final long c;
|
||||
+ private final T type; public final T getData() { return this.type; } // Paper - OBFHELPER
|
||||
+ public final BlockPos pos; public final BlockPos getPosition() { return this.pos; } // Paper - OBFHELPER
|
||||
+ public final long triggerTick; public final long getTargetTick() { return this.triggerTick; } // Paper - OBFHELPER
|
||||
+ public final TickPriority priority; public final TickPriority getPriority() { return this.priority; } // Paper - OBFHELPER
|
||||
+ private final long c; public final long getId() { return this.c; } // Paper - OBFHELPER
|
||||
+ private final int hash; // Paper
|
||||
+ public int tickState; // Paper
|
||||
|
@ -1219,14 +1074,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ this.hash = this.computeHash(); // Paper
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class TickNextTickData<T> {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - optimize hashcode
|
||||
+ @Override
|
||||
@Override
|
||||
public int hashCode() {
|
||||
+ // Paper start - optimize hashcode
|
||||
+ return this.hash;
|
||||
+ }
|
||||
+ public final int computeHash() {
|
||||
|
@ -1234,68 +1087,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
return this.pos.hashCode();
|
||||
}
|
||||
|
||||
- public static <T> Comparator<Object> createTimeComparator() { // Paper - decompile fix
|
||||
- return Comparator.comparingLong((nextticklistentry) -> {
|
||||
- return ((TickNextTickData<T>) nextticklistentry).triggerTick; // Paper - decompile fix
|
||||
- }).thenComparing((nextticklistentry) -> {
|
||||
- return ((TickNextTickData<T>) nextticklistentry).priority; // Paper - decompile fix
|
||||
- }).thenComparingLong((nextticklistentry) -> {
|
||||
- return ((TickNextTickData<T>) nextticklistentry).c; // Paper - decompile fix
|
||||
public static <T> Comparator<TickNextTickData<T>> createTimeComparator() {
|
||||
- return Comparator.<TickNextTickData<T>>comparingLong((tickNextTickData) -> { // Paper - decompile fix
|
||||
- return tickNextTickData.triggerTick;
|
||||
- }).thenComparing((tickNextTickData) -> {
|
||||
- return tickNextTickData.priority;
|
||||
- }).thenComparingLong((tickNextTickData) -> {
|
||||
- return tickNextTickData.c;
|
||||
- });
|
||||
+ // Paper start - let's not use more functional code for no reason.
|
||||
+ public static <T> Comparator<Object> comparator() { return TickNextTickData.createTimeComparator(); } // Paper - OBFHELPER
|
||||
+ public static <T> Comparator<Object> createTimeComparator() {
|
||||
+ return (Comparator)(Comparator<TickNextTickData>)(TickNextTickData nextticklistentry, TickNextTickData nextticklistentry1) -> {
|
||||
+ int i = Long.compare(nextticklistentry.getTargetTick(), nextticklistentry1.getTargetTick());
|
||||
+ // Paper start - let's not use more functional code for no reason.
|
||||
+ return (Comparator) (Comparator<TickNextTickData>) (TickNextTickData nextticklistentry, TickNextTickData nextticklistentry1) -> {
|
||||
+ int i = Long.compare(nextticklistentry.triggerTick, nextticklistentry1.triggerTick);
|
||||
+
|
||||
+ if (i != 0) {
|
||||
+ return i;
|
||||
+ } else {
|
||||
+ i = nextticklistentry.getPriority().compareTo(nextticklistentry1.getPriority());
|
||||
+ i = nextticklistentry.priority.compareTo(nextticklistentry1.priority);
|
||||
+ return i != 0 ? i : Long.compare(nextticklistentry.getId(), nextticklistentry1.getId());
|
||||
+ }
|
||||
+ };
|
||||
}
|
||||
+ // Paper end - let's not use more functional code for no reason.
|
||||
|
||||
public String toString() {
|
||||
return this.type + ": " + this.pos + ", " + this.triggerTick + ", " + this.priority + ", " + this.c;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/BoundingBox.java b/src/main/java/net/minecraft/world/level/levelgen/structure/BoundingBox.java
|
||||
index 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;
|
||||
+ // Paper end - let's not use more functional code for no reason.
|
||||
}
|
||||
|
||||
+ public final boolean intersects(BoundingBox boundingBox) { return this.intersects(boundingBox); } // Paper - OBFHELPER
|
||||
public boolean intersects(BoundingBox other) {
|
||||
return this.x1 >= other.x0 && this.x0 <= other.x1 && this.z1 >= other.z0 && this.z0 <= other.z1 && this.y1 >= other.y0 && this.y0 <= other.y1;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@Override
|
|
@ -70,18 +70,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ 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
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- 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
|
||||
|
||||
if (!this.paperConfig.disableThunder && flag && this.isThundering() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder
|
||||
- blockposition = this.findLightingTargetAround(this.getBlockRandomPos(j, 0, k, 15));
|
||||
+ blockposition.setValues(this.findLightingTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper
|
||||
- blockposition = this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15));
|
||||
+ blockposition.set(this.findLightningTargetAround(this.getBlockRandomPos(j, 0, k, 15))); // Paper
|
||||
if (this.isRainingAt(blockposition)) {
|
||||
DifficultyInstance difficultydamagescaler = this.getCurrentDifficultyAt(blockposition);
|
||||
boolean flag1 = this.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.getEffectiveDifficulty() * paperConfig.skeleHorseSpawnChance; // Paper
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -129,7 +117,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
Biome biomebase = this.getBiome(blockposition);
|
||||
|
||||
- if (biomebase.shouldFreeze(this, blockposition1)) {
|
||||
- if (biomebase.shouldFreeze((LevelReader) this, blockposition1)) {
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition1, Blocks.ICE.defaultBlockState(), null); // CraftBukkit
|
||||
+ // Paper start - optimise chunk ticking
|
||||
+ blockposition.setY(downY);
|
||||
|
@ -138,18 +126,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
}
|
||||
|
||||
+ blockposition.setY(normalY); // Paper
|
||||
if (flag && biomebase.shouldSnow(this, blockposition)) {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.defaultBlockState(), null); // CraftBukkit
|
||||
}
|
||||
if (flag) {
|
||||
+ blockposition.setY(normalY); // Paper
|
||||
if (biomebase.shouldSnow(this, blockposition)) {
|
||||
org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(this, blockposition, Blocks.SNOW.defaultBlockState(), null); // CraftBukkit
|
||||
}
|
||||
|
||||
- if (flag && this.getBiome(blockposition1).getPrecipitation() == Biome.Precipitation.RAIN) {
|
||||
- this.getBlockState(blockposition1).getBlock().handleRain((net.minecraft.world.level.Level) this, blockposition1);
|
||||
+ // Paper start - optimise chunk ticking
|
||||
+ blockposition.setY(downY);
|
||||
+ if (flag && this.getBiome(blockposition).getPrecipitation() == Biome.Precipitation.RAIN) {
|
||||
+ chunk.getBlockState(blockposition).getBlock().handleRain((net.minecraft.world.level.Level) this, blockposition);
|
||||
+ // Paper end
|
||||
- BlockState iblockdata = this.getBlockState(blockposition1);
|
||||
+ blockposition.setY(downY); // Paper
|
||||
+ BlockState iblockdata = this.getBlockState(blockposition); // Paper
|
||||
Biome.Precipitation biomebase_precipitation = this.getBiome(blockposition).getPrecipitation();
|
||||
|
||||
- if (biomebase_precipitation == Biome.Precipitation.RAIN && biomebase.isColdEnoughToSnow(blockposition1)) {
|
||||
+ if (biomebase_precipitation == Biome.Precipitation.RAIN && biomebase.isColdEnoughToSnow(blockposition)) { // Paper
|
||||
biomebase_precipitation = Biome.Precipitation.SNOW;
|
||||
}
|
||||
|
||||
- iblockdata.getBlock().handlePrecipitation(iblockdata, (net.minecraft.world.level.Level) this, blockposition1, biomebase_precipitation);
|
||||
+ iblockdata.getBlock().handlePrecipitation(iblockdata, (net.minecraft.world.level.Level) this, blockposition, biomebase_precipitation); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,27 +154,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if (randomTickSpeed > 0) {
|
||||
- LevelChunkSection[] achunksection = chunk.getSections();
|
||||
- int l = achunksection.length;
|
||||
-
|
||||
- for (int i1 = 0; i1 < l; ++i1) {
|
||||
- LevelChunkSection chunksection = achunksection[i1];
|
||||
+ gameprofilerfiller.push("randomTick");
|
||||
+ timings.chunkTicksBlocks.startTiming(); // Paper
|
||||
|
||||
- for (int i1 = 0; i1 < l; ++i1) {
|
||||
- LevelChunkSection chunksection = achunksection[i1];
|
||||
+ LevelChunkSection[] sections = chunk.getSections();
|
||||
|
||||
- if (chunksection != LevelChunk.EMPTY_SECTION && chunksection.isRandomlyTicking()) {
|
||||
- int j1 = chunksection.bottomBlockY();
|
||||
+ LevelChunkSection[] sections = chunk.getSections();
|
||||
|
||||
- for (int k1 = 0; k1 < randomTickSpeed; ++k1) {
|
||||
- BlockPos blockposition2 = this.getBlockRandomPos(j, j1, k, 15);
|
||||
+ for (int sectionIndex = 0; sectionIndex < 16; ++sectionIndex) {
|
||||
+ LevelChunkSection section = sections[sectionIndex];
|
||||
+ if (section == null || section.tickingList.size() == 0) {
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- for (int k1 = 0; k1 < randomTickSpeed; ++k1) {
|
||||
- BlockPos blockposition2 = this.getBlockRandomPos(j, j1, k, 15);
|
||||
+ int yPos = sectionIndex << 4;
|
||||
|
||||
- gameprofilerfiller.push("randomTick");
|
||||
- BlockState iblockdata = chunksection.getBlockState(blockposition2.getX() - j, blockposition2.getY() - j1, blockposition2.getZ() - k);
|
||||
- BlockState iblockdata1 = chunksection.getBlockState(blockposition2.getX() - j, blockposition2.getY() - j1, blockposition2.getZ() - k);
|
||||
+ int yPos = sectionIndex << 4;
|
||||
+ for (int a = 0; a < randomTickSpeed1; ++a) {
|
||||
+ int tickingBlocks = section.tickingList.size();
|
||||
+ int index = this.randomTickRandom.nextInt(16 * 16 * 16);
|
||||
|
@ -188,8 +182,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ continue;
|
||||
+ }
|
||||
|
||||
- if (iblockdata.isRandomlyTicking()) {
|
||||
- iblockdata.randomTick(this, blockposition2, this.random);
|
||||
- if (iblockdata1.isRandomlyTicking()) {
|
||||
- iblockdata1.randomTick(this, blockposition2, this.random);
|
||||
- }
|
||||
+ long raw = section.tickingList.getRaw(index);
|
||||
+ int location = com.destroystokyo.paper.util.maplist.IBlockDataList.getLocationFromRaw(raw);
|
||||
|
@ -197,7 +191,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ int randomY = ((location >>> (4 + 4)) & 255) | yPos;
|
||||
+ int randomZ = (location >>> 4) & 15;
|
||||
|
||||
- FluidState fluid = iblockdata.getFluidState();
|
||||
- FluidState fluid = iblockdata1.getFluidState();
|
||||
+ BlockPos blockposition2 = blockposition.setValues(j + randomX, randomY, k + randomZ);
|
||||
+ BlockState iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
|
||||
|
||||
|
@ -220,7 +214,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- gameprofilerfiller.pop();
|
||||
}
|
||||
|
||||
protected BlockPos findLightingTargetAround(BlockPos pos) {
|
||||
private Optional<BlockPos> findLightningRod(BlockPos pos) {
|
||||
diff --git a/src/main/java/net/minecraft/util/BitStorage.java b/src/main/java/net/minecraft/util/BitStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- 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
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/LevelChunk.java
|
||||
@@ -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
|
||||
+ @Override public int getHeight(Heightmap.Types type, int x, int z) { // Paper
|
||||
@Override
|
||||
public int getHeight(Heightmap.Types type, int x, int z) {
|
||||
return ((Heightmap) this.heightmaps.get(type)).getFirstAvailable(x & 15, z & 15) - 1;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java b/src/main/java/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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;
|
||||
public class LevelChunkSection {
|
||||
|
||||
@@ -0,0 +0,0 @@ public class LevelChunkSection {
|
||||
public static final int SECTION_HEIGHT = 16;
|
||||
public static final int SECTION_SIZE = 4096;
|
||||
public static final Palette<BlockState> GLOBAL_BLOCKSTATE_PALETTE = new GlobalPalette<>(Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState());
|
||||
- private final int bottomBlockY;
|
||||
+ final int bottomBlockY; // Paper - private -> package-private
|
||||
|
@ -325,15 +316,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ short tickingBlockCount; // Paper - private -> package-private
|
||||
private short tickingFluidCount;
|
||||
final PalettedContainer<BlockState> states; // Paper - package-private
|
||||
|
||||
+ public final com.destroystokyo.paper.util.maplist.IBlockDataList tickingList = new com.destroystokyo.paper.util.maplist.IBlockDataList(); // Paper
|
||||
+
|
||||
// Paper start - Anti-Xray - Add parameters
|
||||
@Deprecated public LevelChunkSection(int yOffset) { this(yOffset, null, null, true); } // Notice for updates: Please make sure this constructor isn't used anywhere
|
||||
public LevelChunkSection(int i, ChunkAccess chunk, Level world, boolean initializeBlocks) {
|
||||
|
||||
public LevelChunkSection(int yOffset) {
|
||||
this(yOffset, (short)0, (short)0, (short)0);
|
||||
@@ -0,0 +0,0 @@ public class LevelChunkSection {
|
||||
--this.nonEmptyBlockCount;
|
||||
if (iblockdata1.isRandomlyTicking()) {
|
||||
if (blockState.isRandomlyTicking()) {
|
||||
--this.tickingBlockCount;
|
||||
+ // Paper start
|
||||
+ this.tickingList.remove(x, y, z);
|
||||
|
@ -361,28 +350,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.nonEmptyBlockCount = 0;
|
||||
this.tickingBlockCount = 0;
|
||||
this.tickingFluidCount = 0;
|
||||
- this.states.count((iblockdata, i) -> {
|
||||
+ this.states.forEachLocation((iblockdata, location) -> { // Paper
|
||||
FluidState fluid = iblockdata.getFluidState();
|
||||
|
||||
if (!iblockdata.isAir()) {
|
||||
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
||||
if (iblockdata.isRandomlyTicking()) {
|
||||
- this.tickingBlockCount = (short) (this.tickingBlockCount + i);
|
||||
+ this.tickingBlockCount = (short) (this.tickingBlockCount + 1);
|
||||
- this.states.count((state, count) -> {
|
||||
+ this.states.forEachLocation((state, location) -> { // Paper
|
||||
FluidState fluidState = state.getFluidState();
|
||||
if (!state.isAir()) {
|
||||
- this.nonEmptyBlockCount = (short)(this.nonEmptyBlockCount + count);
|
||||
+ this.nonEmptyBlockCount = (short)(this.nonEmptyBlockCount + 1); // Paper
|
||||
if (state.isRandomlyTicking()) {
|
||||
- this.tickingBlockCount = (short)(this.tickingBlockCount + count);
|
||||
+ // Paper start
|
||||
+ this.tickingList.add(location, iblockdata);
|
||||
+ this.tickingBlockCount = (short)(this.tickingBlockCount + 1);
|
||||
+ this.tickingList.add(location, state);
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
if (!fluid.isEmpty()) {
|
||||
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
||||
if (fluid.isRandomlyTicking()) {
|
||||
- this.tickingFluidCount = (short) (this.tickingFluidCount + i);
|
||||
+ this.tickingFluidCount = (short) (this.tickingFluidCount + 1);
|
||||
if (!fluidState.isEmpty()) {
|
||||
- this.nonEmptyBlockCount = (short)(this.nonEmptyBlockCount + count);
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); // Paper
|
||||
if (fluidState.isRandomlyTicking()) {
|
||||
- this.tickingFluidCount = (short)(this.tickingFluidCount + count);
|
||||
+ this.tickingFluidCount = (short) (this.tickingFluidCount + 1); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,4 +392,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
@FunctionalInterface
|
||||
public interface CountConsumer<T> {
|
||||
|
||||
void accept(T object, int count);
|
|
@ -17,66 +17,26 @@ diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/ma
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.PlayerAdvancements;
|
||||
import net.minecraft.server.ServerScoreboard;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.server.level.ServerPlayerGameMode;
|
||||
+import net.minecraft.server.level.TicketType;
|
||||
+import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
+import net.minecraft.server.network.ServerLoginPacketListenerImpl;
|
||||
+import net.minecraft.sounds.SoundEvents;
|
||||
+import net.minecraft.sounds.SoundSource;
|
||||
+import net.minecraft.stats.ServerStatsCounter;
|
||||
+import net.minecraft.stats.Stats;
|
||||
import net.minecraft.tags.BlockTags;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
+import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import net.minecraft.world.level.Level;
|
||||
@@ -0,0 +0,0 @@ import io.papermc.paper.adventure.PaperAdventure; // Paper
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
-import net.minecraft.server.level.ServerLevel;
|
||||
-import net.minecraft.server.level.ServerPlayer;
|
||||
-import net.minecraft.server.level.ServerPlayerGameMode;
|
||||
-import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
-import net.minecraft.server.network.ServerLoginPacketListenerImpl;
|
||||
-import net.minecraft.sounds.SoundEvents;
|
||||
-import net.minecraft.sounds.SoundSource;
|
||||
-import net.minecraft.stats.ServerStatsCounter;
|
||||
-import net.minecraft.stats.Stats;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
entityplayer1.forceSetPositionRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
|
||||
// CraftBukkit end
|
||||
|
||||
+ worldserver1.getChunkSource().addRegionTicket(TicketType.POST_TELEPORT, new ChunkPos(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
|
||||
while (avoidSuffocation && !worldserver1.noCollision(entityplayer1) && entityplayer1.getY() < 256.0D) {
|
||||
+ worldserver1.getChunkSource().addRegionTicket(net.minecraft.server.level.TicketType.POST_TELEPORT, new net.minecraft.world.level.ChunkPos(location.getBlockX() >> 4, location.getBlockZ() >> 4), 1, entityplayer.getId()); // Paper
|
||||
while (avoidSuffocation && !worldserver1.noCollision(entityplayer1) && entityplayer1.getY() < (double) worldserver1.getMaxBuildHeight()) {
|
||||
entityplayer1.setPos(entityplayer1.getX(), entityplayer1.getY() + 1.0D, entityplayer1.getZ());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 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
|
||||
@@ -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;
|
||||
|
||||
ChunkMap.TrackedEntity tracker; // Paper
|
||||
+ public boolean collisionLoadChunks = false; // Paper
|
||||
public Throwable addedToWorldStack; // Paper - entity debug
|
||||
public CraftEntity getBukkitEntity() {
|
||||
if (bukkitEntity == null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/CollisionGetter.java b/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/CollisionGetter.java
|
||||
|
@ -84,30 +44,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -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
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/CollisionSpliterator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/CollisionSpliterator.java
|
||||
@@ -0,0 +0,0 @@ import java.util.function.Consumer;
|
||||
import javax.annotation.Nullable;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Cursor3D;
|
||||
+import net.minecraft.server.MCUtil;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import net.minecraft.server.level.WorldGenRegion;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
public class CollisionSpliterator extends AbstractSpliterator<VoxelShape> {
|
||||
|
||||
public class CollisionSpliterator extends AbstractSpliterator<VoxelShape> {
|
||||
@Nullable
|
||||
- private final Entity source;
|
||||
+ 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;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CollisionSpliterator extends AbstractSpliterator<VoxelShape> {
|
||||
boolean collisionCheck(Consumer<? super VoxelShape> consumer) {
|
||||
while (true) {
|
||||
boolean collisionCheck(Consumer<? super VoxelShape> action) {
|
||||
while(true) {
|
||||
if (this.cursor.advance()) {
|
||||
- int i = this.cursor.nextX();
|
||||
- int j = this.cursor.nextY();
|
||||
|
@ -133,53 +83,51 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ int j = this.cursor.nextY(); final int y = j;
|
||||
+ int k = this.cursor.nextZ(); final int z = k;
|
||||
int l = this.cursor.getNextType();
|
||||
|
||||
if (l == 3) {
|
||||
continue;
|
||||
}
|
||||
|
||||
- BlockGetter iblockaccess = this.getChunk(i, k);
|
||||
-
|
||||
- if (iblockaccess == null) {
|
||||
- BlockGetter blockGetter = this.getChunk(i, k);
|
||||
- if (blockGetter == null) {
|
||||
+ // Paper start - ensure we don't load chunks
|
||||
+ Entity entity = this.getEntity();
|
||||
+ BlockPos.MutableBlockPos blockposition_mutableblockposition = this.getMutablePos();
|
||||
+ boolean far = entity != null && 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);
|
||||
+
|
||||
+ boolean isRegionLimited = this.getCollisionAccess() instanceof WorldGenRegion;
|
||||
+ BlockState iblockdata = isRegionLimited ? Blocks.VOID_AIR.defaultBlockState() : ((!far && entity instanceof ServerPlayer) || (entity != null && entity.collisionLoadChunks)
|
||||
+ boolean isRegionLimited = this.getCollisionAccess() instanceof net.minecraft.server.level.WorldGenRegion;
|
||||
+ BlockState blockState = isRegionLimited ? Blocks.VOID_AIR.defaultBlockState() : ((!far && entity instanceof net.minecraft.server.level.ServerPlayer) || (entity != null && entity.collisionLoadChunks)
|
||||
+ ? this.getCollisionAccess().getBlockState(blockposition_mutableblockposition)
|
||||
+ : this.getCollisionAccess().getTypeIfLoaded(blockposition_mutableblockposition)
|
||||
+ );
|
||||
+
|
||||
+ if (iblockdata == null) {
|
||||
+ if (!(entity instanceof ServerPlayer) || entity.level.paperConfig.preventMovingIntoUnloadedChunks) {
|
||||
+ VoxelShape voxelshape3 = Shapes.of(far ? entity.getBoundingBox() : new AABB(new BlockPos(x, y, z)));
|
||||
+ consumer.accept(voxelshape3);
|
||||
+ if (blockState == null) {
|
||||
+ if (!(entity instanceof net.minecraft.server.level.ServerPlayer) || entity.level.paperConfig.preventMovingIntoUnloadedChunks) {
|
||||
+ VoxelShape voxelshape3 = Shapes.create(far ? entity.getBoundingBox() : new AABB(new BlockPos(x, y, z)));
|
||||
+ action.accept(voxelshape3);
|
||||
+ return true;
|
||||
+ }
|
||||
continue;
|
||||
}
|
||||
-
|
||||
- this.pos.set(i, j, k);
|
||||
- BlockState iblockdata = iblockaccess.getBlockState(this.pos);
|
||||
+ // Paper - moved up
|
||||
+ // Paper end
|
||||
|
||||
if (!this.predicate.test(iblockdata, this.pos) || l == 1 && !iblockdata.hasLargeCollisionShape() || l == 2 && !iblockdata.is(Blocks.MOVING_PISTON)) {
|
||||
- this.pos.set(i, j, k);
|
||||
- BlockState blockState = blockGetter.getBlockState(this.pos);
|
||||
if (!this.predicate.test(blockState, this.pos) || l == 1 && !blockState.hasLargeCollisionShape() || l == 2 && !blockState.is(Blocks.MOVING_PISTON)) {
|
||||
continue;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
+++ b/src/main/java/net/minecraft/world/phys/shapes/Shapes.java
|
||||
@@ -0,0 +0,0 @@ public final class Shapes {
|
||||
|
||||
if (k2 < 3) {
|
||||
blockposition_mutableblockposition.set(enumaxiscycle1, i2, j2, l1);
|
||||
- BlockState iblockdata = world.getBlockState(blockposition_mutableblockposition);
|
||||
+ BlockState iblockdata = world.getTypeIfLoaded(blockposition_mutableblockposition); // Paper
|
||||
+ if (iblockdata == null) return 0.0D; // Paper
|
||||
|
||||
if ((k2 != 1 || iblockdata.hasLargeCollisionShape()) && (k2 != 2 || iblockdata.is(Blocks.MOVING_PISTON))) {
|
||||
initial = iblockdata.getCollisionShape((BlockGetter) world, blockposition_mutableblockposition, context).collide(enumdirection_enumaxis2, box.move((double) (-blockposition_mutableblockposition.getX()), (double) (-blockposition_mutableblockposition.getY()), (double) (-blockposition_mutableblockposition.getZ())), initial);
|
||||
if (s < 3) {
|
||||
mutableBlockPos.set(axisCycle, q, r, p);
|
||||
- BlockState blockState = world.getBlockState(mutableBlockPos);
|
||||
+ BlockState blockState = world.getTypeIfLoaded(mutableBlockPos); // Paper
|
||||
+ if (blockState == null) return 0.0D; // Paper
|
||||
if ((s != 1 || blockState.hasLargeCollisionShape()) && (s != 2 || blockState.is(Blocks.MOVING_PISTON))) {
|
||||
initial = blockState.getCollisionShape(world, mutableBlockPos, context).collide(axis3, box.move((double)(-mutableBlockPos.getX()), (double)(-mutableBlockPos.getY()), (double)(-mutableBlockPos.getZ())), initial);
|
||||
if (Math.abs(initial) < 1.0E-7D) {
|
|
@ -74,11 +74,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/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
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final int MIN_VIEW_DISTANCE = 3;
|
||||
public static final int MAX_VIEW_DISTANCE = 33;
|
||||
public static final int MAX_CHUNK_DISTANCE = 33 + ChunkStatus.maxDistance();
|
||||
- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap();
|
||||
- public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap;
|
||||
+ // Paper start - faster copying
|
||||
+ public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<>(); // Paper - faster copying
|
||||
+ public final Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap = new ProtectedVisibleChunksMap(); // Paper - faster copying
|
||||
|
@ -106,13 +104,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
+ public final com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<ChunkHolder> pendingVisibleChunks = new com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<ChunkHolder>(); // Paper - this is used if the visible chunks is updated while iterating only
|
||||
+ public transient com.destroystokyo.paper.util.map.Long2ObjectLinkedOpenHashMapFastCopy<ChunkHolder> visibleChunksClone; // Paper - used for async access of visible chunks, clone and cache only when needed
|
||||
public static final int FORCED_TICKET_LEVEL = 31;
|
||||
- public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap();
|
||||
- public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap;
|
||||
+ // public final Long2ObjectLinkedOpenHashMap<ChunkHolder> updatingChunkMap = new Long2ObjectLinkedOpenHashMap(); // Paper - moved up
|
||||
+ // public volatile Long2ObjectLinkedOpenHashMap<ChunkHolder> visibleChunkMap; // Paper - moved up
|
||||
private final Long2ObjectLinkedOpenHashMap<ChunkHolder> pendingUnloads;
|
||||
public final LongSet entitiesInLevel; // Paper - private -> public
|
||||
public final ServerLevel level;
|
||||
@@ -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) {
|
||||
super(new File(convertable_conversionsession.getDimensionPath(worldserver.dimension()), "region"), dataFixer, flag);
|
||||
public ChunkMap(ServerLevel world, LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, StructureManager structureManager, Executor executor, BlockableEventLoop<Runnable> mainThreadExecutor, LightChunkGetter chunkProvider, ChunkGenerator chunkGenerator, ChunkProgressListener worldGenerationProgressListener, ChunkStatusUpdateListener chunkStatusChangeListener, Supplier<DimensionDataStorage> persistentStateManagerFactory, int viewDistance, boolean dsync) {
|
||||
super(new File(session.getDimensionPath(world.dimension()), "region"), dataFixer, dsync);
|
||||
- this.visibleChunkMap = this.updatingChunkMap.clone();
|
||||
+ //this.visibleChunks = this.updatingChunks.clone(); // Paper - no more cloning
|
||||
this.pendingUnloads = new Long2ObjectLinkedOpenHashMap();
|
||||
|
@ -159,7 +162,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
public ChunkHolder getVisibleChunkIfPresent(long pos) { // Paper - protected -> public
|
||||
public final ChunkHolder getVisibleChunkIfPresent(long pos) { // Paper - protected -> public
|
||||
- return (ChunkHolder) this.visibleChunkMap.get(pos);
|
||||
+ // Paper start - mt safe get
|
||||
+ if (Thread.currentThread() != this.level.thread) {
|
||||
|
@ -173,7 +176,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
protected IntSupplier getChunkQueueLevel(long pos) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// Paper end
|
||||
}
|
||||
|
||||
protected void saveAllChunks(boolean flush) {
|
||||
+ 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 {
|
||||
CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("entity_count").addColumn("block_entity_count").build(writer);
|
||||
CsvOutput csvwriter = CsvOutput.builder().addColumn("x").addColumn("z").addColumn("level").addColumn("in_memory").addColumn("status").addColumn("full_status").addColumn("accessible_ready").addColumn("ticking_ready").addColumn("entity_ticking_ready").addColumn("ticket").addColumn("spawning").addColumn("block_entity_count").build(writer);
|
||||
- ObjectBidirectionalIterator objectbidirectionaliterator = this.visibleChunkMap.long2ObjectEntrySet().iterator();
|
||||
+ ObjectBidirectionalIterator objectbidirectionaliterator = this.getVisibleChunks().long2ObjectEntrySet().iterator(); // Paper
|
||||
|
||||
|
@ -247,8 +250,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/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 {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTileEntityCount() {
|
||||
+ return net.minecraft.server.MCUtil.ensureMain(() -> {
|
||||
// We don't use the full world tile entity list, so we must iterate chunks
|
||||
|
@ -260,9 +263,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
return size;
|
||||
+ });
|
||||
}
|
||||
public int getTickableTileEntityCount() {
|
||||
return world.tickableBlockEntities.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
|
||||
|
||||
@Override
|
||||
public int getChunkCount() {
|
||||
+ return net.minecraft.server.MCUtil.ensureMain(() -> {
|
||||
int ret = 0;
|
||||
|
@ -275,8 +280,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- return ret;
|
||||
+ return ret; });
|
||||
}
|
||||
public int getPlayerCount() {
|
||||
return world.players.size();
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
|
||||
|
||||
@Override
|
||||
|
@ -289,6 +294,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ }
|
||||
+ // 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);
|
||||
}
|
|
@ -39,7 +39,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/ma
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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;
|
||||
private int containerUpdateDelay; // Paper
|
||||
public long loginTime; // Paper
|
||||
|
@ -47,18 +47,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
// Paper start - cancellable death event
|
||||
public boolean queueHealthUpdatePacket = false;
|
||||
public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
diff --git a/src/main/java/net/minecraft/stats/StatType.java b/src/main/java/net/minecraft/stats/StatType.java
|
||||
index 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
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/PatrolSpawner.java
|
||||
|
@ -127,7 +115,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ } else {
|
||||
+ long days;
|
||||
+ if (world.paperConfig.patrolPerPlayerStart) {
|
||||
+ days = entityhuman.getStats().getValue(Stats.CUSTOM.get(Stats.PLAY_ONE_MINUTE)) / 24000L; // PLAY_ONE_MINUTE is actually counting in ticks, a misnomer by Mojang
|
||||
+ days = entityhuman.getStats().getValue(Stats.CUSTOM.get(Stats.PLAY_TIME)) / 24000L; // PLAY_ONE_MINUTE is actually counting in ticks, a misnomer by Mojang
|
||||
+ } else {
|
||||
+ days = world.getDayTime() / 24000L;
|
||||
+ }
|
|
@ -30,19 +30,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- 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
|
||||
}
|
||||
|
||||
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
|
||||
+ this.getChunkSource().addEntity(entity); // Paper - from above to be below valid=true
|
||||
// Paper start - Set origin location when the entity is being added to the world
|
||||
if (entity.origin == null) {
|
||||
entity.origin = entity.getBukkitEntity().getLocation();
|
||||
+ ServerLevel.this.getChunkSource().addEntity(entity);
|
||||
}
|
||||
|
||||
public void onTrackingEnd(Entity entity) {
|
|
@ -8,12 +8,12 @@ diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListener
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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) {
|
||||
+ if (player.removed) {
|
||||
+ LOGGER.info("Attempt to teleport dead player {} restricted", player.getScoreboardName());
|
||||
private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<ClientboundPlayerPositionPacket.RelativeArgument> set, boolean flag) {
|
||||
+ if (player.isRemoved()) {
|
||||
+ LOGGER.info("Attempt to teleport removed player {} restricted", player.getScoreboardName());
|
||||
+ return;
|
||||
+ }
|
||||
// CraftBukkit start
|
|
@ -11,7 +11,7 @@ diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/j
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/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()) {
|
||||
Entity entity = (Entity) iterator.next();
|
||||
int j = entity.getType().clientTrackingRange() * 16;
|
Loading…
Reference in a new issue