More more more more more more more work
Dieser Commit ist enthalten in:
Ursprung
105034367d
Commit
cc171b1928
@ -48,7 +48,7 @@ index 36ed248f0716f2cc465c08ab851b7d83d4c7c0a7..58728a0f0722b378efa129e26f0c822b
|
||||
* @return A new location where X/Y/Z are the center of the block
|
||||
*/
|
||||
diff --git a/src/main/java/org/bukkit/World.java b/src/main/java/org/bukkit/World.java
|
||||
index 33558b6acc861f8b9986122c7c553f9dde22a45d..c1bdd642e870660931c3367884dcd7aa9d3e6923 100644
|
||||
index d3d0e4448135f6c0440c15e0dd3fc15c2616263a..7ed2442031cdcc429aabe91d639871566359ba53 100644
|
||||
--- a/src/main/java/org/bukkit/World.java
|
||||
+++ b/src/main/java/org/bukkit/World.java
|
||||
@@ -90,6 +90,38 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
||||
@ -91,7 +91,7 @@ index 33558b6acc861f8b9986122c7c553f9dde22a45d..c1bdd642e870660931c3367884dcd7aa
|
||||
* Gets the highest non-empty (impassable) coordinate at the given
|
||||
* coordinates.
|
||||
diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java
|
||||
index 3ca05a6e86a5329cf452041eac476e3636eec34a..18ab5cca036522df2d245f755d6c67904e6398e8 100644
|
||||
index 62ab55729e69bfac8eb4b40d877b945d95df27cd..79c0fa47a0d733d1547f8926d88169939c986d8c 100644
|
||||
--- a/src/main/java/org/bukkit/block/Block.java
|
||||
+++ b/src/main/java/org/bukkit/block/Block.java
|
||||
@@ -155,6 +155,72 @@ public interface Block extends Metadatable {
|
@ -6,19 +6,14 @@ Subject: [PATCH] Configurable sprint interruption on attack
|
||||
If the sprint interruption is disabled players continue sprinting when they attack entities.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 9d7d9c800710fff5cf41c973463b9c2d72a3e32a..4e0f61179e3b2ae91811746d32b24998173a922c 100644
|
||||
index 9d7d9c800710fff5cf41c973463b9c2d72a3e32a..0ad0c84fd2e32d0c51f9aae777b80922a8f11a5a 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -388,4 +388,14 @@ public class PaperWorldConfig {
|
||||
@@ -388,4 +388,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);
|
||||
+ }
|
||||
+
|
||||
+ public boolean disableSprintInterruptionOnAttack;
|
||||
+ private void disableSprintInterruptionOnAttack() {
|
||||
+ disableSprintInterruptionOnAttack = getBoolean("game-mechanics.disable-sprint-interruption-on-attack", false);
|
||||
|
@ -12,10 +12,10 @@ This disables that by not saving the thrower when the chunk is unloaded.
|
||||
This is mainly useful for survival servers that do not allow freeform teleporting.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 4e0f61179e3b2ae91811746d32b24998173a922c..a0937dd52e4a2aa1bfadcbd1ac0dc2cb26d59cf0 100644
|
||||
index 0ad0c84fd2e32d0c51f9aae777b80922a8f11a5a..760a7e667c8023cfa313d0566a6ed3b8cb2f929b 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -398,4 +398,10 @@ public class PaperWorldConfig {
|
||||
@@ -393,4 +393,10 @@ public class PaperWorldConfig {
|
||||
private void disableSprintInterruptionOnAttack() {
|
||||
disableSprintInterruptionOnAttack = getBoolean("game-mechanics.disable-sprint-interruption-on-attack", false);
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ Subject: [PATCH] Make shield blocking delay configurable
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index a0937dd52e4a2aa1bfadcbd1ac0dc2cb26d59cf0..4dce401da0e0fdf985ecb90f37b92e16cf210d25 100644
|
||||
index 760a7e667c8023cfa313d0566a6ed3b8cb2f929b..4fe89087fb7f5132ea7e4fec5fbc2885644f369e 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -404,4 +404,9 @@ public class PaperWorldConfig {
|
||||
@@ -399,4 +399,9 @@ public class PaperWorldConfig {
|
||||
disableEnderpearlExploit = getBoolean("game-mechanics.disable-unloaded-chunk-enderpearl-exploit", disableEnderpearlExploit);
|
||||
log("Disable Unloaded Chunk Enderpearl Exploit: " + (disableEnderpearlExploit ? "enabled" : "disabled"));
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ Subject: [PATCH] Add config to disable ender dragon legacy check
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 4dce401da0e0fdf985ecb90f37b92e16cf210d25..35c6978eaf25ed505f99e42a58d388c62fde8319 100644
|
||||
index 4fe89087fb7f5132ea7e4fec5fbc2885644f369e..3a9f0d5937b9d9abd4e4941c1a3f35f202b0d84a 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -409,4 +409,9 @@ public class PaperWorldConfig {
|
||||
@@ -404,4 +404,9 @@ public class PaperWorldConfig {
|
||||
private void shieldBlockingDelay() {
|
||||
shieldBlockingDelay = getInt("game-mechanics.shield-blocking-delay", 5);
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ Subject: [PATCH] Option to prevent armor stands from doing entity lookups
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 35c6978eaf25ed505f99e42a58d388c62fde8319..0fd29d5854d9d6155ea590f86d4492d86afab433 100644
|
||||
index 3a9f0d5937b9d9abd4e4941c1a3f35f202b0d84a..ba3dd73edd6a577633bce0cdcc27e1b698377ff0 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -414,4 +414,9 @@ public class PaperWorldConfig {
|
||||
@@ -409,4 +409,9 @@ public class PaperWorldConfig {
|
||||
private void scanForLegacyEnderDragon() {
|
||||
scanForLegacyEnderDragon = getBoolean("game-mechanics.scan-for-legacy-ender-dragon", true);
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ Subject: [PATCH] Allow disabling armour stand ticking
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 0fd29d5854d9d6155ea590f86d4492d86afab433..ff6cf94dec708c6d3cac837ca03be2fe12d5e05f 100644
|
||||
index ba3dd73edd6a577633bce0cdcc27e1b698377ff0..c79b175fe28077be8a8ca28772fc8cd6f5e418b1 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -419,4 +419,10 @@ public class PaperWorldConfig {
|
||||
@@ -414,4 +414,10 @@ public class PaperWorldConfig {
|
||||
private void armorStandEntityLookups() {
|
||||
armorStandEntityLookups = getBoolean("armor-stands-do-collision-entity-lookups", true);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ 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
|
||||
index 5f23b9ab6540530acac623d2cd8e9ec5d0064f39..d38049bed6f3dc3198e687686ef4d8938c7a6b59 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 {
|
@ -6,10 +6,10 @@ Subject: [PATCH] Restore vanlla default mob-spawn-range and water animals
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
index c45332fa7b374e7775ca24a7065af3cb5c85d7cf..45be7d1821497f13ab0da3c4bbff7585238e902e 100644
|
||||
index 6879ceb1c1c6b276f6686333b9b61a8a00690302..ee8c84770b9b7fb9f3763e378f399da58f042b06 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
@@ -165,7 +165,7 @@ public class SpigotWorldConfig
|
||||
@@ -178,7 +178,7 @@ public class SpigotWorldConfig
|
||||
public byte mobSpawnRange;
|
||||
private void mobSpawnRange()
|
||||
{
|
@ -5,7 +5,7 @@ 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
|
||||
index 11aefbf65b0e63777d6ed5bfdb18c7f7df30fc0e..6ec81054bcf25d99aec567d568c361eea84ed384 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;
|
||||
@ -50,7 +50,7 @@ index 239f3a17ab8cff4e6c97044e4f8e6755abac193d..82747a12d4977ed2d26d203f690ecc9b
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -481,7 +493,15 @@ public class Slime extends Mob implements Enemy {
|
||||
@@ -486,7 +498,15 @@ public class Slime extends Mob implements Enemy {
|
||||
public boolean canUse() {
|
||||
LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
@ -67,7 +67,7 @@ index 239f3a17ab8cff4e6c97044e4f8e6755abac193d..82747a12d4977ed2d26d203f690ecc9b
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -494,7 +514,15 @@ public class Slime extends Mob implements Enemy {
|
||||
@@ -499,7 +519,15 @@ public class Slime extends Mob implements Enemy {
|
||||
public boolean canContinueToUse() {
|
||||
LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
@ -84,8 +84,8 @@ index 239f3a17ab8cff4e6c97044e4f8e6755abac193d..82747a12d4977ed2d26d203f690ecc9b
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -502,6 +530,13 @@ public class Slime extends Mob implements Enemy {
|
||||
this.slime.lookAt((Entity) this.slime.getTarget(), 10.0F, 10.0F);
|
||||
@@ -517,6 +545,13 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setDirection(this.slime.getYRot(), this.slime.isDealsDamage());
|
||||
}
|
||||
+
|
||||
@ -98,7 +98,7 @@ index 239f3a17ab8cff4e6c97044e4f8e6755abac193d..82747a12d4977ed2d26d203f690ecc9b
|
||||
}
|
||||
|
||||
private static class SlimeRandomDirectionGoal extends Goal {
|
||||
@@ -517,14 +552,18 @@ public class Slime extends Mob implements Enemy {
|
||||
@@ -532,7 +567,7 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
@ -107,19 +107,19 @@ index 239f3a17ab8cff4e6c97044e4f8e6755abac193d..82747a12d4977ed2d26d203f690ecc9b
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
@@ -540,6 +575,11 @@ public class Slime extends Mob implements Enemy {
|
||||
if (--this.nextRandomizeTime <= 0) {
|
||||
this.nextRandomizeTime = 40 + this.slime.getRandom().nextInt(60);
|
||||
- this.chosenDegrees = (float) this.slime.getRandom().nextInt(360);
|
||||
this.nextRandomizeTime = this.adjustedTickDelay(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));
|
||||
+ SlimeChangeDirectionEvent event = new SlimeChangeDirectionEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), this.chosenDegrees);
|
||||
+ 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 {
|
||||
@@ -557,7 +597,7 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
@ -128,7 +128,7 @@ index 239f3a17ab8cff4e6c97044e4f8e6755abac193d..82747a12d4977ed2d26d203f690ecc9b
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -550,4 +589,15 @@ public class Slime extends Mob implements Enemy {
|
||||
@@ -565,4 +605,15 @@ public class Slime extends Mob implements Enemy {
|
||||
((Slime.SlimeMoveControl) this.slime.getMoveControl()).setWantedMovement(1.0D);
|
||||
}
|
||||
}
|
@ -5,10 +5,10 @@ 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
|
||||
index c79b175fe28077be8a8ca28772fc8cd6f5e418b1..7c538eba5d7e0112aae4c1584172233a3217ae89 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 {
|
||||
@@ -420,4 +420,10 @@ public class PaperWorldConfig {
|
||||
this.armorStandTick = this.getBoolean("armor-stands-tick", this.armorStandTick);
|
||||
log("ArmorStand ticking is " + (this.armorStandTick ? "enabled" : "disabled") + " by default");
|
||||
}
|
||||
@ -20,23 +20,23 @@ index ff6cf94dec708c6d3cac837ca03be2fe12d5e05f..29703f57969b80e25ff9a4971e640f34
|
||||
+ }
|
||||
}
|
||||
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
|
||||
index c3d3c06e06a85ce926a2be69ec9d9b8a3eb9b8e2..11ebadaa2438281a54cffe025a49ee5046a71ba5 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;
|
||||
@@ -24,6 +24,7 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||
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 {
|
||||
@@ -107,11 +108,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
|
||||
- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world));
|
||||
+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
@ -60,12 +60,12 @@ index db4bcb600ab43439ef65d4510fb20d770ce9dba3..087601ffdeea97ec4cbb9959607bdcbc
|
||||
@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 {
|
||||
@@ -124,7 +141,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
|
||||
- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world));
|
||||
+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
@ -7,10 +7,10 @@ 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
|
||||
index 7d06d476d8e12bdb395488e85e34231daccbd853..987a4180a1eb902c512c2e6a36d692cbdd9b1563 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 {
|
||||
@@ -636,6 +636,14 @@ public abstract class BlockBehaviour {
|
||||
this.hasPostProcess = blockbase_info.hasPostProcess;
|
||||
this.emissiveRendering = blockbase_info.emissiveRendering;
|
||||
}
|
39
patches/server/0252-Optimize-MappedRegistry.patch
Normale Datei
39
patches/server/0252-Optimize-MappedRegistry.patch
Normale Datei
@ -0,0 +1,39 @@
|
||||
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 3b9eb0d19623a8a8e60f785edfd2faadba54ce84..9fd8c67f6b389350a82b341ff0a5d55f5c5c228c 100644
|
||||
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
@@ -38,12 +38,10 @@ 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 = (Object2IntMap) Util.make(new Object2IntOpenCustomHashMap(Util.identityStrategy()), (object2intopencustomhashmap) -> {
|
||||
- object2intopencustomhashmap.defaultReturnValue(-1);
|
||||
- });
|
||||
- private final BiMap<ResourceLocation, T> storage = HashBiMap.create();
|
||||
- private final BiMap<ResourceKey<T>, T> keyStorage = HashBiMap.create();
|
||||
- private final Map<T, Lifecycle> lifecycles = Maps.newIdentityHashMap();
|
||||
+ 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 = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ private final BiMap<ResourceKey<T>, T> keyStorage = HashBiMap.create(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ private final Map<T, Lifecycle> lifecycles = new java.util.IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
private Lifecycle elementsLifecycle;
|
||||
@Nullable
|
||||
protected Object[] randomCache;
|
||||
@@ -51,7 +49,7 @@ public class MappedRegistry<T> extends WritableRegistry<T> {
|
||||
|
||||
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle) {
|
||||
super(key, lifecycle);
|
||||
- this.elementsLifecycle = lifecycle;
|
||||
+ this.toId.defaultReturnValue(-1); // Paper
|
||||
}
|
||||
|
||||
public static <T> MapCodec<MappedRegistry.RegistryEntry<T>> withNameAndId(ResourceKey<? extends Registry<T>> key, MapCodec<T> entryCodec) {
|
@ -5,10 +5,10 @@ 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
|
||||
index c57803ba5daa33df42374aab75a7120e1a1b7c5b..451be9232eaa513ed66ff0d2b93c932317ad6729 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 {
|
||||
@@ -171,6 +171,11 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
}
|
||||
|
||||
this.setPhantomSize(nbt.getInt("Size"));
|
||||
@ -20,7 +20,7 @@ index 7cbb16646c6c83d443deedaf425d18d6de76e314..080f6d12838faf47ead0958d6bc08f26
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -181,6 +186,11 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
@@ -180,6 +185,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());
|
||||
@ -32,7 +32,7 @@ index 7cbb16646c6c83d443deedaf425d18d6de76e314..080f6d12838faf47ead0958d6bc08f26
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,6 +242,14 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
@@ -231,6 +241,14 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
return entitysize.scale(f);
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ index 7cbb16646c6c83d443deedaf425d18d6de76e314..080f6d12838faf47ead0958d6bc08f26
|
||||
|
||||
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
|
||||
index 9ac3047019ab32992530786b8ea7457a97d2299b..891c12b8cfcdc7a2915955bdd08e50b5b9465e02 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;
|
||||
@ -59,7 +59,7 @@ index ee18e2826f6390ef5a29557b733fd00db5bc409f..42effcbd3ca7c38a4e8b1aa835543ad2
|
||||
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 {
|
||||
@@ -71,8 +72,17 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
int k = 1 + random.nextInt(difficultydamagescaler.getDifficulty().getId() + 1);
|
||||
|
||||
for (int l = 0; l < k; ++l) {
|
||||
@ -72,12 +72,12 @@ index ee18e2826f6390ef5a29557b733fd00db5bc409f..42effcbd3ca7c38a4e8b1aa835543ad2
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end
|
||||
Phantom entityphantom = (Phantom) EntityType.PHANTOM.create((Level) world);
|
||||
Phantom entityphantom = (Phantom) EntityType.PHANTOM.create(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
|
||||
world.addFreshEntityWithPassengers(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
|
@ -5,7 +5,7 @@ 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
|
||||
index bf7ddca34c8d9834a5b923fab30a605afa5f337a..c2dbe53f504327f153efe195c74ad28c1b89791f 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 {
|
@ -6,7 +6,7 @@ Subject: [PATCH] Make CraftWorld#loadChunk(int, int, false) load unconverted
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 375c3adac2dc80f15d06e8acb11c8c451ec579e5..bccc66266739954ca5d7208d233884f5270e0064 100644
|
||||
index d72bfc263798797ca83e529c26bd2a1733c65eb4..d1ffbacdabc500bfbe3f65eed6206e499775f97a 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 {
|
@ -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;
|
||||
}
|
||||
|
@ -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 {
|
In neuem Issue referenzieren
Einen Benutzer sperren