More more more more more more more work
This commit is contained in:
parent
105034367d
commit
cc171b1928
25 changed files with 272 additions and 305 deletions
|
@ -0,0 +1,40 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Tue, 7 Feb 2017 16:55:35 -0600
|
||||
Subject: [PATCH] Make targetSize more aggressive in the chunk unload queue
|
||||
|
||||
#NOTE: Vanilla now does incremental chunk saves
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index fb3b0693abb6f2f044d39508b727fb3a2ad16823..4a2739edb01c97c99524dc96decbdcb12e0b7d4f 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -215,7 +215,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.playerMap = new PlayerMap();
|
||||
this.entityMap = new Int2ObjectOpenHashMap();
|
||||
this.chunkTypeCache = new Long2ByteOpenHashMap();
|
||||
- this.unloadQueue = Queues.newConcurrentLinkedQueue();
|
||||
+ this.unloadQueue = new com.destroystokyo.paper.utils.CachedSizeConcurrentLinkedQueue<>(); // Paper - need constant-time size()
|
||||
this.structureManager = structureManager;
|
||||
File file = session.getDimensionPath(world.dimension());
|
||||
|
||||
@@ -518,7 +518,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
// Spigot start
|
||||
org.spigotmc.SlackActivityAccountant activityAccountant = this.level.getServer().slackActivityAccountant;
|
||||
activityAccountant.startActivity(0.5);
|
||||
- int targetSize = (int) (this.toDrop.size() * ChunkMap.UNLOAD_QUEUE_RESIZE_FACTOR);
|
||||
+ int targetSize = Math.min(this.toDrop.size() - 100, (int) (this.toDrop.size() * ChunkMap.UNLOAD_QUEUE_RESIZE_FACTOR)); // Paper - Make more aggressive
|
||||
// Spigot end
|
||||
while (longiterator.hasNext()) { // Spigot
|
||||
long j = longiterator.nextLong();
|
||||
@@ -540,7 +540,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
Runnable runnable;
|
||||
|
||||
- while ((shouldKeepTicking.getAsBoolean() || this.unloadQueue.size() > 2000) && (runnable = (Runnable) this.unloadQueue.poll()) != null) {
|
||||
+ int queueTarget = Math.min(this.unloadQueue.size() - 100, (int) (this.unloadQueue.size() * UNLOAD_QUEUE_RESIZE_FACTOR)); // Paper - Target this queue as well
|
||||
+ while ((shouldKeepTicking.getAsBoolean() || this.unloadQueue.size() > queueTarget) && (runnable = (Runnable)this.unloadQueue.poll()) != null) { // Paper - Target this queue as well
|
||||
runnable.run();
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Thu, 11 Jan 2018 16:47:28 -0600
|
||||
Subject: [PATCH] Make max squid spawn height configurable
|
||||
|
||||
#NOTE: Spigot removed the min option, Vanilla now has the same spawn rule for all ambient water animals
|
||||
I don't know why upstream made only the minimum height configurable but
|
||||
whatever
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index e2894138d3efb32161087ad2a1093b8c15c56a65..5892823425055efb92bf635b035d62981942b966 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -383,4 +383,9 @@ public class PaperWorldConfig {
|
||||
disableCreeperLingeringEffect = getBoolean("disable-creeper-lingering-effect", false);
|
||||
log("Creeper lingering effect: " + disableCreeperLingeringEffect);
|
||||
}
|
||||
+
|
||||
+ public double squidMaxSpawnHeight;
|
||||
+ private void squidMaxSpawnHeight() {
|
||||
+ squidMaxSpawnHeight = getDouble("squid-spawn-height.maximum", 0.0D);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Squid.java b/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
index 3ffc1ee8a9ae63c8678c12736fab5d6ba0a21a5b..4da560f6e4da0750bda78b900b2d916d58adfccb 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Squid.java
|
||||
@@ -211,7 +211,8 @@ public class Squid extends WaterAnimal {
|
||||
}
|
||||
|
||||
public static boolean checkSquidSpawnRules(EntityType<Squid> type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) {
|
||||
- return pos.getY() > world.getMinecraftWorld().spigotConfig.squidSpawnRangeMin && pos.getY() < world.getSeaLevel(); // Spigot
|
||||
+ final double maxHeight = world.getMinecraftWorld().paperConfig.squidMaxSpawnHeight > 0 ? world.getMinecraftWorld().paperConfig.squidMaxSpawnHeight : world.getSeaLevel(); // Paper
|
||||
+ return pos.getY() > world.getMinecraftWorld().spigotConfig.squidSpawnRangeMin && pos.getY() < maxHeight; // Spigot // Paper
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,108 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Wed, 15 Aug 2018 12:05:12 -0700
|
||||
Subject: [PATCH] Optimize BlockPosition helper methods
|
||||
|
||||
Resolves #1338
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
index ed52d042f41942ae512148fbba310093358ead68..80d8873bc2512ecde6a531e974b14e9b48402d64 100644
|
||||
--- a/src/main/java/net/minecraft/core/BlockPos.java
|
||||
+++ b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
@@ -130,67 +130,84 @@ public class BlockPos extends Vec3i {
|
||||
|
||||
@Override
|
||||
public BlockPos above() {
|
||||
- return this.relative(Direction.UP);
|
||||
+ return new BlockPos(this.getX(), this.getY() + 1, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos above(int distance) {
|
||||
- return this.relative(Direction.UP, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos below() {
|
||||
- return this.relative(Direction.DOWN);
|
||||
+ return new BlockPos(this.getX(), this.getY() - 1, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos below(int i) {
|
||||
- return this.relative(Direction.DOWN, i);
|
||||
+ return i == 0 ? this : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos north() {
|
||||
- return this.relative(Direction.NORTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos north(int distance) {
|
||||
- return this.relative(Direction.NORTH, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos south() {
|
||||
- return this.relative(Direction.SOUTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos south(int distance) {
|
||||
- return this.relative(Direction.SOUTH, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos west() {
|
||||
- return this.relative(Direction.WEST);
|
||||
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos west(int distance) {
|
||||
- return this.relative(Direction.WEST, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos east() {
|
||||
- return this.relative(Direction.EAST);
|
||||
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos east(int distance) {
|
||||
- return this.relative(Direction.EAST, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos relative(Direction direction) {
|
||||
+ // Paper Start - Optimize BlockPosition
|
||||
+ switch(direction) {
|
||||
+ case UP:
|
||||
+ return new BlockPos(this.getX(), this.getY() + 1, this.getZ());
|
||||
+ case DOWN:
|
||||
+ return new BlockPos(this.getX(), this.getY() - 1, this.getZ());
|
||||
+ case NORTH:
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1);
|
||||
+ case SOUTH:
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1);
|
||||
+ case WEST:
|
||||
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ());
|
||||
+ case EAST:
|
||||
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ());
|
||||
+ default:
|
||||
return new BlockPos(this.getX() + direction.getStepX(), this.getY() + direction.getStepY(), this.getZ() + direction.getStepZ());
|
||||
+ }
|
||||
+ // Paper End
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 18 Aug 2018 12:43:16 -0400
|
||||
Subject: [PATCH] Restore vanlla default mob-spawn-range and water animals
|
||||
limit
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
index c45332fa7b374e7775ca24a7065af3cb5c85d7cf..45be7d1821497f13ab0da3c4bbff7585238e902e 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
@@ -165,7 +165,7 @@ public class SpigotWorldConfig
|
||||
public byte mobSpawnRange;
|
||||
private void mobSpawnRange()
|
||||
{
|
||||
- this.mobSpawnRange = (byte) this.getInt( "mob-spawn-range", 6 );
|
||||
+ this.mobSpawnRange = (byte) getInt( "mob-spawn-range", 8 ); // Paper - Vanilla
|
||||
this.log( "Mob Spawn Range: " + this.mobSpawnRange );
|
||||
}
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 24 Aug 2018 08:18:42 -0500
|
||||
Subject: [PATCH] Slime Pathfinder Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index 239f3a17ab8cff4e6c97044e4f8e6755abac193d..82747a12d4977ed2d26d203f690ecc9bdbfadfc1 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -44,6 +44,12 @@ import net.minecraft.world.level.biome.Biomes;
|
||||
import net.minecraft.world.level.levelgen.WorldgenRandom;
|
||||
import net.minecraft.world.level.storage.loot.BuiltInLootTables;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
+// Paper start
|
||||
+import com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent;
|
||||
+import com.destroystokyo.paper.event.entity.SlimeSwimEvent;
|
||||
+import com.destroystokyo.paper.event.entity.SlimeTargetLivingEntityEvent;
|
||||
+import com.destroystokyo.paper.event.entity.SlimeWanderEvent;
|
||||
+// Paper end
|
||||
// CraftBukkit start
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -108,6 +114,7 @@ public class Slime extends Mob implements Enemy {
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
+ nbt.putBoolean("Paper.canWander", this.canWander); // Paper
|
||||
nbt.putInt("Size", this.getSize() - 1);
|
||||
nbt.putBoolean("wasOnGround", this.wasOnGround);
|
||||
}
|
||||
@@ -116,6 +123,11 @@ public class Slime extends Mob implements Enemy {
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
this.setSize(nbt.getInt("Size") + 1, false);
|
||||
super.readAdditionalSaveData(nbt);
|
||||
+ // Paper start - check exists before loading or this will be loaded as false
|
||||
+ if (nbt.contains("Paper.canWander")) {
|
||||
+ this.canWander = nbt.getBoolean("Paper.canWander");
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.wasOnGround = nbt.getBoolean("wasOnGround");
|
||||
}
|
||||
|
||||
@@ -454,7 +466,7 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
|
||||
+ return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeSwimEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -481,7 +493,15 @@ public class Slime extends Mob implements Enemy {
|
||||
public boolean canUse() {
|
||||
LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
- return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : this.slime.getMoveControl() instanceof Slime.SlimeMoveControl);
|
||||
+ // Paper start
|
||||
+ if (entityliving == null || !entityliving.isAlive()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (!this.slime.canAttack(entityliving)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -494,7 +514,15 @@ public class Slime extends Mob implements Enemy {
|
||||
public boolean canContinueToUse() {
|
||||
LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
- return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : --this.growTiredTimer > 0);
|
||||
+ // Paper start
|
||||
+ if (entityliving == null || !entityliving.isAlive()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (!this.slime.canAttack(entityliving)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return --this.growTiredTimer > 0 && this.slime.canWander && new SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -502,6 +530,13 @@ public class Slime extends Mob implements Enemy {
|
||||
this.slime.lookAt((Entity) this.slime.getTarget(), 10.0F, 10.0F);
|
||||
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.slime.getYRot(), this.slime.isDealsDamage());
|
||||
}
|
||||
+
|
||||
+ // Paper start - clear timer and target when goal resets
|
||||
+ public void stop() {
|
||||
+ this.growTiredTimer = 0;
|
||||
+ this.slime.setTarget(null);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
private static class SlimeRandomDirectionGoal extends Goal {
|
||||
@@ -517,14 +552,18 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return this.slime.getTarget() == null && (this.slime.onGround || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
|
||||
+ return this.slime.getTarget() == null && (this.slime.onGround || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander; // Paper - add canWander
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (--this.nextRandomizeTime <= 0) {
|
||||
this.nextRandomizeTime = 40 + this.slime.getRandom().nextInt(60);
|
||||
- this.chosenDegrees = (float) this.slime.getRandom().nextInt(360);
|
||||
+ // Paper start
|
||||
+ SlimeChangeDirectionEvent event = new SlimeChangeDirectionEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (float) this.slime.getRandom().nextInt(360));
|
||||
+ if (!this.slime.canWander || !event.callEvent()) return;
|
||||
+ this.chosenDegrees = event.getNewYaw();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.chosenDegrees, false);
|
||||
@@ -542,7 +581,7 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return !this.slime.isPassenger();
|
||||
+ return !this.slime.isPassenger() && this.slime.canWander && new SlimeWanderEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -550,4 +589,15 @@ public class Slime extends Mob implements Enemy {
|
||||
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setWantedMovement(1.0D);
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ private boolean canWander = true;
|
||||
+ public boolean canWander() {
|
||||
+ return canWander;
|
||||
+ }
|
||||
+
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ this.canWander = canWander;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
index 67fc37f909639e1effe6034526990f10d575d14d..4d401403de2399919043651345eed91c11ac986f 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
@@ -34,4 +34,16 @@ public class CraftSlime extends CraftMob implements Slime {
|
||||
public EntityType getType() {
|
||||
return EntityType.SLIME;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean canWander() {
|
||||
+ return getHandle().canWander();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ getHandle().setWander(canWander);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Wed, 8 Aug 2018 16:33:21 -0600
|
||||
Subject: [PATCH] Configurable speed for water flowing over lava
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index ff6cf94dec708c6d3cac837ca03be2fe12d5e05f..29703f57969b80e25ff9a4971e640f34fb212edf 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -425,4 +425,10 @@ public class PaperWorldConfig {
|
||||
this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick);
|
||||
log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default");
|
||||
}
|
||||
+
|
||||
+ public int waterOverLavaFlowSpeed;
|
||||
+ private void waterOverLavaFlowSpeed() {
|
||||
+ waterOverLavaFlowSpeed = getInt("water-over-lava-flow-speed", 5);
|
||||
+ log("Water over lava flow speed: " + waterOverLavaFlowSpeed);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
index db4bcb600ab43439ef65d4510fb20d770ce9dba3..087601ffdeea97ec4cbb9959607bdcbcbae7c6fa 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
@@ -26,6 +26,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty;
|
||||
import net.minecraft.world.level.material.FlowingFluid;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.level.material.FluidState;
|
||||
+import net.minecraft.world.level.material.Material;
|
||||
import net.minecraft.world.level.pathfinder.PathComputationType;
|
||||
import net.minecraft.world.level.storage.loot.LootContext;
|
||||
import net.minecraft.world.phys.shapes.CollisionContext;
|
||||
@@ -109,11 +110,27 @@ public class LiquidBlock extends Block implements BucketPickup {
|
||||
@Override
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||
- world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
|
||||
+ world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Get flow speed. Throttle if its water and flowing adjacent to lava
|
||||
+ public int getFlowSpeed(Level world, BlockPos blockposition) {
|
||||
+ if (this.material == Material.WATER) {
|
||||
+ if (
|
||||
+ world.getMaterialIfLoaded(blockposition.north(1)) == Material.LAVA ||
|
||||
+ world.getMaterialIfLoaded(blockposition.south(1)) == Material.LAVA ||
|
||||
+ world.getMaterialIfLoaded(blockposition.west(1)) == Material.LAVA ||
|
||||
+ world.getMaterialIfLoaded(blockposition.east(1)) == Material.LAVA
|
||||
+ ) {
|
||||
+ return world.paperConfig.waterOverLavaFlowSpeed;
|
||||
+ }
|
||||
+ }
|
||||
+ return this.fluid.getTickDelay(world);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
if (state.getFluidState().isSource() || neighborState.getFluidState().isSource()) {
|
||||
@@ -126,7 +143,7 @@ public class LiquidBlock extends Block implements BucketPickup {
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean notify) {
|
||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||
- world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay((LevelReader) world));
|
||||
+ world.getLiquidTicks().scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: miclebrick <miclebrick@outlook.com>
|
||||
Date: Thu, 23 Aug 2018 11:45:32 -0400
|
||||
Subject: [PATCH] Optimize CraftBlockData Creation
|
||||
|
||||
Avoids a hashmap lookup by cacheing a reference to the CraftBlockData
|
||||
and cloning it when one is needed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index adf1c04d34383d088a3fc8c06cdc8b55552c354f..a087eec747bb355afd627c6042d20440c3e43e1b 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -637,6 +637,14 @@ public abstract class BlockBehaviour {
|
||||
this.hasPostProcess = blockbase_info.hasPostProcess;
|
||||
this.emissiveRendering = blockbase_info.emissiveRendering;
|
||||
}
|
||||
+ // Paper start - impl cached craft block data, lazy load to fix issue with loading at the wrong time
|
||||
+ private org.bukkit.craftbukkit.block.data.CraftBlockData cachedCraftBlockData;
|
||||
+
|
||||
+ public org.bukkit.craftbukkit.block.data.CraftBlockData createCraftBlockData() {
|
||||
+ if (cachedCraftBlockData == null) cachedCraftBlockData = org.bukkit.craftbukkit.block.data.CraftBlockData.createData(asState());
|
||||
+ return (org.bukkit.craftbukkit.block.data.CraftBlockData) cachedCraftBlockData.clone();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
// Paper start
|
||||
protected boolean shapeExceedsCube = true;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index c6a9ce2a67591205cbeb436b5043e737331c3527..3594f432a25b580173e8577bf324be954f5eddd1 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -527,7 +527,17 @@ public class CraftBlockData implements BlockData {
|
||||
return craft;
|
||||
}
|
||||
|
||||
+ // Paper start - optimize creating BlockData to not need a map lookup
|
||||
+ static {
|
||||
+ // Initialize cached data for all IBlockData instances after registration
|
||||
+ Block.BLOCK_STATE_REGISTRY.iterator().forEachRemaining(BlockState::createCraftBlockData);
|
||||
+ }
|
||||
public static CraftBlockData fromData(BlockState data) {
|
||||
+ return data.createCraftBlockData();
|
||||
+ }
|
||||
+
|
||||
+ public static CraftBlockData createData(BlockState data) {
|
||||
+ // Paper end
|
||||
return CraftBlockData.MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data);
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 26 Aug 2018 20:49:50 -0400
|
||||
Subject: [PATCH] Optimize MappedRegistry
|
||||
|
||||
Use larger initial sizes to increase bucket capacity on the BiMap
|
||||
|
||||
BiMap.get was seen to be using a good bit of CPU time.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
index 889c213205738ba637a28895977714df2d025b6d..87ea9b851531ac98a2dce66651f1730c5eb5e7d4 100644
|
||||
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
@@ -37,7 +37,7 @@ import org.apache.logging.log4j.Logger;
|
||||
public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
protected static final Logger LOGGER = LogManager.getLogger();
|
||||
private final ObjectList<T> byId = new ObjectArrayList<>(256);
|
||||
- private final Object2IntMap<T> toId = new Object2IntOpenCustomHashMap<>(Util.identityStrategy());
|
||||
+ private final it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T> toId = new it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T>(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map
|
||||
private final BiMap<ResourceLocation, T> storage;
|
||||
private final BiMap<ResourceKey<T>, T> keyStorage;
|
||||
private final Map<T, Lifecycle> lifecycles;
|
||||
@@ -48,9 +48,9 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle) {
|
||||
super(key, lifecycle);
|
||||
this.toId.defaultReturnValue(-1);
|
||||
- this.storage = HashBiMap.create();
|
||||
- this.keyStorage = HashBiMap.create();
|
||||
- this.lifecycles = Maps.newIdentityHashMap();
|
||||
+ this.storage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ this.keyStorage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ this.lifecycles = new java.util.IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
this.elementsLifecycle = lifecycle;
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 25 Aug 2018 19:56:51 -0500
|
||||
Subject: [PATCH] Add PhantomPreSpawnEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
index 7cbb16646c6c83d443deedaf425d18d6de76e314..080f6d12838faf47ead0958d6bc08f26f78c4671 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
@@ -172,6 +172,11 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
}
|
||||
|
||||
this.setPhantomSize(nbt.getInt("Size"));
|
||||
+ // Paper start
|
||||
+ if (nbt.hasUUID("Paper.SpawningEntity")) {
|
||||
+ this.spawningEntity = nbt.getUUID("Paper.SpawningEntity");
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -181,6 +186,11 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
nbt.putInt("AY", this.anchorPoint.getY());
|
||||
nbt.putInt("AZ", this.anchorPoint.getZ());
|
||||
nbt.putInt("Size", this.getPhantomSize());
|
||||
+ // Paper start
|
||||
+ if (this.spawningEntity != null) {
|
||||
+ nbt.putUUID("Paper.SpawningEntity", this.spawningEntity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,6 +242,14 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
return entitysize.scale(f);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ java.util.UUID spawningEntity;
|
||||
+
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return spawningEntity;
|
||||
+ }
|
||||
+ public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; }
|
||||
+ // Paper end
|
||||
private static enum AttackPhase {
|
||||
|
||||
CIRCLE, SWOOP;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
index ee18e2826f6390ef5a29557b733fd00db5bc409f..42effcbd3ca7c38a4e8b1aa835543ad243112a33 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
@@ -4,6 +4,7 @@ import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
+import net.minecraft.server.MCUtil;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.stats.ServerStatsCounter;
|
||||
@@ -73,8 +74,17 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
int k = 1 + random.nextInt(difficultydamagescaler.getDifficulty().getId() + 1);
|
||||
|
||||
for (int l = 0; l < k; ++l) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(MCUtil.toLocation(world, blockposition1), ((ServerPlayer) entityhuman).getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL);
|
||||
+ if (!event.callEvent()) {
|
||||
+ if (event.shouldAbortSpawn()) {
|
||||
+ break;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end
|
||||
Phantom entityphantom = (Phantom) EntityType.PHANTOM.create((Level) world);
|
||||
-
|
||||
+ entityphantom.setSpawningEntity(entityhuman.getUUID()); // Paper
|
||||
entityphantom.moveTo(blockposition1, 0.0F, 0.0F);
|
||||
groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity, (CompoundTag) null);
|
||||
world.addAllEntities(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
index f77b83bee6eb739220b55793a0807f0267cfc8a9..c9dab70b0b284fe1c1daafd3c1f5bd08b14fa35d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
@@ -34,4 +34,11 @@ public class CraftPhantom extends CraftFlying implements Phantom {
|
||||
public EntityType getType() {
|
||||
return EntityType.PHANTOM;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return getHandle().getSpawningEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 24 Aug 2018 11:50:26 -0500
|
||||
Subject: [PATCH] Add More Creeper API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
index dc7ad6f2a1ae71c411fb39460b52cd1129c928c4..bbca035b89c2334e65abc46dd76234c833ac222d 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -309,7 +309,18 @@ public class Creeper extends Monster implements PowerableMob {
|
||||
}
|
||||
|
||||
public void ignite() {
|
||||
- this.entityData.set(Creeper.DATA_IS_IGNITED, true);
|
||||
+ // Paper start
|
||||
+ setIgnited(true);
|
||||
+ }
|
||||
+
|
||||
+ public void setIgnited(boolean ignited) {
|
||||
+ if (isIgnited() != ignited) {
|
||||
+ com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited);
|
||||
+ if (event.callEvent()) {
|
||||
+ this.entityData.set(Creeper.DATA_IS_IGNITED, event.isIgnited());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public boolean canDropMobsSkull() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
index ea9dc2219cdff3976796e4848b0faa278656be63..63a8188010f045d5c17a1ecb63e8081ec86c2960 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
@@ -94,4 +94,16 @@ public class CraftCreeper extends CraftMonster implements Creeper {
|
||||
public EntityType getType() {
|
||||
return EntityType.CREEPER;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setIgnited(boolean ignited) {
|
||||
+ getHandle().setIgnited(ignited);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isIgnited() {
|
||||
+ return getHandle().isIgnited();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -3,6 +3,9 @@ From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
|||
Date: Sat, 13 Jul 2019 09:23:10 -0700
|
||||
Subject: [PATCH] Asynchronous chunk IO and loading
|
||||
|
||||
# UPDATE NOTES: RegionFileStorage and SectionStorage need resolving (will conflict on apply)
|
||||
# ChunkSerializer needs the new tick lists to be saved (see added todos)
|
||||
|
||||
This patch re-adds a file IO thread as well as shoving de-serializing
|
||||
chunk NBT data onto worker threads. This patch also will shove
|
||||
chunk data serialization onto the same worker threads when the chunk
|
||||
|
@ -2278,12 +2281,12 @@ index a5e438a834826161c52ca9db57d234d9ff80a591..b8bc1b9b8e8a33df90a963f9f9769292
|
|||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
|
||||
index 70f2a946f50ca6be2ffaef8db8c1c03a729c757b..4f45ac04a219e619c13b31befd2c4e452057079c 100644
|
||||
index 4f45ac04a219e619c13b31befd2c4e452057079c..eca61ff543244dbf05db0a30c21c5bbeea2b9144 100644
|
||||
--- a/src/main/java/net/minecraft/server/MCUtil.java
|
||||
+++ b/src/main/java/net/minecraft/server/MCUtil.java
|
||||
@@ -505,4 +505,8 @@ public final class MCUtil {
|
||||
return null;
|
||||
}
|
||||
@@ -509,4 +509,8 @@ public final class MCUtil {
|
||||
public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) {
|
||||
return net.minecraft.server.level.ChunkMap.MAX_VIEW_DISTANCE + net.minecraft.world.level.chunk.ChunkStatus.getDistance(status);
|
||||
}
|
||||
+
|
||||
+ public static int getTicketLevelFor(net.minecraft.world.level.chunk.ChunkStatus status) {
|
||||
|
@ -2291,22 +2294,22 @@ index 70f2a946f50ca6be2ffaef8db8c1c03a729c757b..4f45ac04a219e619c13b31befd2c4e45
|
|||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
|
||||
index 6f30e10d59416799edbe362951ce61733e37b256..2b8b47f121b78cc5fe166c4280a327ddcf799b77 100644
|
||||
index 4ab820c43ddc79f5a280e2d4b322a667b9ba725f..e0c1e4e38ff49429a587c59afb86e95c452d52a0 100644
|
||||
--- a/src/main/java/net/minecraft/server/Main.java
|
||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||
@@ -217,6 +217,7 @@ public class Main {
|
||||
@@ -227,6 +227,7 @@ public class Main {
|
||||
|
||||
convertable_conversionsession.a((IRegistryCustom) iregistrycustom_dimension, (SaveData) object);
|
||||
convertable_conversionsession.saveDataTag(iregistrycustom_dimension, (SaveData) object);
|
||||
*/
|
||||
+ Class.forName(net.minecraft.world.entity.npc.VillagerTrades.class.getName());// Paper - load this sync so it won't fail later async
|
||||
final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.spin((thread) -> {
|
||||
DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, datapackconfiguration1, thread, iregistrycustom_dimension, convertable_conversionsession, resourcepackrepository, datapackresources, null, dedicatedserversettings, DataFixers.getDataFixer(), minecraftsessionservice, gameprofilerepository, usercache, LoggerChunkProgressListener::new);
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index cb2ca56df7f2adedff2ebdd26957c23164b56255..7a7c501b1dffb4928aa74edd684d79f7fa312789 100644
|
||||
index 44f32023db3edaae107f48fd9b96baf5432417d9..a9f54a691af0cd15cbc38af8b8df3831de244aa7 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1001,7 +1001,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
@@ -984,7 +984,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.getProfileCache().save(false); // Paper
|
||||
}
|
||||
// Spigot end
|
||||
|
@ -2316,10 +2319,10 @@ index cb2ca56df7f2adedff2ebdd26957c23164b56255..7a7c501b1dffb4928aa74edd684d79f7
|
|||
|
||||
public String getLocalIp() {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
index 1072998cd4b00bd74e8aed9a17fbf67e31a595cd..7e3f4bb1ce723adbea8622aec8cce73faccfc664 100644
|
||||
index 303125c4d0f8f235703975eab5eccb9aa045ccf8..dbcf3e764a26c89ef10afa294e1b80575ab2113e 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
|
||||
@@ -151,6 +151,18 @@ public class ChunkHolder {
|
||||
@@ -163,6 +163,18 @@ public class ChunkHolder {
|
||||
return chunkstatus;
|
||||
}
|
||||
}
|
||||
|
@ -2338,7 +2341,7 @@ index 1072998cd4b00bd74e8aed9a17fbf67e31a595cd..7e3f4bb1ce723adbea8622aec8cce73f
|
|||
|
||||
return null;
|
||||
}
|
||||
@@ -375,7 +387,7 @@ public class ChunkHolder {
|
||||
@@ -402,7 +414,7 @@ public class ChunkHolder {
|
||||
ChunkStatus chunkstatus = ChunkHolder.getStatus(this.oldTicketLevel);
|
||||
ChunkStatus chunkstatus1 = ChunkHolder.getStatus(this.ticketLevel);
|
||||
boolean flag = this.oldTicketLevel <= ChunkMap.MAX_CHUNK_DISTANCE;
|
||||
|
@ -2348,10 +2351,10 @@ index 1072998cd4b00bd74e8aed9a17fbf67e31a595cd..7e3f4bb1ce723adbea8622aec8cce73f
|
|||
ChunkHolder.FullChunkStatus playerchunk_state1 = ChunkHolder.getFullChunkStatus(this.ticketLevel);
|
||||
// CraftBukkit start
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b44166903bb7fda 100644
|
||||
index 6af70073e1ee0290ec30392153c2c18dfeffa0e8..9aa0df8c92744e1651254f427dd8d1fc904172d5 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -447,6 +447,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -492,6 +492,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
this.queueSorter.close();
|
||||
|
@ -2359,23 +2362,17 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
this.poiManager.close();
|
||||
} finally {
|
||||
super.close();
|
||||
@@ -483,7 +484,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -528,7 +529,8 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
this.processUnloads(() -> {
|
||||
return true;
|
||||
});
|
||||
- this.flushWorker();
|
||||
+ //this.flushWorker(); // Paper - nuke IOWorker
|
||||
+ this.level.asyncChunkTaskManager.flush(); // Paper - flush to preserve behavior compat with pre-async behaviour
|
||||
+// this.i(); // Paper - nuke IOWorker
|
||||
} else {
|
||||
this.visibleChunkMap.values().stream().filter(ChunkHolder::wasAccessibleSinceLastSave).forEach((playerchunk) -> {
|
||||
ChunkAccess ichunkaccess = (ChunkAccess) playerchunk.getChunkToSave().getNow(null); // CraftBukkit - decompile error
|
||||
@@ -498,16 +500,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
}
|
||||
|
||||
- private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.96; // Spigot
|
||||
+ private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.90; // Spigot // Paper - unload more
|
||||
|
||||
@@ -546,17 +548,21 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
protected void tick(BooleanSupplier shouldKeepTicking) {
|
||||
ProfilerFiller gameprofilerfiller = this.level.getProfiler();
|
||||
|
||||
|
@ -2387,11 +2384,18 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
if (!this.level.noSave()) {
|
||||
+ try (Timing ignored = this.level.timings.chunkUnload.startTiming()) { // Paper
|
||||
this.processUnloads(shouldKeepTicking);
|
||||
+ }// Paper
|
||||
+ } // Paper
|
||||
}
|
||||
|
||||
gameprofilerfiller.pop();
|
||||
@@ -528,12 +534,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
- private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.96; // Spigot
|
||||
+ private static final double UNLOAD_QUEUE_RESIZE_FACTOR = 0.90; // Spigot // Paper - unload more
|
||||
|
||||
private void processUnloads(BooleanSupplier shouldKeepTicking) {
|
||||
LongIterator longiterator = this.toDrop.iterator();
|
||||
@@ -573,12 +579,13 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
if (playerchunk != null) {
|
||||
this.pendingUnloads.put(j, playerchunk);
|
||||
this.modified = true;
|
||||
|
@ -2402,11 +2406,11 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
}
|
||||
// Spigot end
|
||||
- this.scheduleUnload(j, playerchunk);
|
||||
+ //this.a(j, playerchunk); // Paper - move up because spigot did a dumb
|
||||
+ //this.scheduleUnload(j, playerchunk); // Paper - move up because spigot did a dumb
|
||||
}
|
||||
}
|
||||
activityAccountant.endActivity(); // Spigot
|
||||
@@ -547,6 +554,46 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -594,6 +601,46 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
}
|
||||
|
||||
|
@ -2418,7 +2422,7 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
+ ChunkPos chunkPos = chunk.getPos();
|
||||
+ CompoundTag poiData;
|
||||
+ try (Timing ignored = this.level.timings.chunkUnloadPOISerialization.startTiming()) {
|
||||
+ poiData = this.getVillagePlace().getData(chunk.getPos());
|
||||
+ poiData = this.poiManager.getData(chunk.getPos());
|
||||
+ }
|
||||
+
|
||||
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.level, chunkPos.x, chunkPos.z,
|
||||
|
@ -2453,7 +2457,7 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
private void scheduleUnload(long pos, ChunkHolder holder) {
|
||||
CompletableFuture<ChunkAccess> completablefuture = holder.getChunkToSave();
|
||||
Consumer<ChunkAccess> consumer = (ichunkaccess) -> { // CraftBukkit - decompile error
|
||||
@@ -566,7 +613,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -613,7 +660,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
((LevelChunk) ichunkaccess).setLoaded(false);
|
||||
}
|
||||
|
||||
|
@ -2467,11 +2471,11 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
+ LOGGER.fatal("Failed to prepare async save, attempting synchronous save", ex);
|
||||
+ this.save(ichunkaccess);
|
||||
+ }
|
||||
+ // Paper end - async chunk saving
|
||||
+ // Paper end - async chunk savin
|
||||
if (this.entitiesInLevel.remove(pos) && ichunkaccess instanceof LevelChunk) {
|
||||
LevelChunk chunk = (LevelChunk) ichunkaccess;
|
||||
|
||||
@@ -631,19 +687,23 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -678,20 +734,20 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> scheduleChunkLoad(ChunkPos pos) {
|
||||
|
@ -2484,30 +2488,29 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
- try (Timing ignored2 = this.level.timings.chunkIO.startTimingIfSync()) { // Paper start - timings
|
||||
- nbttagcompound = this.readChunk(pos);
|
||||
- } // Paper end
|
||||
-
|
||||
- if (nbttagcompound != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
|
||||
- boolean flag = nbttagcompound.contains("Status", 8);
|
||||
-
|
||||
- if (flag) {
|
||||
- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.poiManager, pos, nbttagcompound);
|
||||
+ // Paper start
|
||||
+ if (ioThrowable != null) {
|
||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable);
|
||||
+ }
|
||||
|
||||
- if (nbttagcompound != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
|
||||
- boolean flag = nbttagcompound.contains("Level", 10) && nbttagcompound.getCompound("Level").contains("Status", 8);
|
||||
+ this.getVillagePlace().loadInData(pos, chunkHolder.poiData);
|
||||
+ this.poiManager.loadInData(pos, chunkHolder.poiData);
|
||||
+ chunkHolder.tasks.forEach(Runnable::run);
|
||||
+ // Paper end
|
||||
|
||||
- if (flag) {
|
||||
- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.structureManager, this.poiManager, pos, nbttagcompound);
|
||||
+ if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async
|
||||
+
|
||||
+ if (true) {
|
||||
+ ProtoChunk protochunk = chunkHolder.protoChunk;
|
||||
|
||||
this.markPosition(pos, protochunk.getStatus().getChunkType());
|
||||
return Either.left(protochunk);
|
||||
@@ -666,7 +726,32 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
@@ -713,7 +769,32 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
this.markPositionReplaceable(pos);
|
||||
return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level));
|
||||
return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level, this.level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), (BlendingData) null));
|
||||
- }, this.mainThreadExecutor);
|
||||
+ // Paper start - Async chunk io
|
||||
+ };
|
||||
|
@ -2537,8 +2540,8 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
+ // Paper end
|
||||
}
|
||||
|
||||
private void markPositionReplaceable(ChunkPos chunkcoordintpair) {
|
||||
@@ -848,6 +933,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
private void markPositionReplaceable(ChunkPos pos) {
|
||||
@@ -896,6 +977,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
public boolean save(ChunkAccess chunk) {
|
||||
|
@ -2546,7 +2549,7 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
this.poiManager.flush(chunk.getPos());
|
||||
if (!chunk.isUnsaved()) {
|
||||
return false;
|
||||
@@ -859,7 +945,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -907,7 +989,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
ChunkStatus chunkstatus = chunk.getStatus();
|
||||
|
||||
if (chunkstatus.getChunkType() != ChunkStatus.ChunkType.LEVELCHUNK) {
|
||||
|
@ -2555,18 +2558,18 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
return false;
|
||||
}
|
||||
|
||||
@@ -869,9 +955,16 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -917,9 +999,15 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
this.level.getProfiler().incrementCounter("chunkSave");
|
||||
- CompoundTag nbttagcompound = ChunkSerializer.write(this.level, chunk);
|
||||
-
|
||||
- this.write(chunkcoordintpair, nbttagcompound);
|
||||
+ CompoundTag nbttagcompound;
|
||||
+ try (co.aikar.timings.Timing ignored1 = this.level.timings.chunkSaveDataSerialization.startTiming()) { // Paper
|
||||
+ nbttagcompound = ChunkSerializer.write(this.level, chunk);
|
||||
+ } // Paper
|
||||
+ } // Paper;
|
||||
+
|
||||
|
||||
- this.write(chunkcoordintpair, nbttagcompound);
|
||||
+ // Paper start - async chunk io
|
||||
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.level, chunkcoordintpair.x, chunkcoordintpair.z,
|
||||
+ null, nbttagcompound, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY);
|
||||
|
@ -2574,15 +2577,15 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
this.markPosition(chunkcoordintpair, chunkstatus.getChunkType());
|
||||
return true;
|
||||
} catch (Exception exception) {
|
||||
@@ -880,6 +973,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
@@ -928,6 +1016,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+ } // Paper
|
||||
}
|
||||
|
||||
private boolean isExistingChunkFull(ChunkPos chunkcoordintpair) {
|
||||
@@ -1007,6 +1101,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
private boolean isExistingChunkFull(ChunkPos pos) {
|
||||
@@ -1060,6 +1149,35 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2618,19 +2621,11 @@ index cec5e220bcbed01f45afc75f653b5937ffea25cc..d445990c843ad86215be238c4b441669
|
|||
@Nullable
|
||||
public CompoundTag readChunk(ChunkPos pos) throws IOException {
|
||||
CompoundTag nbttagcompound = this.read(pos);
|
||||
@@ -1360,6 +1483,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
|
||||
}
|
||||
|
||||
+ @Deprecated public PoiManager getVillagePlace() { return this.getPoiManager(); } // Paper - OBFHELPER
|
||||
protected PoiManager getPoiManager() {
|
||||
return this.poiManager;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 4956a9ea1b4545d80468521afe8c5453b53768c3..1603d406b54aefdf337827df164c227a33423f61 100644
|
||||
index 212261651fd650cc895f817ccca37699d1cade8f..463cbbbe97bd421ac343ba80cc99731ff5fb4052 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -481,10 +481,128 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -500,10 +500,128 @@ public class ServerChunkCache extends ChunkSource {
|
||||
return ret;
|
||||
}
|
||||
// Paper end
|
||||
|
@ -2759,13 +2754,13 @@ index 4956a9ea1b4545d80468521afe8c5453b53768c3..1603d406b54aefdf337827df164c227a
|
|||
if (Thread.currentThread() != this.mainThread) {
|
||||
return (ChunkAccess) CompletableFuture.supplyAsync(() -> {
|
||||
return this.getChunk(x, z, leastStatus, create);
|
||||
@@ -507,13 +625,18 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -526,13 +644,18 @@ public class ServerChunkCache extends ChunkSource {
|
||||
}
|
||||
|
||||
gameprofilerfiller.incrementCounter("getChunkCacheMiss");
|
||||
- CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create);
|
||||
+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.getChunkFutureMainThread(x, z, leastStatus, create, true); // Paper
|
||||
ServerChunkCache.MainThreadExecutor chunkproviderserver_a = this.mainThreadProcessor;
|
||||
ServerChunkCache.MainThreadExecutor chunkproviderserver_b = this.mainThreadProcessor;
|
||||
|
||||
Objects.requireNonNull(completablefuture);
|
||||
if (!completablefuture.isDone()) { // Paper
|
||||
|
@ -2774,12 +2769,12 @@ index 4956a9ea1b4545d80468521afe8c5453b53768c3..1603d406b54aefdf337827df164c227a
|
|||
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.pushChunkWait(this.level, x1, z1);
|
||||
+ // Paper end
|
||||
this.level.timings.syncChunkLoad.startTiming(); // Paper
|
||||
chunkproviderserver_a.managedBlock(completablefuture::isDone);
|
||||
chunkproviderserver_b.managedBlock(completablefuture::isDone);
|
||||
+ com.destroystokyo.paper.io.chunk.ChunkTaskManager.popChunkWait(); // Paper - async chunk debug
|
||||
this.level.timings.syncChunkLoad.stopTiming(); // Paper
|
||||
} // Paper
|
||||
ichunkaccess = (ChunkAccess) ((Either) completablefuture.join()).map((ichunkaccess1) -> {
|
||||
@@ -600,6 +723,11 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -619,6 +742,11 @@ public class ServerChunkCache extends ChunkSource {
|
||||
}
|
||||
|
||||
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> getChunkFutureMainThread(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
|
||||
|
@ -2791,7 +2786,7 @@ index 4956a9ea1b4545d80468521afe8c5453b53768c3..1603d406b54aefdf337827df164c227a
|
|||
ChunkPos chunkcoordintpair = new ChunkPos(chunkX, chunkZ);
|
||||
long k = chunkcoordintpair.toLong();
|
||||
int l = 33 + ChunkStatus.getDistance(leastStatus);
|
||||
@@ -997,11 +1125,12 @@ public class ServerChunkCache extends ChunkSource {
|
||||
@@ -1028,11 +1156,12 @@ public class ServerChunkCache extends ChunkSource {
|
||||
// CraftBukkit start - process pending Chunk loadCallback() and unloadCallback() after each run task
|
||||
public boolean pollTask() {
|
||||
try {
|
||||
|
@ -2806,10 +2801,10 @@ index 4956a9ea1b4545d80468521afe8c5453b53768c3..1603d406b54aefdf337827df164c227a
|
|||
} finally {
|
||||
chunkMap.callbackExecutor.run();
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index afdb25743ceb404b4681ee2965fe3448f1f1b06a..e4626f6edb845ce751235c4341a608de81857603 100644
|
||||
index 29b2ddee252759c7ad17df8fe19ea08a36eb2673..807b508daaab587514cf91106df648758d6e9798 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -295,6 +295,78 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
@@ -307,6 +307,78 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2888,7 +2883,7 @@ index afdb25743ceb404b4681ee2965fe3448f1f1b06a..e4626f6edb845ce751235c4341a608de
|
|||
// Paper end
|
||||
|
||||
// Add env and gen to constructor, WorldData -> WorldDataServer
|
||||
@@ -368,6 +440,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
@@ -374,6 +446,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
|
||||
this.sleepStatus = new SleepStatus();
|
||||
this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
|
@ -2910,10 +2905,10 @@ index 0d536d72ac918fbd403397ff369d10143ee9c204..be677d437d17b74c6188ce1bd5fc6fdc
|
|||
private final String name;
|
||||
private final Comparator<T> comparator;
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index cc1b855b09d4826f88b0c2b9c08fb901191a2108..1e3d7081467cccf09d4510907388479560f67f67 100644
|
||||
index c8a5cd52689b2cd81a2206f0f71623d784c379ce..7ed73ea4a5f7383c953ee3e28ce8f234d8ff941e 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -711,6 +711,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
@@ -710,6 +710,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]))); // Paper
|
||||
return;
|
||||
}
|
||||
|
@ -2928,7 +2923,7 @@ index cc1b855b09d4826f88b0c2b9c08fb901191a2108..1e3d7081467cccf09d45109073884795
|
|||
StringReader stringreader = new StringReader(packet.getCommand());
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
|
||||
index 3ca8b13744b406c3e563747f0cb69647c94103df..7b1d2748328ffc1447bcacd1316f2c6fdbaf92b0 100644
|
||||
index 2a73700b0cd31e2a88c478b884de0a7f3d018259..0a1e667487e2c7849e11c0395816dc8ce20e0113 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/village/poi/PoiManager.java
|
||||
@@ -37,9 +37,11 @@ public class PoiManager extends SectionStorage<PoiSection> {
|
||||
|
@ -2937,8 +2932,8 @@ index 3ca8b13744b406c3e563747f0cb69647c94103df..7b1d2748328ffc1447bcacd1316f2c6f
|
|||
private final LongSet loadedChunks = new LongOpenHashSet();
|
||||
+ private final net.minecraft.server.level.ServerLevel world; // Paper
|
||||
|
||||
public PoiManager(File directory, DataFixer dataFixer, boolean dsync, LevelHeightAccessor world) {
|
||||
super(directory, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, world);
|
||||
public PoiManager(Path path, DataFixer dataFixer, boolean dsync, LevelHeightAccessor world) {
|
||||
super(path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, world);
|
||||
+ this.world = (net.minecraft.server.level.ServerLevel)world; // Paper
|
||||
this.distanceTracker = new PoiManager.DistanceTracker();
|
||||
}
|
||||
|
@ -2999,33 +2994,19 @@ index 3ca8b13744b406c3e563747f0cb69647c94103df..7b1d2748328ffc1447bcacd1316f2c6f
|
|||
public static enum Occupancy {
|
||||
HAS_SPACE(PoiRecord::hasSpace),
|
||||
IS_OCCUPIED(PoiRecord::isOccupied),
|
||||
diff --git a/src/main/java/net/minecraft/world/level/TickNextTickData.java b/src/main/java/net/minecraft/world/level/TickNextTickData.java
|
||||
index 3af31dc2c82c11ee78d497c5777615c17cb13c7a..3b8c04f6ffd7e6c197465aa1caf633ba92529472 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/TickNextTickData.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/TickNextTickData.java
|
||||
@@ -4,7 +4,7 @@ import java.util.Comparator;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
||||
public class TickNextTickData<T> {
|
||||
- private static long counter;
|
||||
+ 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;
|
||||
@@ -16,7 +16,7 @@ public class TickNextTickData<T> {
|
||||
}
|
||||
|
||||
public TickNextTickData(BlockPos pos, T t, long time, TickPriority priority) {
|
||||
- this.c = (long)(counter++);
|
||||
+ this.c = (TickNextTickData.COUNTER.getAndIncrement()); // Paper - async chunk loading
|
||||
this.pos = pos.immutable();
|
||||
this.type = t;
|
||||
this.triggerTick = time;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
index 03190535999d30aea0428631ae576b18f5d10eb7..b8bdd69bda00ba0eb72c161d3b49101b8221ac41 100644
|
||||
index 2fd969d1450d1251c139f3721d146fd2e191c4dd..806e6559555a6e71ef8199d4ffc5ce86a06bb871 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||
@@ -67,7 +67,30 @@ public class ChunkSerializer {
|
||||
@@ -62,6 +62,7 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
import net.minecraft.world.level.material.Fluid;
|
||||
import net.minecraft.world.ticks.LevelChunkTicks;
|
||||
import net.minecraft.world.ticks.ProtoChunkTicks;
|
||||
+import net.minecraft.world.ticks.TickContainerAccess;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -75,7 +76,31 @@ public class ChunkSerializer {
|
||||
|
||||
public ChunkSerializer() {}
|
||||
|
||||
|
@ -3044,77 +3025,71 @@ index 03190535999d30aea0428631ae576b18f5d10eb7..b8bdd69bda00ba0eb72c161d3b49101b
|
|||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static ProtoChunk read(ServerLevel world, StructureManager structureManager, PoiManager poiStorage, ChunkPos pos, CompoundTag nbt) {
|
||||
public static ProtoChunk read(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt) {
|
||||
+ // Paper start - add variant for async calls
|
||||
+ InProgressChunkHolder holder = loadChunk(world, structureManager, poiStorage, pos, nbt, true);
|
||||
+ InProgressChunkHolder holder = loadChunk(world, poiStorage, chunkPos, nbt, true);
|
||||
+ holder.tasks.forEach(Runnable::run);
|
||||
+ return holder.protoChunk;
|
||||
+ }
|
||||
+ public static InProgressChunkHolder loadChunk(ServerLevel world, StructureManager structureManager, PoiManager poiStorage, ChunkPos pos, CompoundTag nbt, boolean distinguish) {
|
||||
+
|
||||
+ public static InProgressChunkHolder loadChunk(ServerLevel world, PoiManager poiStorage, ChunkPos chunkPos, CompoundTag nbt, boolean distinguish) {
|
||||
+ java.util.ArrayDeque<Runnable> tasksToExecuteOnMain = new java.util.ArrayDeque<>();
|
||||
+ // Paper end
|
||||
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
|
||||
BiomeSource worldchunkmanager = chunkgenerator.getBiomeSource();
|
||||
CompoundTag nbttagcompound1 = nbt.getCompound("Level");
|
||||
@@ -94,7 +117,9 @@ public class ChunkSerializer {
|
||||
ChunkPos chunkcoordintpair1 = new ChunkPos(nbt.getInt("xPos"), nbt.getInt("zPos"));
|
||||
|
||||
if (!Objects.equals(chunkPos, chunkcoordintpair1)) {
|
||||
@@ -92,7 +117,9 @@ public class ChunkSerializer {
|
||||
LevelLightEngine lightengine = chunkproviderserver.getLightEngine();
|
||||
|
||||
if (flag) {
|
||||
+ tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main
|
||||
lightengine.retainData(pos, true);
|
||||
lightengine.retainData(chunkPos, true);
|
||||
+ }); // Paper - delay this task since we're executing off-main
|
||||
}
|
||||
|
||||
for (int j = 0; j < nbttaglist.size(); ++j) {
|
||||
@@ -110,16 +135,28 @@ public class ChunkSerializer {
|
||||
achunksection[world.getSectionIndexFromSectionY(b0)] = chunksection;
|
||||
}
|
||||
|
||||
+ tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main
|
||||
poiStorage.checkConsistencyWithBlocks(pos, chunksection);
|
||||
+ }); // Paper - delay this task since we're executing off-main
|
||||
}
|
||||
Registry<Biome> iregistry = world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
|
||||
@@ -141,11 +168,21 @@ public class ChunkSerializer {
|
||||
|
||||
if (flag) {
|
||||
if (nbttagcompound2.contains("BlockLight", 7)) {
|
||||
- lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(pos, b0), new DataLayer(nbttagcompound2.getByteArray("BlockLight")), true);
|
||||
if (nbttagcompound1.contains("BlockLight", 7)) {
|
||||
- lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("BlockLight")), true);
|
||||
+ // Paper start - delay this task since we're executing off-main
|
||||
+ DataLayer blockLight = new DataLayer(nbttagcompound2.getByteArray("BlockLight"));
|
||||
+ DataLayer blockLight = new DataLayer(nbttagcompound1.getByteArray("BlockLight"));
|
||||
+ tasksToExecuteOnMain.add(() -> {
|
||||
+ lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkcoordintpair1, b0), blockLight, true);
|
||||
+ });
|
||||
+ // Paper end - delay this task since we're executing off-main
|
||||
}
|
||||
|
||||
if (flag1 && nbttagcompound2.contains("SkyLight", 7)) {
|
||||
- lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(pos, b0), new DataLayer(nbttagcompound2.getByteArray("SkyLight")), true);
|
||||
if (flag1 && nbttagcompound1.contains("SkyLight", 7)) {
|
||||
- lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("SkyLight")), true);
|
||||
+ // Paper start - delay this task since we're executing off-main
|
||||
+ DataLayer skyLight = new DataLayer(nbttagcompound2.getByteArray("SkyLight"));
|
||||
+ DataLayer skyLight = new DataLayer(nbttagcompound1.getByteArray("SkyLight"));
|
||||
+ tasksToExecuteOnMain.add(() -> {
|
||||
+ lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkcoordintpair1, b0), skyLight, true);
|
||||
+ });
|
||||
+ // Paper end - delay this task since we're executing off-main
|
||||
+ // Paper end - delay this task since we're executing off-mai
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,7 +270,7 @@ public class ChunkSerializer {
|
||||
@@ -258,7 +295,7 @@ public class ChunkSerializer {
|
||||
}
|
||||
|
||||
if (chunkstatus_type == ChunkStatus.ChunkType.LEVELCHUNK) {
|
||||
- return new ImposterProtoChunk((LevelChunk) object);
|
||||
+ return new InProgressChunkHolder(new ImposterProtoChunk((LevelChunk) object), tasksToExecuteOnMain); // Paper - Async chunk loading
|
||||
- return new ImposterProtoChunk((LevelChunk) object, false);
|
||||
+ return new InProgressChunkHolder(new ImposterProtoChunk((LevelChunk) object, false), tasksToExecuteOnMain); // Paper - Async chunk loading
|
||||
} else {
|
||||
ProtoChunk protochunk1 = (ProtoChunk) object;
|
||||
|
||||
@@ -272,11 +309,92 @@ public class ChunkSerializer {
|
||||
protochunk1.setCarvingMask(worldgenstage_features, BitSet.valueOf(nbttagcompound5.getByteArray(s1)));
|
||||
@@ -297,10 +334,89 @@ public class ChunkSerializer {
|
||||
protochunk1.setCarvingMask(worldgenstage_features, new CarvingMask(nbttagcompound4.getLongArray(s1), ((ChunkAccess) object).getMinBuildHeight()));
|
||||
}
|
||||
|
||||
- return protochunk1;
|
||||
+ return new InProgressChunkHolder(protochunk1, tasksToExecuteOnMain); // Paper - Async chunk loading
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - async chunk save for unload
|
||||
+ public static final class AsyncSaveData {
|
||||
+ public final DataLayer[] blockLight;
|
||||
|
@ -3163,8 +3138,9 @@ index 03190535999d30aea0428631ae576b18f5d10eb7..b8bdd69bda00ba0eb72c161d3b49101b
|
|||
+ skyLight[i - lightenginethreaded.getMinLightSection()] = skyArray;
|
||||
+ }
|
||||
+
|
||||
+ TickList<Block> blockTickList = chunk.getBlockTicks();
|
||||
+ TickContainerAccess<Block> blockTickList = chunk.getBlockTicks();
|
||||
+
|
||||
+ //TODO check ChunkSerializer "block_ticks"
|
||||
+ ListTag blockTickListSerialized;
|
||||
+ if (blockTickList instanceof ProtoTickList || blockTickList instanceof ChunkTickList) {
|
||||
+ blockTickListSerialized = null;
|
||||
|
@ -3172,13 +3148,14 @@ index 03190535999d30aea0428631ae576b18f5d10eb7..b8bdd69bda00ba0eb72c161d3b49101b
|
|||
+ blockTickListSerialized = world.getBlockTicks().save(chunkPos);
|
||||
+ }
|
||||
+
|
||||
+ TickList<Fluid> fluidTickList = chunk.getLiquidTicks();
|
||||
+ TickContainerAccess<Fluid> fluidTickList = chunk.getFluidTicks();
|
||||
+
|
||||
+ //TODO
|
||||
+ ListTag fluidTickListSerialized;
|
||||
+ if (fluidTickList instanceof ProtoTickList || fluidTickList instanceof ChunkTickList) {
|
||||
+ fluidTickListSerialized = null;
|
||||
+ } else {
|
||||
+ fluidTickListSerialized = world.getLiquidTicks().save(chunkPos);
|
||||
+ fluidTickListSerialized = world.getFluidTicks().save(chunkPos);
|
||||
+ }
|
||||
+
|
||||
+ ListTag blockEntitiesSerialized = new ListTag();
|
||||
|
@ -3187,9 +3164,15 @@ index 03190535999d30aea0428631ae576b18f5d10eb7..b8bdd69bda00ba0eb72c161d3b49101b
|
|||
+ if (blockEntityNbt != null) {
|
||||
+ blockEntitiesSerialized.add(blockEntityNbt);
|
||||
+ }
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ return new AsyncSaveData(blockLight, skyLight, blockTickListSerialized, fluidTickListSerialized, blockEntitiesSerialized, world.getGameTime());
|
||||
+ }
|
||||
+
|
||||
private static void logErrors(ChunkPos chunkPos, int y, String message) {
|
||||
ChunkSerializer.LOGGER.error("Recoverable errors when loading section [" + chunkPos.x + ", " + y + ", " + chunkPos.z + "]: " + message);
|
||||
}
|
||||
@@ -310,6 +426,10 @@ public class ChunkSerializer {
|
||||
}
|
||||
|
||||
public static CompoundTag write(ServerLevel world, ChunkAccess chunk) {
|
||||
|
@ -3199,23 +3182,21 @@ index 03190535999d30aea0428631ae576b18f5d10eb7..b8bdd69bda00ba0eb72c161d3b49101b
|
|||
+ // Paper end
|
||||
ChunkPos chunkcoordintpair = chunk.getPos();
|
||||
CompoundTag nbttagcompound = new CompoundTag();
|
||||
CompoundTag nbttagcompound1 = new CompoundTag();
|
||||
@@ -285,7 +403,7 @@ public class ChunkSerializer {
|
||||
nbttagcompound.put("Level", nbttagcompound1);
|
||||
nbttagcompound1.putInt("xPos", chunkcoordintpair.x);
|
||||
nbttagcompound1.putInt("zPos", chunkcoordintpair.z);
|
||||
- nbttagcompound1.putLong("LastUpdate", world.getGameTime());
|
||||
+ nbttagcompound1.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : world.getGameTime()); // Paper - async chunk unloading
|
||||
nbttagcompound1.putLong("InhabitedTime", chunk.getInhabitedTime());
|
||||
nbttagcompound1.putString("Status", chunk.getStatus().getName());
|
||||
UpgradeData chunkconverter = chunk.getUpgradeData();
|
||||
@@ -304,9 +422,17 @@ public class ChunkSerializer {
|
||||
LevelChunkSection chunksection = (LevelChunkSection) Arrays.stream(achunksection).filter((chunksection1) -> {
|
||||
return chunksection1 != null && SectionPos.blockToSectionCoord(chunksection1.bottomBlockY()) == finalI; // CraftBukkit - decompile errors
|
||||
}).findFirst().orElse(LevelChunk.EMPTY_SECTION);
|
||||
|
||||
@@ -318,6 +438,7 @@ public class ChunkSerializer {
|
||||
nbttagcompound.putInt("yPos", chunk.getMinSection());
|
||||
nbttagcompound.putInt("zPos", chunkcoordintpair.z);
|
||||
nbttagcompound.putLong("LastUpdate", world.getGameTime());
|
||||
+ nbttagcompound.putLong("LastUpdate", asyncsavedata != null ? asyncsavedata.worldTime : world.getGameTime()); // Paper - async chunk unloading
|
||||
nbttagcompound.putLong("InhabitedTime", chunk.getInhabitedTime());
|
||||
nbttagcompound.putString("Status", chunk.getStatus().getName());
|
||||
BlendingData blendingdata = chunk.getBlendingData();
|
||||
@@ -360,8 +481,17 @@ public class ChunkSerializer {
|
||||
for (int i = lightenginethreaded.getMinLightSection(); i < lightenginethreaded.getMaxLightSection(); ++i) {
|
||||
int j = chunk.getSectionIndexFromSectionY(i);
|
||||
boolean flag1 = j >= 0 && j < achunksection.length;
|
||||
- DataLayer nibblearray = lightenginethreaded.getLayerListener(LightLayer.BLOCK).getDataLayerData(SectionPos.of(chunkcoordintpair, i));
|
||||
- DataLayer nibblearray1 = lightenginethreaded.getLayerListener(LightLayer.SKY).getDataLayerData(SectionPos.of(chunkcoordintpair, i));
|
||||
-
|
||||
+ // Paper start - async chunk save for unload
|
||||
+ DataLayer nibblearray; // block light
|
||||
+ DataLayer nibblearray1; // sky light
|
||||
|
@ -3227,11 +3208,11 @@ index 03190535999d30aea0428631ae576b18f5d10eb7..b8bdd69bda00ba0eb72c161d3b49101b
|
|||
+ nibblearray1 = asyncsavedata.skyLight[i - lightenginethreaded.getMinLightSection()];
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (chunksection != LevelChunk.EMPTY_SECTION || nibblearray != null || nibblearray1 != null) {
|
||||
CompoundTag nbttagcompound2 = new CompoundTag();
|
||||
|
||||
@@ -338,8 +464,17 @@ public class ChunkSerializer {
|
||||
nbttagcompound1.putIntArray("Biomes", biomestorage.writeBiomes());
|
||||
if (flag1 || nibblearray != null || nibblearray1 != null) {
|
||||
CompoundTag nbttagcompound1 = new CompoundTag();
|
||||
@@ -399,8 +529,17 @@ public class ChunkSerializer {
|
||||
nbttagcompound.putBoolean("isLightOn", true);
|
||||
}
|
||||
|
||||
- ListTag nbttaglist1 = new ListTag();
|
||||
|
@ -3248,38 +3229,24 @@ index 03190535999d30aea0428631ae576b18f5d10eb7..b8bdd69bda00ba0eb72c161d3b49101b
|
|||
+ }
|
||||
+ // Paper end
|
||||
|
||||
CompoundTag nbttagcompound3;
|
||||
CompoundTag nbttagcompound2;
|
||||
|
||||
@@ -382,6 +517,10 @@ public class ChunkSerializer {
|
||||
nbttagcompound1.put("ToBeTicked", ((ProtoTickList) ticklist).save());
|
||||
} else if (ticklist instanceof ChunkTickList) {
|
||||
nbttagcompound1.put("TileTicks", ((ChunkTickList) ticklist).save());
|
||||
+ // Paper start - async chunk save for unload
|
||||
+ } else if (asyncsavedata != null) {
|
||||
+ nbttagcompound1.put("TileTicks", asyncsavedata.blockTickList);
|
||||
+ // Paper end
|
||||
} else {
|
||||
nbttagcompound1.put("TileTicks", world.getBlockTicks().save(chunkcoordintpair));
|
||||
}
|
||||
@@ -392,6 +531,10 @@ public class ChunkSerializer {
|
||||
nbttagcompound1.put("LiquidsToBeTicked", ((ProtoTickList) ticklist1).save());
|
||||
} else if (ticklist1 instanceof ChunkTickList) {
|
||||
nbttagcompound1.put("LiquidTicks", ((ChunkTickList) ticklist1).save());
|
||||
+ // Paper start - async chunk save for unload
|
||||
+ } else if (asyncsavedata != null) {
|
||||
+ nbttagcompound1.put("LiquidTicks", asyncsavedata.fluidTickList);
|
||||
+ // Paper end
|
||||
} else {
|
||||
nbttagcompound1.put("LiquidTicks", world.getLiquidTicks().save(chunkcoordintpair));
|
||||
}
|
||||
@@ -463,6 +602,7 @@ public class ChunkSerializer {
|
||||
private static void saveTicks(ServerLevel world, CompoundTag nbt, ChunkAccess.TicksToSave tickSchedulers) {
|
||||
long i = world.getLevelData().getGameTime();
|
||||
|
||||
+ //TODO original patch line 3259
|
||||
nbt.put("block_ticks", tickSchedulers.blocks().save(i, (block) -> {
|
||||
return Registry.BLOCK.getKey(block).toString();
|
||||
}));
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||
index 8121470cdd94bde4d84f70882f3bdb3dc067cf15..6f13c7adce7d4b3d170045ea5ef2a841d34ae7b0 100644
|
||||
index 0259baec1ceb911f39e733d52d232dec19577550..9fe3ab209ebbfc40dc1bf046d474296c660e38d5 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||
@@ -21,27 +21,38 @@ import net.minecraft.world.level.storage.DimensionDataStorage;
|
||||
|
||||
@@ -25,27 +25,38 @@ import net.minecraft.world.level.storage.DimensionDataStorage;
|
||||
public class ChunkStorage implements AutoCloseable {
|
||||
|
||||
public static final int LAST_MONOLYTH_STRUCTURE_DATA_VERSION = 1493;
|
||||
- private final IOWorker worker;
|
||||
+ // Paper - nuke IO worker
|
||||
protected final DataFixer fixerUpper;
|
||||
|
@ -3291,7 +3258,7 @@ index 8121470cdd94bde4d84f70882f3bdb3dc067cf15..6f13c7adce7d4b3d170045ea5ef2a841
|
|||
+ public final RegionFileStorage regionFileCache;
|
||||
+ // Paper end - async chunk loading
|
||||
|
||||
public ChunkStorage(File directory, DataFixer dataFixer, boolean dsync) {
|
||||
public ChunkStorage(Path directory, DataFixer dataFixer, boolean dsync) {
|
||||
this.fixerUpper = dataFixer;
|
||||
- this.worker = new IOWorker(directory, dsync, "chunk");
|
||||
+ // Paper start - async chunk io
|
||||
|
@ -3321,7 +3288,7 @@ index 8121470cdd94bde4d84f70882f3bdb3dc067cf15..6f13c7adce7d4b3d170045ea5ef2a841
|
|||
if (nbt != null) {
|
||||
CompoundTag level = nbt.getCompound("Level");
|
||||
if (level.getBoolean("TerrainPopulated")) {
|
||||
@@ -77,11 +88,13 @@ public class ChunkStorage implements AutoCloseable {
|
||||
@@ -80,11 +91,13 @@ public class ChunkStorage implements AutoCloseable {
|
||||
if (i < 1493) {
|
||||
nbttagcompound = NbtUtils.update(this.fixerUpper, DataFixTypes.CHUNK, nbttagcompound, i, 1493);
|
||||
if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
|
||||
|
@ -3335,7 +3302,7 @@ index 8121470cdd94bde4d84f70882f3bdb3dc067cf15..6f13c7adce7d4b3d170045ea5ef2a841
|
|||
}
|
||||
}
|
||||
|
||||
@@ -99,22 +112,26 @@ public class ChunkStorage implements AutoCloseable {
|
||||
@@ -114,23 +127,27 @@ public class ChunkStorage implements AutoCloseable {
|
||||
|
||||
@Nullable
|
||||
public CompoundTag read(ChunkPos chunkPos) throws IOException {
|
||||
|
@ -3366,20 +3333,21 @@ index 8121470cdd94bde4d84f70882f3bdb3dc067cf15..6f13c7adce7d4b3d170045ea5ef2a841
|
|||
- this.worker.close();
|
||||
+ this.regionFileCache.close(); // Paper - nuke IO worker
|
||||
}
|
||||
}
|
||||
|
||||
public ChunkScanAccess chunkScanner() {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
index 84327c8fe1dc62c7b99950261a344042b4456616..298b5abbc792dd33be38acbd1c572c9778c4d2d2 100644
|
||||
index 7b69007609ed421ee72ddc3d6f2a7b64888babf1..6f7bcf74b0ff42841e37f36561d6c54e1ee8c989 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||
@@ -47,6 +47,7 @@ public class RegionFile implements AutoCloseable {
|
||||
@@ -44,6 +44,7 @@ public class RegionFile implements AutoCloseable {
|
||||
private final IntBuffer timestamps;
|
||||
@VisibleForTesting
|
||||
protected final RegionBitmap usedSectors;
|
||||
+ public final java.util.concurrent.locks.ReentrantLock fileLock = new java.util.concurrent.locks.ReentrantLock(true); // Paper
|
||||
|
||||
public RegionFile(File file, File directory, boolean dsync) throws IOException {
|
||||
this(file.toPath(), directory.toPath(), RegionFileVersion.VERSION_DEFLATE, dsync);
|
||||
@@ -231,7 +232,7 @@ public class RegionFile implements AutoCloseable {
|
||||
public RegionFile(Path path, Path path1, boolean dsync) throws IOException {
|
||||
this(path, path1, RegionFileVersion.VERSION_DEFLATE, dsync);
|
||||
@@ -228,7 +229,7 @@ public class RegionFile implements AutoCloseable {
|
||||
return (byteCount + 4096 - 1) / 4096;
|
||||
}
|
||||
|
||||
|
@ -3388,7 +3356,7 @@ index 84327c8fe1dc62c7b99950261a344042b4456616..298b5abbc792dd33be38acbd1c572c97
|
|||
int i = this.getOffset(pos);
|
||||
|
||||
if (i == 0) {
|
||||
@@ -398,6 +399,11 @@ public class RegionFile implements AutoCloseable {
|
||||
@@ -395,6 +396,11 @@ public class RegionFile implements AutoCloseable {
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
|
@ -3400,7 +3368,7 @@ index 84327c8fe1dc62c7b99950261a344042b4456616..298b5abbc792dd33be38acbd1c572c97
|
|||
try {
|
||||
this.padToFullSector();
|
||||
} finally {
|
||||
@@ -407,6 +413,10 @@ public class RegionFile implements AutoCloseable {
|
||||
@@ -404,6 +410,10 @@ public class RegionFile implements AutoCloseable {
|
||||
this.file.close();
|
||||
}
|
||||
}
|
||||
|
@ -3410,7 +3378,7 @@ index 84327c8fe1dc62c7b99950261a344042b4456616..298b5abbc792dd33be38acbd1c572c97
|
|||
+ } // Paper end
|
||||
|
||||
}
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
index 3d07235ad34d219c7c5fccd216a3a6935ced645c..ebb1a050beab9530942c4498335f084c89faef06 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
|
||||
|
@ -3418,7 +3386,7 @@ index 3d07235ad34d219c7c5fccd216a3a6935ced645c..ebb1a050beab9530942c4498335f084c
|
|||
@@ -28,11 +28,32 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
this.sync = dsync;
|
||||
}
|
||||
|
||||
|
||||
- public RegionFile getFile(ChunkPos chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit
|
||||
+ // Paper start
|
||||
+ public synchronized RegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) {
|
||||
|
@ -3438,7 +3406,7 @@ index 3d07235ad34d219c7c5fccd216a3a6935ced645c..ebb1a050beab9530942c4498335f084c
|
|||
+ // Paper end
|
||||
long i = ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ());
|
||||
RegionFile regionfile = (RegionFile) this.regionCache.getAndMoveToFirst(i);
|
||||
|
||||
|
||||
if (regionfile != null) {
|
||||
+ // Paper start
|
||||
+ if (lock) {
|
||||
|
@ -3451,7 +3419,7 @@ index 3d07235ad34d219c7c5fccd216a3a6935ced645c..ebb1a050beab9530942c4498335f084c
|
|||
if (this.regionCache.size() >= com.destroystokyo.paper.PaperConfig.regionFileCacheSize) { // Paper - configurable
|
||||
@@ -50,6 +71,12 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
RegionFile regionfile1 = new RegionFile(file1, this.folder, this.sync);
|
||||
|
||||
|
||||
this.regionCache.putAndMoveToFirst(i, regionfile1);
|
||||
+ // Paper start
|
||||
+ if (lock) {
|
||||
|
@ -3474,23 +3442,23 @@ index 3d07235ad34d219c7c5fccd216a3a6935ced645c..ebb1a050beab9530942c4498335f084c
|
|||
// CraftBukkit end
|
||||
+ try { // Paper
|
||||
DataInputStream datainputstream = regionfile.getChunkDataInputStream(pos);
|
||||
|
||||
|
||||
CompoundTag nbttagcompound;
|
||||
@@ -98,10 +126,14 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
}
|
||||
|
||||
|
||||
return nbttagcompound;
|
||||
+ } finally { // Paper start
|
||||
+ regionfile.fileLock.unlock();
|
||||
+ } // Paper end
|
||||
}
|
||||
|
||||
|
||||
protected void write(ChunkPos pos, @Nullable CompoundTag nbt) throws IOException {
|
||||
- RegionFile regionfile = this.getFile(pos, false); // CraftBukkit
|
||||
+ RegionFile regionfile = this.getFile(pos, false, true); // CraftBukkit // Paper
|
||||
+ try { // Paper
|
||||
int attempts = 0; Exception laste = null; while (attempts++ < 5) { try { // Paper
|
||||
|
||||
|
||||
if (nbt == null) {
|
||||
@@ -140,9 +172,12 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
MinecraftServer.LOGGER.error("Failed to save chunk", laste);
|
||||
|
@ -3500,20 +3468,20 @@ index 3d07235ad34d219c7c5fccd216a3a6935ced645c..ebb1a050beab9530942c4498335f084c
|
|||
+ regionfile.fileLock.unlock();
|
||||
+ } // Paper end
|
||||
}
|
||||
|
||||
|
||||
- public void close() throws IOException {
|
||||
+ public synchronized void close() throws IOException { // Paper -> synchronized
|
||||
ExceptionCollector<IOException> exceptionsuppressor = new ExceptionCollector<>();
|
||||
ObjectIterator objectiterator = this.regionCache.values().iterator();
|
||||
|
||||
|
||||
@@ -159,7 +194,7 @@ public class RegionFileStorage implements AutoCloseable {
|
||||
exceptionsuppressor.throwIfPresent();
|
||||
}
|
||||
|
||||
|
||||
- public void flush() throws IOException {
|
||||
+ public synchronized void flush() throws IOException { // Paper - synchronize
|
||||
ObjectIterator objectiterator = this.regionCache.values().iterator();
|
||||
|
||||
|
||||
while (objectiterator.hasNext()) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SectionStorage.java
|
||||
index e5e138fb23d03eb63e547e74d3e14ec9d96d8107..90f7b06bd2c558be35c4577044fa033e1fb5cc22 100644
|
||||
|
@ -3522,7 +3490,7 @@ index e5e138fb23d03eb63e547e74d3e14ec9d96d8107..90f7b06bd2c558be35c4577044fa033e
|
|||
@@ -30,10 +30,10 @@ import net.minecraft.world.level.LevelHeightAccessor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
||||
-public class SectionStorage<R> implements AutoCloseable {
|
||||
+public class SectionStorage<R> extends RegionFileStorage implements AutoCloseable { // Paper - nuke IOWorker
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
@ -3534,7 +3502,7 @@ index e5e138fb23d03eb63e547e74d3e14ec9d96d8107..90f7b06bd2c558be35c4577044fa033e
|
|||
private final Function<Runnable, Codec<R>> codec;
|
||||
@@ -43,12 +43,13 @@ public class SectionStorage<R> implements AutoCloseable {
|
||||
protected final LevelHeightAccessor levelHeightAccessor;
|
||||
|
||||
|
||||
public SectionStorage(File directory, Function<Runnable, Codec<R>> codecFactory, Function<Runnable, R> factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, LevelHeightAccessor world) {
|
||||
+ super(directory, dsync); // Paper - nuke IOWorker
|
||||
this.codec = codecFactory;
|
||||
|
@ -3545,11 +3513,11 @@ index e5e138fb23d03eb63e547e74d3e14ec9d96d8107..90f7b06bd2c558be35c4577044fa033e
|
|||
- this.worker = new IOWorker(directory, dsync, directory.getName());
|
||||
+ // Paper - remove mojang I/O thread
|
||||
}
|
||||
|
||||
|
||||
protected void tick(BooleanSupplier shouldKeepTicking) {
|
||||
@@ -106,13 +107,18 @@ public class SectionStorage<R> implements AutoCloseable {
|
||||
}
|
||||
|
||||
|
||||
private void readColumn(ChunkPos chunkPos) {
|
||||
- this.readColumn(chunkPos, NbtOps.INSTANCE, this.tryRead(chunkPos));
|
||||
+ // Paper start - expose function to load in data
|
||||
|
@ -3559,7 +3527,7 @@ index e5e138fb23d03eb63e547e74d3e14ec9d96d8107..90f7b06bd2c558be35c4577044fa033e
|
|||
+ this.readColumn(chunkPos, NbtOps.INSTANCE, compound);
|
||||
+ // Paper end - expose function to load in data
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private CompoundTag tryRead(ChunkPos pos) {
|
||||
try {
|
||||
|
@ -3577,9 +3545,9 @@ index e5e138fb23d03eb63e547e74d3e14ec9d96d8107..90f7b06bd2c558be35c4577044fa033e
|
|||
} else {
|
||||
LOGGER.error("Expected compound tag, got {}", (Object)tag);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
+ // Paper start - internal get data function, copied from above
|
||||
+ private CompoundTag getDataInternal(ChunkPos chunkcoordintpair) {
|
||||
+ Dynamic<Tag> dynamic = this.writeColumn(chunkcoordintpair, NbtOps.INSTANCE);
|
||||
|
@ -3595,9 +3563,9 @@ index e5e138fb23d03eb63e547e74d3e14ec9d96d8107..90f7b06bd2c558be35c4577044fa033e
|
|||
+ // Paper end
|
||||
private <T> Dynamic<T> writeColumn(ChunkPos chunkPos, DynamicOps<T> dynamicOps) {
|
||||
Map<T, T> map = Maps.newHashMap();
|
||||
|
||||
|
||||
@@ -219,6 +238,23 @@ public class SectionStorage<R> implements AutoCloseable {
|
||||
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
- this.worker.close();
|
||||
|
@ -3622,7 +3590,7 @@ index e5e138fb23d03eb63e547e74d3e14ec9d96d8107..90f7b06bd2c558be35c4577044fa033e
|
|||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index bccc66266739954ca5d7208d233884f5270e0064..034c2886b4e29be40fa2e5e213a7457d803c0f55 100644
|
||||
index d1ffbacdabc500bfbe3f65eed6206e499775f97a..7f4024dbc1a0c50af9344689561de54eb35e1c98 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -1811,6 +1811,34 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
|
@ -1,58 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <zach.brown@destroystokyo.com>
|
||||
Date: Tue, 28 Aug 2018 23:04:15 -0400
|
||||
Subject: [PATCH] Inventory#removeItemAnySlot
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
index d76d70e7031a643f697a8ec13471450de2bca705..6ca8e76d1569f3f631275fea187e7110f09fc69e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
@@ -223,10 +223,16 @@ public class CraftInventory implements Inventory {
|
||||
}
|
||||
|
||||
private int first(ItemStack item, boolean withAmount) {
|
||||
+ // Paper start
|
||||
+ return first(item, withAmount, getStorageContents());
|
||||
+ }
|
||||
+
|
||||
+ private int first(ItemStack item, boolean withAmount, ItemStack[] inventory) {
|
||||
+ // Paper end
|
||||
if (item == null) {
|
||||
return -1;
|
||||
}
|
||||
- ItemStack[] inventory = this.getStorageContents();
|
||||
+ // ItemStack[] inventory = this.getStorageContents(); // Paper - let param deal
|
||||
for (int i = 0; i < inventory.length; i++) {
|
||||
if (inventory[i] == null) continue;
|
||||
|
||||
@@ -349,6 +355,17 @@ public class CraftInventory implements Inventory {
|
||||
|
||||
@Override
|
||||
public HashMap<Integer, ItemStack> removeItem(ItemStack... items) {
|
||||
+ // Paper start
|
||||
+ return removeItem(false, items);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public HashMap<Integer, ItemStack> removeItemAnySlot(ItemStack... items) {
|
||||
+ return removeItem(true, items);
|
||||
+ }
|
||||
+
|
||||
+ private HashMap<Integer, ItemStack> removeItem(boolean searchEntire, ItemStack... items) {
|
||||
+ // Paper end
|
||||
Validate.notNull(items, "Items cannot be null");
|
||||
HashMap<Integer, ItemStack> leftover = new HashMap<Integer, ItemStack>();
|
||||
|
||||
@@ -359,7 +376,10 @@ public class CraftInventory implements Inventory {
|
||||
int toDelete = item.getAmount();
|
||||
|
||||
while (true) {
|
||||
- int first = this.first(item, false);
|
||||
+ // Paper start - Allow searching entire contents
|
||||
+ ItemStack[] toSearch = searchEntire ? getContents() : getStorageContents();
|
||||
+ int first = this.first(item, false, toSearch);
|
||||
+ // Paper end
|
||||
|
||||
// Drat! we don't have this type in the inventory
|
||||
if (first == -1) {
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 2 Sep 2018 19:34:33 -0700
|
||||
Subject: [PATCH] Make CraftWorld#loadChunk(int, int, false) load unconverted
|
||||
chunks
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 375c3adac2dc80f15d06e8acb11c8c451ec579e5..bccc66266739954ca5d7208d233884f5270e0064 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -369,7 +369,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@Override
|
||||
public boolean loadChunk(int x, int z, boolean generate) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
|
||||
- ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
|
||||
+ ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
|
||||
|
||||
// If generate = false, but the chunk already exists, we will get this back.
|
||||
if (chunk instanceof ImposterProtoChunk) {
|
Loading…
Add table
Add a link
Reference in a new issue