mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 15:00:13 +01:00
even even even even more work
This commit is contained in:
parent
e943ece469
commit
ec7bd6a7c6
52 changed files with 1064 additions and 1106 deletions
|
@ -4,3 +4,5 @@
|
|||
* Mini: "Optimize World Server Map": Figure out how to fill PaperWorldMap, it needs a dim key which doesnt exist anymore?
|
||||
* Mini: "MC-50319": fix if still works
|
||||
* Mini: I definetly dropped a patch I didnt want to drop, we need to go thru in the end and see if all patches are still in, lol
|
||||
* Make sure the flat bedrock setting doesn't do anything stupid
|
||||
* Check DataBits foreach
|
|
@ -24,7 +24,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
net.minecraft.server.Block block = iblockdata.getBlock();
|
||||
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
|
||||
// Modelled off EntityHuman#hasBlock
|
||||
if (block != Blocks.AIR && (item == null || iblockdata.getMaterial().isAlwaysDestroyable() || nmsItem.canDestroySpecialBlock(iblockdata))) {
|
||||
if (block != Blocks.AIR && (item == null || !iblockdata.isAlwaysDestroyable() || nmsItem.canDestroySpecialBlock(iblockdata))) {
|
||||
net.minecraft.server.Block.dropItems(iblockdata, world.getMinecraftWorld(), position, world.getTileEntity(position), null, nmsItem);
|
||||
+ if (triggerEffect) world.triggerEffect(org.bukkit.Effect.STEP_SOUND.getId(), position, net.minecraft.server.Block.getCombinedId(block.getBlockData())); // Paper
|
||||
result = true;
|
||||
|
|
|
@ -24,7 +24,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityIronGolem.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityIronGolem.java
|
||||
@@ -0,0 +0,0 @@ public class EntityIronGolem extends EntityGolem {
|
||||
@@ -0,0 +0,0 @@ public class EntityIronGolem extends EntityGolem implements IEntityAngerable {
|
||||
BlockPosition blockposition1 = blockposition.down();
|
||||
IBlockData iblockdata = iworldreader.getType(blockposition1);
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@ diff --git a/src/main/java/net/minecraft/server/MobSpawnerPatrol.java b/src/main
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MobSpawnerPatrol.java
|
||||
+++ b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java
|
||||
@@ -0,0 +0,0 @@ public class MobSpawnerPatrol {
|
||||
public MobSpawnerPatrol() {}
|
||||
@@ -0,0 +0,0 @@ public class MobSpawnerPatrol implements MobSpawner {
|
||||
|
||||
@Override
|
||||
public int a(WorldServer worldserver, boolean flag, boolean flag1) {
|
||||
+ if (worldserver.paperConfig.disablePillagerPatrols) return 0; // Paper
|
||||
if (!flag) {
|
||||
|
|
|
@ -23,14 +23,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/BlockPortal.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockPortal.java
|
||||
@@ -0,0 +0,0 @@ public class BlockPortal extends Block {
|
||||
Entity entity = EntityTypes.ZOMBIE_PIGMAN.spawnCreature(worldserver, (NBTTagCompound) null, (IChatBaseComponent) null, (EntityHuman) null, blockposition.up(), EnumMobSpawn.STRUCTURE, false, false, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL);
|
||||
|
||||
if (entity != null) {
|
||||
entity.portalCooldown = entity.getDefaultPortalCooldown();
|
||||
+ entity.fromNetherPortal = true; // Paper
|
||||
+ if (worldserver.paperConfig.nerfNetherPortalPigmen) ((EntityInsentient) entity).aware = false; // Paper
|
||||
entity.portalCooldown = entity.ba();
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/Entity.java
|
||||
|
|
|
@ -1039,6 +1039,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
+import com.destroystokyo.paper.antixray.ChunkPacketInfo; // Paper - Anti-Xray - Add chunk packet info
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -1065,8 +1066,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.nonEmptyBlockCount = short0;
|
||||
this.tickingBlockCount = short1;
|
||||
this.e = short2;
|
||||
- this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData());
|
||||
+ this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData(), world == null ? null : world.chunkPacketBlockController.getPredefinedBlockData(world, chunk, this, initializeBlocks), initializeBlocks); // Paper - Anti-Xray - Add predefined block data
|
||||
- this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData());
|
||||
+ this.blockIds = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData(), world == null ? null : world.chunkPacketBlockController.getPredefinedBlockData(world, chunk, this, initializeBlocks), initializeBlocks); // Paper - Anti-Xray - Add predefined block data
|
||||
}
|
||||
|
||||
public final IBlockData getType(int i, int j, int k) { // Paper
|
||||
|
@ -1092,10 +1093,10 @@ diff --git a/src/main/java/net/minecraft/server/DataPaletteBlock.java b/src/main
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
||||
+++ b/src/main/java/net/minecraft/server/DataPaletteBlock.java
|
||||
@@ -0,0 +0,0 @@ package net.minecraft.server;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap;
|
||||
@@ -0,0 +0,0 @@
|
||||
package net.minecraft.server;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2IntMap.Entry;
|
||||
+import com.destroystokyo.paper.antixray.ChunkPacketInfo; // Paper - Anti-Xray - Add chunk packet info
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
@ -1195,9 +1196,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
public synchronized void a(NBTTagList nbttaglist, long[] along) { // Paper - synchronize
|
||||
this.a();
|
||||
- int i = Math.max(4, MathHelper.d(nbttaglist.size()));
|
||||
- int i = Math.max(4, MathHelper.e(nbttaglist.size()));
|
||||
+ // Paper - Anti-Xray - TODO: Should this.predefinedObjects.length just be added here (faster) or should the contents be compared to calculate the size (less RAM)?
|
||||
+ int i = Math.max(4, MathHelper.d(nbttaglist.size() + (this.predefinedObjects == null ? 0 : this.predefinedObjects.length))); // Paper - Anti-Xray - Calculate the size with predefined objects
|
||||
+ int i = Math.max(4, MathHelper.e(nbttaglist.size() + (this.predefinedObjects == null ? 0 : this.predefinedObjects.length))); // Paper - Anti-Xray - Calculate the size with predefined objects
|
||||
|
||||
- if (i != this.i) {
|
||||
+ if (true || i != this.i) { // Paper - Anti-Xray - Not initialized yet
|
||||
|
@ -1221,13 +1222,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
|
||||
private byte[] f; private byte[] getData() { return this.f; } // Paper - OBFHELPER
|
||||
private List<NBTTagCompound> g;
|
||||
private boolean h;
|
||||
+ private volatile boolean ready; // Paper - Async-Anti-Xray - Ready flag for the network manager
|
||||
private boolean i;
|
||||
|
||||
- public PacketPlayOutMapChunk() {}
|
||||
+ // Paper start - Async-Anti-Xray - Set the ready flag to true
|
||||
+ private volatile boolean ready; // Paper - Async-Anti-Xray - Ready flag for the network manager
|
||||
+ public PacketPlayOutMapChunk() {
|
||||
+ this.ready = true;
|
||||
+ }
|
||||
|
@ -1238,7 +1238,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public class PacketPlayOutMapChunk implements Packet<PacketListenerPlayOut> {
|
||||
}
|
||||
// Paper end
|
||||
public PacketPlayOutMapChunk(Chunk chunk, int i) {
|
||||
public PacketPlayOutMapChunk(Chunk chunk, int i, boolean flag) {
|
||||
+ ChunkPacketInfo<IBlockData> chunkPacketInfo = chunk.world.chunkPacketBlockController.getChunkPacketInfo(this, chunk, i); // Paper - Anti-Xray - Add chunk packet info
|
||||
ChunkCoordIntPair chunkcoordintpair = chunk.getPos();
|
||||
|
||||
|
@ -1247,12 +1247,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
this.f = new byte[this.a(chunk, i)];
|
||||
- this.c = this.a(new PacketDataSerializer(this.j()), chunk, i);
|
||||
- this.c = this.a(new PacketDataSerializer(this.k()), chunk, i);
|
||||
+ // Paper start - Anti-Xray - Add chunk packet info
|
||||
+ if (chunkPacketInfo != null) {
|
||||
+ chunkPacketInfo.setData(this.getData());
|
||||
+ }
|
||||
+ this.c = this.writeChunk(new PacketDataSerializer(this.j()), chunk, i, chunkPacketInfo);
|
||||
+ this.c = this.writeChunk(new PacketDataSerializer(this.k()), chunk, i, chunkPacketInfo);
|
||||
+ // Paper end
|
||||
this.g = Lists.newArrayList();
|
||||
iterator = chunk.getTileEntities().entrySet().iterator();
|
||||
|
@ -1306,9 +1306,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
PlayerChunkMap.LOGGER.error("Couldn't load chunk {}", chunkcoordintpair, exception);
|
||||
}
|
||||
|
||||
this.g(chunkcoordintpair);
|
||||
- return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a));
|
||||
+ return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.world)); // Paper - Anti-Xray - Add parameter
|
||||
}, this.executor);
|
||||
|
@ -1403,17 +1403,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public final co.aikar.timings.WorldTimingsHandler timings; // Paper
|
||||
public static BlockPosition lastPhysicsProblem; // Spigot
|
||||
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
return ((ChunkProviderServer) this.chunkProvider).getChunkAt(x, z, false);
|
||||
return (CraftServer) Bukkit.getServer();
|
||||
}
|
||||
|
||||
- protected World(WorldData worlddata, DimensionManager dimensionmanager, BiFunction<World, WorldProvider, IChunkProvider> bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) {
|
||||
+ protected World(WorldData worlddata, DimensionManager dimensionmanager, java.util.concurrent.Executor executor, BiFunction<World, WorldProvider, IChunkProvider> bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { // Paper - executor
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot
|
||||
this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig(worlddata.getName(), this.spigotConfig); // Paper
|
||||
- protected World(WorldDataMutable worlddatamutable, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, Supplier<GameProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) {
|
||||
+ protected World(WorldDataMutable worlddatamutable, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, Supplier<GameProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) {
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot
|
||||
this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig((((WorldDataServer)worlddatamutable).getName()), this.spigotConfig); // Paper
|
||||
+ this.chunkPacketBlockController = this.paperConfig.antiXray ? new ChunkPacketBlockControllerAntiXray(this.paperConfig, executor) : ChunkPacketBlockController.NO_OPERATION_INSTANCE; // Paper - Anti-Xray
|
||||
this.generator = gen;
|
||||
if (dimensionmanager.world == null) dimensionmanager.world = (WorldServer) this; // Paper
|
||||
this.world = new CraftWorld((WorldServer) this, gen, env);
|
||||
this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit
|
||||
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
// CraftBukkit end
|
||||
|
||||
|
@ -1426,15 +1426,15 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
|
||||
// Add env and gen to constructor
|
||||
public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
- super(worlddata, dimensionmanager, (world, worldprovider) -> {
|
||||
+ super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down
|
||||
// CraftBukkit start
|
||||
ChunkGenerator<?> chunkGenerator;
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
|
||||
// Add env and gen to constructor, WorldData -> WorldDataServer
|
||||
public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
- super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env);
|
||||
+ super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor
|
||||
this.pvpMode = minecraftserver.getPVP();
|
||||
convertable = convertable_conversionsession;
|
||||
uuid = WorldUUID.getUUID(convertable_conversionsession.folder.toFile());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
|
@ -1452,8 +1452,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
NBTTagCompound data = new NBTTagCompound();
|
||||
cs[i].getBlocks().a(data, "Palette", "BlockStates");
|
||||
|
||||
- DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData()); // TODO: snapshot whole ChunkSection
|
||||
+ DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::d, GameProfileSerializer::a, Blocks.AIR.getBlockData(), null, false); // TODO: snapshot whole ChunkSection // Paper - Anti-Xray - Add no predefined block data and don't initialize because it's done in the line below internally
|
||||
- DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData()); // TODO: snapshot whole ChunkSection
|
||||
+ DataPaletteBlock blockids = new DataPaletteBlock<>(ChunkSection.GLOBAL_PALETTE, net.minecraft.server.Block.REGISTRY_ID, GameProfileSerializer::c, GameProfileSerializer::a, Blocks.AIR.getBlockData(), null, false); // TODO: snapshot whole ChunkSection // Paper - Anti-Xray - Add no predefined block data and don't initialize because it's done in the line below internally
|
||||
blockids.a(data.getList("Palette", CraftMagicNumbers.NBT.TAG_COMPOUND), data.getLongArray("BlockStates"));
|
||||
|
||||
sectionBlockIDs[i] = blockids;
|
||||
|
|
|
@ -2534,7 +2534,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ public static InProgressChunkHolder loadChunk(WorldServer worldserver, DefinedStructureManager definedstructuremanager, VillagePlace villageplace, ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound, boolean distinguish) {
|
||||
+ ArrayDeque<Runnable> tasksToExecuteOnMain = new ArrayDeque<>();
|
||||
+ // Paper end
|
||||
ChunkGenerator<?> chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
|
||||
ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
|
||||
WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
|
||||
NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level");
|
||||
@@ -0,0 +0,0 @@ public class ChunkRegionLoader {
|
||||
|
@ -2560,25 +2560,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
if (flag) {
|
||||
if (nbttagcompound2.hasKeyOfType("BlockLight", 7)) {
|
||||
- lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("BlockLight")));
|
||||
- lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("BlockLight")), true);
|
||||
+ // Paper start - delay this task since we're executing off-main
|
||||
+ NibbleArray blockLight = new NibbleArray(nbttagcompound2.getByteArray("BlockLight"));
|
||||
+ // Note: We move the block light nibble array creation here for perf & in case the compound is modified
|
||||
+ tasksToExecuteOnMain.add(() -> {
|
||||
+ lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), blockLight);
|
||||
+ lightengine.a(EnumSkyBlock.BLOCK, SectionPosition.a(chunkcoordintpair, b0), blockLight, true);
|
||||
+ });
|
||||
+ // Paper end
|
||||
+ // Paper end - delay this task since we're executing off-main
|
||||
}
|
||||
|
||||
if (flag2 && nbttagcompound2.hasKeyOfType("SkyLight", 7)) {
|
||||
- lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("SkyLight")));
|
||||
- lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), new NibbleArray(nbttagcompound2.getByteArray("SkyLight")), true);
|
||||
+ // Paper start - delay this task since we're executing off-main
|
||||
+ NibbleArray skyLight = new NibbleArray(nbttagcompound2.getByteArray("SkyLight"));
|
||||
+ // Note: We move the block light nibble array creation here for perf & in case the compound is modified
|
||||
+ tasksToExecuteOnMain.add(() -> {
|
||||
+ lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), skyLight);
|
||||
+ lightengine.a(EnumSkyBlock.SKY, SectionPosition.a(chunkcoordintpair, b0), skyLight, true);
|
||||
+ });
|
||||
+ // Paper end
|
||||
+ // Paper end - delay this task since we're executing off-main
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2597,9 +2595,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
- 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 NibbleArray[] blockLight; // null or size of 17 (for indices -1 through 15)
|
||||
|
@ -2617,9 +2615,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ this.blockTickList = blockTickList;
|
||||
+ this.fluidTickList = fluidTickList;
|
||||
+ this.worldTime = worldTime;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
}
|
||||
}
|
||||
|
||||
+ // must be called sync
|
||||
+ public static AsyncSaveData getAsyncSaveData(WorldServer world, IChunkAccess chunk) {
|
||||
+ org.spigotmc.AsyncCatcher.catchOp("preparation of chunk data for async save");
|
||||
|
@ -2731,8 +2729,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if (ticklist instanceof ProtoChunkTickList) {
|
||||
nbttagcompound1.set("ToBeTicked", ((ProtoChunkTickList) ticklist).b());
|
||||
} else if (ticklist instanceof TickListChunk) {
|
||||
- nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).a(worldserver.getTime()));
|
||||
+ nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).a(asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime())); // Paper - async chunk unloading
|
||||
nbttagcompound1.set("TileTicks", ((TickListChunk) ticklist).b());
|
||||
+ // Paper start - async chunk save for unload
|
||||
+ } else if (asyncsavedata != null) {
|
||||
+ nbttagcompound1.set("TileTicks", asyncsavedata.blockTickList);
|
||||
|
@ -2748,15 +2745,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if (ticklist1 instanceof ProtoChunkTickList) {
|
||||
nbttagcompound1.set("LiquidsToBeTicked", ((ProtoChunkTickList) ticklist1).b());
|
||||
} else if (ticklist1 instanceof TickListChunk) {
|
||||
- nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).a(worldserver.getTime()));
|
||||
+ nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).a(asyncsavedata != null ? asyncsavedata.worldTime : worldserver.getTime())); // Paper - async chunk unloading
|
||||
nbttagcompound1.set("LiquidTicks", ((TickListChunk) ticklist1).b());
|
||||
+ // Paper start - async chunk save for unload
|
||||
+ } else if (asyncsavedata != null) {
|
||||
+ nbttagcompound1.set("LiquidTicks", asyncsavedata.fluidTickList);
|
||||
+ // Paper end
|
||||
} else {
|
||||
- nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair));
|
||||
+ nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair)); // Paper - diff on method change (see getAsyncSaveData)
|
||||
+ nbttagcompound1.set("LiquidTicks", worldserver.getFluidTickList().a(chunkcoordintpair)); // Paper - diff on method change (see getAsyncSaveData)
|
||||
}
|
||||
|
||||
nbttagcompound1.set("PostProcessing", a(ichunkaccess.l()));
|
||||
|
@ -2824,23 +2820,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
import java.util.function.Supplier;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
-public class IChunkLoader implements AutoCloseable {
|
||||
+public class IChunkLoader extends RegionFileCache implements AutoCloseable {
|
||||
public class IChunkLoader implements AutoCloseable {
|
||||
|
||||
- private final IOWorker a; public IOWorker getIOWorker() { return a; } // Paper - OBFHELPER
|
||||
+// private final IOWorker a; public IOWorker getIOWorker() { return a; } // Paper - OBFHELPER - nuke IOWorker
|
||||
+ // Paper - OBFHELPER - nuke IOWorker
|
||||
protected final DataFixer b;
|
||||
@Nullable
|
||||
- private PersistentStructureLegacy c;
|
||||
+ private volatile PersistentStructureLegacy c; // Paper - async chunk loading
|
||||
+
|
||||
+ private final Object persistentDataLock = new Object(); // Paper
|
||||
+ protected final RegionFileCache regionFileCache;
|
||||
|
||||
public IChunkLoader(File file, DataFixer datafixer) {
|
||||
+ super(file);
|
||||
public IChunkLoader(File file, DataFixer datafixer, boolean flag) {
|
||||
+ this.regionFileCache = new RegionFileCache(file, flag); // Paper - nuke IOWorker
|
||||
this.b = datafixer;
|
||||
- this.a = new IOWorker(new RegionFileCache(file), "chunk");
|
||||
+// this.a = new IOWorker(new RegionFileCache(file), "chunk"); // Paper - nuke IOWorker
|
||||
- this.a = new IOWorker(file, flag, "chunk");
|
||||
+ // Paper - nuke IOWorker
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
|
@ -2881,7 +2877,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
|
||||
+ synchronized (this.persistentDataLock) { // Paper - Async chunk loading
|
||||
if (this.c == null) {
|
||||
this.c = PersistentStructureLegacy.a(dimensionmanager.getType(), (WorldPersistentData) supplier.get()); // CraftBukkit - getType
|
||||
this.c = PersistentStructureLegacy.a(resourcekey, (WorldPersistentData) supplier.get());
|
||||
}
|
||||
|
||||
nbttagcompound = this.c.a(nbttagcompound);
|
||||
|
@ -2890,49 +2886,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class IChunkLoader implements AutoCloseable {
|
||||
return nbttagcompound.hasKeyOfType("DataVersion", 99) ? nbttagcompound.getInt("DataVersion") : -1;
|
||||
|
||||
@Nullable
|
||||
public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException {
|
||||
- return this.a.a(chunkcoordintpair);
|
||||
+ return this.regionFileCache.read(chunkcoordintpair);
|
||||
}
|
||||
|
||||
- @Nullable
|
||||
- public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException {
|
||||
- return this.a.a(chunkcoordintpair);
|
||||
- }
|
||||
-
|
||||
- public void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) {
|
||||
- this.a.a(chunkcoordintpair, nbttagcompound);
|
||||
+// Paper start - nuke IOWorker
|
||||
+// @Nullable
|
||||
+// public NBTTagCompound read(ChunkCoordIntPair chunkcoordintpair) throws IOException {
|
||||
+// return this.a.a(chunkcoordintpair);
|
||||
+// }
|
||||
+//
|
||||
+ public void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { write(chunkcoordintpair, nbttagcompound); } // Paper OBFHELPER
|
||||
+ public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { // Paper - OBFHELPER - (Switched around for safety)
|
||||
+ super.write(chunkcoordintpair, nbttagcompound);
|
||||
+ this.regionFileCache.write(chunkcoordintpair, nbttagcompound);
|
||||
if (this.c != null) {
|
||||
- this.c.a(chunkcoordintpair.pair());
|
||||
+ synchronized (this.persistentDataLock) { // Paper - Async chunk loading
|
||||
+ this.c.a(chunkcoordintpair.pair()); } // Paper - Async chunk loading}
|
||||
this.c.a(chunkcoordintpair.pair());
|
||||
+ } // Paper - Async chunk loading}
|
||||
}
|
||||
|
||||
}
|
||||
-
|
||||
- }
|
||||
-
|
||||
- public void i() {
|
||||
- this.a.a().join();
|
||||
- }
|
||||
-
|
||||
- public void close() throws IOException {
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
- this.a.close();
|
||||
- }
|
||||
+//
|
||||
+// public void i() {
|
||||
+// this.a.a().join();
|
||||
+// }
|
||||
+//
|
||||
+// public void close() throws IOException {
|
||||
+// this.a.close();
|
||||
+// }
|
||||
+// Paper end
|
||||
+ this.regionFileCache.close();
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
@ -2948,6 +2929,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return 33 + ChunkStatus.getTicketLevelOffset(status);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/Main.java
|
||||
+++ b/src/main/java/net/minecraft/server/Main.java
|
||||
@@ -0,0 +0,0 @@ public class Main {
|
||||
|
||||
convertable_conversionsession.a((IRegistryCustom) iregistrycustom_dimension, (SaveData) object);
|
||||
*/
|
||||
+ Class.forName("net.minecraft.server.VillagerTrades");// Paper - load this sync so it won't fail later async
|
||||
final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.a((thread) -> {
|
||||
DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, datapackconfiguration1, thread, iregistrycustom_dimension, convertable_conversionsession, resourcepackrepository, datapackresources, null, dedicatedserversettings, DataConverterRegistry.a(), minecraftsessionservice, gameprofilerepository, usercache, WorldLoadListenerLogger::new);
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
|
@ -2956,18 +2949,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.getUserCache().c(false); // Paper
|
||||
}
|
||||
// Spigot end
|
||||
-
|
||||
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.close(true, true); // Paper
|
||||
}
|
||||
|
||||
public String getServerIp() {
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
dedicatedserver.setEraseCache(true);
|
||||
}
|
||||
|
||||
+ Class.forName("net.minecraft.server.VillagerTrades");// Paper - load this sync so it won't fail later async
|
||||
dedicatedserver.serverThread.setPriority(Thread.NORM_PRIORITY+2); // Paper - boost priority
|
||||
dedicatedserver.serverThread.start();
|
||||
// CraftBukkit end
|
||||
diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/NextTickListEntry.java
|
||||
|
@ -3067,7 +3053,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
private final LightEngineThreaded lightEngine;
|
||||
private final IAsyncTaskHandler<Runnable> executor;
|
||||
public final ChunkGenerator<?> chunkGenerator;
|
||||
public final ChunkGenerator chunkGenerator;
|
||||
- private final Supplier<WorldPersistentData> l;
|
||||
+ private final Supplier<WorldPersistentData> l; public final Supplier<WorldPersistentData> getWorldPersistentDataSupplier() { return this.l; } // Paper - OBFHELPER
|
||||
private final VillagePlace m;
|
||||
|
@ -3083,11 +3069,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private final PlayerMap playerMap;
|
||||
public final Int2ObjectMap<PlayerChunkMap.EntityTracker> trackedEntities;
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getWorldProvider().f(), threadedmailbox1, this.p.a(threadedmailbox1, false));
|
||||
this.lightEngine = new LightEngineThreaded(ilightaccess, this, this.world.getDimensionManager().hasSkyLight(), threadedmailbox1, this.p.a(threadedmailbox1, false));
|
||||
this.chunkDistanceManager = new PlayerChunkMap.a(executor, iasynctaskhandler);
|
||||
this.l = supplier;
|
||||
- this.m = new VillagePlace(new File(this.w, "poi"), datafixer);
|
||||
+ this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper
|
||||
- this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag);
|
||||
+ this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper
|
||||
this.setViewDistance(i);
|
||||
}
|
||||
|
||||
|
@ -3240,15 +3226,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.lightEngine.queueUpdate();
|
||||
this.worldLoadListener.a(ichunkaccess.getPos(), (ChunkStatus) null);
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Async chunk io
|
||||
+ public NBTTagCompound completeChunkData(NBTTagCompound compound, ChunkCoordIntPair chunkcoordintpair) throws IOException {
|
||||
+ return compound == null ? null : this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.getWorldPersistentDataSupplier(), compound, chunkcoordintpair, this.world);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
private CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> f(ChunkCoordIntPair chunkcoordintpair) {
|
||||
- return CompletableFuture.supplyAsync(() -> {
|
||||
+ // Paper start - Async chunk io
|
||||
|
@ -3259,38 +3238,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- try (Timing ignored2 = this.world.timings.chunkIO.startTimingIfSync()) { // Paper start - timings
|
||||
- nbttagcompound = this.readChunkData(chunkcoordintpair);
|
||||
- } // Paper end
|
||||
-
|
||||
+ // Paper start
|
||||
+ if (ioThrowable != null) {
|
||||
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
- if (nbttagcompound != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
|
||||
- boolean flag = nbttagcompound.hasKeyOfType("Level", 10) && nbttagcompound.getCompound("Level").hasKeyOfType("Status", 8);
|
||||
+ if (ioThrowable != null) {
|
||||
+ com.destroystokyo.paper.io.IOUtil.rethrow(ioThrowable);
|
||||
+ }
|
||||
+ if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.world.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async
|
||||
|
||||
- if (flag) {
|
||||
- ProtoChunk protochunk = ChunkRegionLoader.loadChunk(this.world, this.definedStructureManager, this.m, chunkcoordintpair, nbttagcompound);
|
||||
+ this.getVillagePlace().loadInData(chunkcoordintpair, chunkHolder.poiData);
|
||||
+ chunkHolder.tasks.forEach(Runnable::run);
|
||||
+ // Paper - async load completes this
|
||||
+ // Paper end
|
||||
|
||||
- protochunk.setLastSaved(this.world.getTime());
|
||||
- return Either.left(protochunk);
|
||||
- }
|
||||
-
|
||||
- PlayerChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", chunkcoordintpair);
|
||||
- }} // Paper
|
||||
+ // Paper start - This is done async
|
||||
+ if (chunkHolder.protoChunk != null) {
|
||||
+ chunkHolder.protoChunk.setLastSaved(this.world.getTime());
|
||||
+ return Either.left(chunkHolder.protoChunk);
|
||||
+ }
|
||||
+ // Paper end
|
||||
} catch (ReportedException reportedexception) {
|
||||
Throwable throwable = reportedexception.getCause();
|
||||
+ if (true) {
|
||||
+ ProtoChunk protochunk = chunkHolder.protoChunk;
|
||||
|
||||
protochunk.setLastSaved(this.world.getTime());
|
||||
this.a(chunkcoordintpair, protochunk.getChunkStatus().getType());
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
}
|
||||
|
||||
this.g(chunkcoordintpair);
|
||||
return Either.left(new ProtoChunk(chunkcoordintpair, ChunkConverter.a, this.world)); // Paper - Anti-Xray - Add parameter
|
||||
- }, this.executor);
|
||||
+ // Paper start - Async chunk io
|
||||
|
@ -3321,7 +3288,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
}
|
||||
|
||||
private CompletableFuture<Either<IChunkAccess, PlayerChunk.Failure>> b(PlayerChunk playerchunk, ChunkStatus chunkstatus) {
|
||||
private void g(ChunkCoordIntPair chunkcoordintpair) {
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
}
|
||||
|
||||
|
@ -3330,43 +3297,37 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
this.m.a(ichunkaccess.getPos());
|
||||
if (!ichunkaccess.isNeedsSaving()) {
|
||||
return false;
|
||||
} else {
|
||||
- try {
|
||||
- this.world.checkSession();
|
||||
- } catch (ExceptionWorldConflict exceptionworldconflict) {
|
||||
- PlayerChunkMap.LOGGER.error("Couldn't save chunk; already in use by another instance of Minecraft?", exceptionworldconflict);
|
||||
- com.destroystokyo.paper.exception.ServerInternalException.reportInternalException(exceptionworldconflict); // Paper
|
||||
- return false;
|
||||
- }
|
||||
+ // Paper - The save session check is performed on the IO thread
|
||||
|
||||
ichunkaccess.setLastSaved(this.world.getTime());
|
||||
ichunkaccess.setNeedsSaving(false);
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
NBTTagCompound nbttagcompound;
|
||||
ChunkStatus chunkstatus = ichunkaccess.getChunkStatus();
|
||||
|
||||
if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) {
|
||||
+ try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveOverwriteCheck.startTiming()) { // Paper
|
||||
// Paper start - Optimize save by using status cache
|
||||
ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkcoordintpair);
|
||||
if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) {
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
if (this.h(chunkcoordintpair)) {
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
if (chunkstatus == ChunkStatus.EMPTY && ichunkaccess.h().values().stream().noneMatch(StructureStart::e)) {
|
||||
return false;
|
||||
}
|
||||
+ } // Paper
|
||||
}
|
||||
|
||||
+ } // Paper
|
||||
this.world.getMethodProfiler().c("chunkSave");
|
||||
- NBTTagCompound nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess);
|
||||
+ NBTTagCompound nbttagcompound;
|
||||
+ try (co.aikar.timings.Timing ignored1 = this.world.timings.chunkSaveDataSerialization.startTiming()) { // Paper
|
||||
nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess);
|
||||
- this.a(chunkcoordintpair, nbttagcompound);
|
||||
+ nbttagcompound = ChunkRegionLoader.saveChunk(this.world, ichunkaccess);
|
||||
+ } // Paper
|
||||
+
|
||||
|
||||
- this.a(chunkcoordintpair, nbttagcompound);
|
||||
+ // Paper start - async chunk io
|
||||
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.scheduleSave(this.world, chunkcoordintpair.x, chunkcoordintpair.z,
|
||||
+ null, nbttagcompound, com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY);
|
||||
+ // Paper end - async chunk io
|
||||
this.a(chunkcoordintpair, chunkstatus.getType());
|
||||
return true;
|
||||
} catch (Exception exception) {
|
||||
PlayerChunkMap.LOGGER.error("Failed to save chunk {},{}", chunkcoordintpair.x, chunkcoordintpair.z, exception);
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
return false;
|
||||
}
|
||||
|
@ -3374,7 +3335,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ } // Paper
|
||||
}
|
||||
|
||||
protected void setViewDistance(int i) {
|
||||
private boolean h(ChunkCoordIntPair chunkcoordintpair) {
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
}
|
||||
}
|
||||
|
@ -3417,14 +3378,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public ChunkStatus getChunkStatusOnDiskIfCached(ChunkCoordIntPair chunkPos) {
|
||||
- RegionFile regionFile = this.getIOWorker().getRegionFileCache().getRegionFileIfLoaded(chunkPos);
|
||||
+ synchronized (this) { // Paper
|
||||
+ RegionFile regionFile = this.getRegionFileIfLoaded(chunkPos);
|
||||
+ RegionFile regionFile = this.regionFileCache.getRegionFileIfLoaded(chunkPos);
|
||||
|
||||
return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
|
||||
+ } // Paper
|
||||
}
|
||||
|
||||
public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException {
|
||||
- RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false);
|
||||
- RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, true);
|
||||
+ // Paper start - async chunk save for unload
|
||||
+ IChunkAccess unloadingChunk = this.world.asyncChunkTaskManager.getChunkInSaveProgress(chunkPos.x, chunkPos.z);
|
||||
+ if (unloadingChunk != null) {
|
||||
|
@ -3435,20 +3396,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ NBTTagCompound inProgressWrite = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE
|
||||
+ .getPendingWrite(this.world, chunkPos.x, chunkPos.z, false);
|
||||
|
||||
- if (!regionFile.chunkExists(chunkPos)) {
|
||||
- if (regionFile == null || !regionFile.chunkExists(chunkPos)) {
|
||||
- return null;
|
||||
+ if (inProgressWrite != null) {
|
||||
+ return ChunkRegionLoader.getStatus(inProgressWrite);
|
||||
}
|
||||
+ // Paper end
|
||||
+ synchronized (this) { // Paper - async io
|
||||
+ RegionFile regionFile = this.getFile(chunkPos, false);
|
||||
+
|
||||
+ if (!regionFile.chunkExists(chunkPos)) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ RegionFile regionFile = this.regionFileCache.getFile(chunkPos, true);
|
||||
|
||||
- ChunkStatus status = regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
|
||||
+ if (regionFile == null || !regionFile.chunkExists(chunkPos)) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ ChunkStatus status = regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
|
||||
|
||||
- if (status != null) {
|
||||
|
@ -3470,7 +3431,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public void updateChunkStatusOnDisk(ChunkCoordIntPair chunkPos, @Nullable NBTTagCompound compound) throws IOException {
|
||||
- RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false);
|
||||
+ synchronized (this) {
|
||||
+ RegionFile regionFile = this.getFile(chunkPos, false);
|
||||
+ RegionFile regionFile = this.regionFileCache.getFile(chunkPos, false);
|
||||
|
||||
- regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkRegionLoader.getStatus(compound));
|
||||
+ regionFile.setStatus(chunkPos.x, chunkPos.z, ChunkRegionLoader.getStatus(compound));
|
||||
|
@ -3506,7 +3467,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ synchronized (world.getChunkProvider().playerChunkMap) {
|
||||
+ net.minecraft.server.RegionFile file;
|
||||
+ try {
|
||||
+ file = world.getChunkProvider().playerChunkMap.getFile(chunkPos, false);
|
||||
+ file = world.getChunkProvider().playerChunkMap.regionFileCache.getFile(chunkPos, false);
|
||||
+ } catch (IOException ex) {
|
||||
+ throw new RuntimeException(ex);
|
||||
+ }
|
||||
|
@ -3577,9 +3538,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
this.closed = true; // Paper
|
||||
try {
|
||||
this.c();
|
||||
this.d();
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
}
|
||||
this.dataFile.close();
|
||||
}
|
||||
}
|
||||
+ } finally { // Paper start - Prevent regionfiles from being closed during use
|
||||
|
@ -3633,7 +3594,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
} else {
|
||||
if (this.cache.size() >= com.destroystokyo.paper.PaperConfig.regionFileCacheSize) { // Paper - configurable
|
||||
@@ -0,0 +0,0 @@ public final class RegionFileCache implements AutoCloseable {
|
||||
RegionFile regionfile1 = new RegionFile(file, this.b);
|
||||
RegionFile regionfile1 = new RegionFile(file, this.b, this.c);
|
||||
|
||||
this.cache.putAndMoveToFirst(i, regionfile1);
|
||||
+ // Paper start
|
||||
|
@ -3686,9 +3647,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
- public void close() throws IOException {
|
||||
+ public synchronized void close() throws IOException { // Paper -> synchronized
|
||||
ExceptionSuppressor<IOException> exceptionsuppressor = new ExceptionSuppressor<>();
|
||||
ObjectIterator objectiterator = this.cache.values().iterator();
|
||||
|
||||
while (objectiterator.hasNext()) {
|
||||
@@ -0,0 +0,0 @@ public final class RegionFileCache implements AutoCloseable {
|
||||
}
|
||||
|
||||
|
@ -3710,39 +3671,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
-public class RegionFileSection<R extends MinecraftSerializable> implements AutoCloseable {
|
||||
+public class RegionFileSection<R extends MinecraftSerializable> extends RegionFileCache implements AutoCloseable { // Paper - nuke IOWorker
|
||||
-public class RegionFileSection<R> implements AutoCloseable {
|
||||
+public class RegionFileSection<R> extends RegionFileCache implements AutoCloseable { // Paper - nuke IOWorker
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
- private final IOWorker b;
|
||||
+// private final IOWorker b;
|
||||
+ // Paper - nuke IOWorker
|
||||
private final Long2ObjectMap<Optional<R>> c = new Long2ObjectOpenHashMap();
|
||||
- private final LongLinkedOpenHashSet d = new LongLinkedOpenHashSet();
|
||||
+ protected final LongLinkedOpenHashSet d = new LongLinkedOpenHashSet(); // Paper - private -> protected
|
||||
private final BiFunction<Runnable, Dynamic<?>, R> e;
|
||||
private final Function<Runnable, Codec<R>> e;
|
||||
private final Function<Runnable, R> f;
|
||||
private final DataFixer g;
|
||||
private final DataFixTypes h;
|
||||
|
||||
public RegionFileSection(File file, BiFunction<Runnable, Dynamic<?>, R> bifunction, Function<Runnable, R> function, DataFixer datafixer, DataFixTypes datafixtypes) {
|
||||
+ super(file); // Paper - nuke IOWorker
|
||||
this.e = bifunction;
|
||||
this.f = function;
|
||||
public RegionFileSection(File file, Function<Runnable, Codec<R>> function, Function<Runnable, R> function1, DataFixer datafixer, DataFixTypes datafixtypes, boolean flag) {
|
||||
+ super(file, flag); // Paper - nuke IOWorker
|
||||
this.e = function;
|
||||
this.f = function1;
|
||||
this.g = datafixer;
|
||||
this.h = datafixtypes;
|
||||
- this.b = new IOWorker(new RegionFileCache(file), file.getName());
|
||||
+// this.b = new IOWorker(new RegionFileCache(file), file.getName()); // Paper - nuke IOWorker
|
||||
- this.b = new IOWorker(file, flag, file.getName());
|
||||
+ //this.b = new IOWorker(file, flag, file.getName()); // Paper - nuke IOWorker
|
||||
}
|
||||
|
||||
protected void a(BooleanSupplier booleansupplier) {
|
||||
- while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) {
|
||||
- ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).u();
|
||||
+ while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) { // Paper - conflict here to avoid obfhelpers
|
||||
+ ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).u(); // Paper - conflict here to avoid obfhelpers
|
||||
while (!this.d.isEmpty() && booleansupplier.getAsBoolean()) {
|
||||
- ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).r();
|
||||
+ ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(this.d.firstLong()).r(); // Paper - conflict here to avoid obfhelpers
|
||||
|
||||
this.d(chunkcoordintpair);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class RegionFileSection<R extends MinecraftSerializable> implements AutoC
|
||||
@@ -0,0 +0,0 @@ public class RegionFileSection<R> implements AutoCloseable {
|
||||
}
|
||||
|
||||
private void b(ChunkCoordIntPair chunkcoordintpair) {
|
||||
|
@ -3763,7 +3723,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
} catch (IOException ioexception) {
|
||||
RegionFileSection.LOGGER.error("Error reading chunk {} data from disk", chunkcoordintpair, ioexception);
|
||||
return null;
|
||||
@@ -0,0 +0,0 @@ public class RegionFileSection<R extends MinecraftSerializable> implements AutoC
|
||||
@@ -0,0 +0,0 @@ public class RegionFileSection<R> implements AutoCloseable {
|
||||
}
|
||||
|
||||
private void d(ChunkCoordIntPair chunkcoordintpair) {
|
||||
|
@ -3797,19 +3757,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private <T> Dynamic<T> a(ChunkCoordIntPair chunkcoordintpair, DynamicOps<T> dynamicops) {
|
||||
Map<T, T> map = Maps.newHashMap();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class RegionFileSection<R extends MinecraftSerializable> implements AutoC
|
||||
@@ -0,0 +0,0 @@ public class RegionFileSection<R> implements AutoCloseable {
|
||||
public void a(ChunkCoordIntPair chunkcoordintpair) {
|
||||
if (!this.d.isEmpty()) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
- long j = SectionPosition.a(chunkcoordintpair, i).v();
|
||||
+ long j = SectionPosition.a(chunkcoordintpair, i).v(); // Paper - conflict here to avoid obfhelpers
|
||||
- long j = SectionPosition.a(chunkcoordintpair, i).s();
|
||||
+ long j = SectionPosition.a(chunkcoordintpair, i).s(); // Paper - conflict here to avoid obfhelpers
|
||||
|
||||
- if (this.d.contains(j)) {
|
||||
+ if (this.d.contains(j)) { // Paper - conflict here to avoid obfhelpers
|
||||
this.d(chunkcoordintpair);
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class RegionFileSection<R extends MinecraftSerializable> implements AutoC
|
||||
@@ -0,0 +0,0 @@ public class RegionFileSection<R> implements AutoCloseable {
|
||||
|
||||
}
|
||||
|
||||
|
@ -3827,7 +3787,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // This is checking if the data exists, then it builds it later in getDataInternal(ChunkCoordIntPair)
|
||||
+ if (!this.d.isEmpty()) {
|
||||
+ for (int i = 0; i < 16; ++i) {
|
||||
+ long j = SectionPosition.a(chunkcoordintpair, i).v();
|
||||
+ long j = SectionPosition.a(chunkcoordintpair, i).s();
|
||||
+
|
||||
+ if (this.d.contains(j)) {
|
||||
+ return this.getDataInternal(chunkcoordintpair);
|
||||
|
@ -3860,14 +3820,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
+ private final WorldServer world; // Paper
|
||||
+
|
||||
public VillagePlace(File file, DataFixer datafixer) {
|
||||
+ // Paper start
|
||||
+ this(file, datafixer, null);
|
||||
public VillagePlace(File file, DataFixer datafixer, boolean flag) {
|
||||
+ // Paper start - add world parameter
|
||||
+ this(file, datafixer, flag, null);
|
||||
+ }
|
||||
+ public VillagePlace(File file, DataFixer datafixer, WorldServer world) {
|
||||
+ // Paper end
|
||||
super(file, VillagePlaceSection::new, VillagePlaceSection::new, datafixer, DataFixTypes.POI_CHUNK);
|
||||
+ this.world = world; // Paper
|
||||
+ public VillagePlace(File file, DataFixer datafixer, boolean flag, WorldServer world) {
|
||||
super(file, VillagePlaceSection::a, VillagePlaceSection::new, datafixer, DataFixTypes.POI_CHUNK, flag);
|
||||
+ this.world = world;
|
||||
+ // Paper end - add world parameter
|
||||
}
|
||||
|
||||
public void a(BlockPosition blockposition, VillagePlaceType villageplacetype) {
|
||||
|
@ -3882,7 +3842,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ } else {
|
||||
+ //super.a(booleansupplier); // re-implement below
|
||||
+ while (!((RegionFileSection)this).d.isEmpty() && booleansupplier.getAsBoolean()) {
|
||||
+ ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(((RegionFileSection)this).d.firstLong()).u();
|
||||
+ ChunkCoordIntPair chunkcoordintpair = SectionPosition.a(((RegionFileSection)this).d.firstLong()).r();
|
||||
+
|
||||
+ NBTTagCompound data;
|
||||
+ try (co.aikar.timings.Timing ignored1 = this.world.timings.poiSaveDataSerialization.startTiming()) {
|
||||
|
@ -3936,8 +3896,8 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
return new Throwable(entity + " Added to world at " + new java.util.Date());
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
return this.chunkProvider.getChunkAt(x, z, false);
|
||||
}
|
||||
|
||||
+ // Paper start - Asynchronous IO
|
||||
|
@ -3993,7 +3953,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ RegionFile file;
|
||||
+
|
||||
+ try {
|
||||
+ file = WorldServer.this.getChunkProvider().playerChunkMap.getFile(new ChunkCoordIntPair(chunkX, chunkZ), false);
|
||||
+ file = WorldServer.this.getChunkProvider().playerChunkMap.regionFileCache.getFile(new ChunkCoordIntPair(chunkX, chunkZ), false);
|
||||
+ } catch (java.io.IOException ex) {
|
||||
+ throw new RuntimeException(ex);
|
||||
+ }
|
||||
|
@ -4005,7 +3965,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ @Override
|
||||
+ public <T> T computeForRegionFileIfLoaded(int chunkX, int chunkZ, java.util.function.Function<RegionFile, T> function) {
|
||||
+ synchronized (WorldServer.this.getChunkProvider().playerChunkMap) {
|
||||
+ RegionFile file = WorldServer.this.getChunkProvider().playerChunkMap.getRegionFileIfLoaded(new ChunkCoordIntPair(chunkX, chunkZ));
|
||||
+ RegionFile file = WorldServer.this.getChunkProvider().playerChunkMap.regionFileCache.getRegionFileIfLoaded(new ChunkCoordIntPair(chunkX, chunkZ));
|
||||
+ return function.apply(file);
|
||||
+ }
|
||||
+ }
|
||||
|
@ -4013,19 +3973,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager;
|
||||
+ // Paper end
|
||||
+
|
||||
// Add env and gen to constructor
|
||||
public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
|
||||
this.mobSpawnerTrader = this.worldProvider.getDimensionManager().getType() == DimensionManager.OVERWORLD ? new MobSpawnerTrader(this) : null; // CraftBukkit - getType()
|
||||
// Add env and gen to constructor, WorldData -> WorldDataServer
|
||||
public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
this.dragonBattle = null;
|
||||
}
|
||||
this.getServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
+
|
||||
+ this.asyncChunkTaskManager = new com.destroystokyo.paper.io.chunk.ChunkTaskManager(this); // Paper
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
|
||||
MCUtil.getSpiralOutChunks(spawn, radiusInBlocks >> 4).forEach(pair -> {
|
||||
|
@ -4082,8 +4042,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
// fall through to load
|
||||
// we do this so we do not re-read the chunk data on disk
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld implements World {
|
||||
|
||||
return new CraftDragonBattle(worldProvider.o()); // PAIL rename getDragonBattle
|
||||
public DragonBattle getEnderDragonBattle() {
|
||||
return (getHandle().getDragonBattle() == null) ? null : new CraftDragonBattle(getHandle().getDragonBattle());
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Fri, 21 Feb 2020 18:44:28 +0000
|
||||
Subject: [PATCH] Backport fix for MC-167561
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityWolf.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityWolf.java
|
||||
@@ -0,0 +0,0 @@ public class EntityWolf extends EntityTameableAnimal {
|
||||
boolean flag = super.a(entityhuman, enumhand);
|
||||
|
||||
if (!flag || this.isBaby()) {
|
||||
- this.goalSit.setSitting(!this.isSitting());
|
||||
+ //this.goalSit.setSitting(!this.isSitting()); // Paper start - copied from below
|
||||
+ if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) {
|
||||
+ this.goalSit.setSitting(!this.isSitting());
|
||||
+ this.jumping = false;
|
||||
+ this.navigation.o();
|
||||
+ this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
|
||||
+ }
|
||||
+ // Paper end - copied from below
|
||||
}
|
||||
|
||||
return flag;
|
||||
@@ -0,0 +0,0 @@ public class EntityWolf extends EntityTameableAnimal {
|
||||
return true;
|
||||
}
|
||||
|
||||
+ /* Paper start - Move into above
|
||||
if (this.i((EntityLiving) entityhuman) && !this.i(itemstack)) {
|
||||
this.goalSit.setSitting(!this.isSitting());
|
||||
this.jumping = false;
|
||||
this.navigation.o();
|
||||
this.setGoalTarget((EntityLiving) null, TargetReason.FORGOT_TARGET, true); // CraftBukkit - reason
|
||||
}
|
||||
+ */ // Paper end
|
||||
} else if (item == Items.BONE && !this.isAngry()) {
|
||||
if (!entityhuman.abilities.canInstantlyBuild) {
|
||||
itemstack.subtract(1);
|
|
@ -1,29 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Thu, 6 Feb 2020 19:20:27 -0600
|
||||
Subject: [PATCH] Be more tolerant of invalid attributes
|
||||
|
||||
Prior to this commit, the player would be disconnected if they ever encountered an attribute with a name that did
|
||||
not match Bukkit's expected vanilla scheme. It appears that datapacks can set whatever attribute name they want,
|
||||
ignoring vanilla's typical scheme.
|
||||
|
||||
In a more perfect world the API would expose some way to interact with these attributes, however Bukkit is not
|
||||
particularly flexible in this area. Perhaps this is an area for future expansion at a later time.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeMap.java
|
||||
@@ -0,0 +0,0 @@ public class CraftAttributeMap implements Attributable {
|
||||
public static Attribute fromMinecraft(String nms) {
|
||||
String[] split = nms.split("\\.", 2);
|
||||
|
||||
+ // Paper start - Datapacks can set their own attributes that may not match our expectations, ignore them
|
||||
+ if (split.length != 2) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
String generic = split[0];
|
||||
String descriptor = CaseFormat.LOWER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, split[1]); // movementSpeed -> MOVEMENT_SPEED
|
||||
String fin = generic + "_" + descriptor;
|
|
@ -34,7 +34,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/n
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityBee.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityBee.java
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird {
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
|
||||
|
||||
public EntityBee(EntityTypes<? extends EntityBee> entitytypes, World world) {
|
||||
super(entitytypes, world);
|
||||
|
@ -51,5 +51,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ };
|
||||
+ // Paper end
|
||||
this.lookController = new EntityBee.j(this);
|
||||
this.a(PathType.DANGER_FIRE, -1.0F);
|
||||
this.a(PathType.WATER, -1.0F);
|
||||
this.a(PathType.COCOA, -1.0F);
|
||||
|
|
|
@ -27,18 +27,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+++ b/src/main/java/net/minecraft/server/EntityZombie.java
|
||||
@@ -0,0 +0,0 @@ public class EntityZombie extends EntityMonster {
|
||||
@Override
|
||||
public void b(EntityLiving entityliving) {
|
||||
super.b(entityliving);
|
||||
public void a_(EntityLiving entityliving) {
|
||||
super.a_(entityliving);
|
||||
- if ((this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) && entityliving instanceof EntityVillager) {
|
||||
- if (this.world.getDifficulty() != EnumDifficulty.HARD && this.random.nextBoolean()) {
|
||||
+ // Paper start
|
||||
+ if (world.paperConfig.zombieVillagerInfectionChance != 0.0 && (world.paperConfig.zombieVillagerInfectionChance != -1.0 || this.world.getDifficulty() == EnumDifficulty.NORMAL || this.world.getDifficulty() == EnumDifficulty.HARD) && entityliving instanceof EntityVillager) {
|
||||
+ if (world.paperConfig.zombieVillagerInfectionChance == -1.0 && this.world.getDifficulty() != EnumDifficulty.HARD && this.random.nextBoolean()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (world.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > world.paperConfig.zombieVillagerInfectionChance) {
|
||||
return;
|
||||
- }
|
||||
}
|
||||
+ if (world.paperConfig.zombieVillagerInfectionChance != -1.0 && (this.random.nextDouble() * 100.0) > world.paperConfig.zombieVillagerInfectionChance) {
|
||||
+ return;
|
||||
+ } // Paper end
|
||||
|
||||
EntityVillager entityvillager = (EntityVillager) entityliving;
|
||||
|
|
|
@ -38,29 +38,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ disableRelativeProjectileVelocity = getBoolean("game-mechanics.disable-relative-projectile-velocity", false);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java
|
||||
diff --git a/src/main/java/net/minecraft/server/IProjectile.java b/src/main/java/net/minecraft/server/IProjectile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityArrow.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityArrow.java
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityArrow extends Entity implements IProjectile {
|
||||
float f7 = MathHelper.cos(f1 * 0.017453292F) * MathHelper.cos(f * 0.017453292F);
|
||||
|
||||
this.shoot((double) f5, (double) f6, (double) f7, f3, f4);
|
||||
- this.setMot(this.getMot().add(entity.getMot().x, entity.onGround ? 0.0D : entity.getMot().y, entity.getMot().z));
|
||||
+ if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(entity.getMot().x, entity.onGround ? 0.0D : entity.getMot().y, entity.getMot().z)); // Paper - allow disabling relative velocity
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityProjectile.java b/src/main/java/net/minecraft/server/EntityProjectile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityProjectile.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityProjectile.java
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityProjectile extends Entity implements IProjectile {
|
||||
--- a/src/main/java/net/minecraft/server/IProjectile.java
|
||||
+++ b/src/main/java/net/minecraft/server/IProjectile.java
|
||||
@@ -0,0 +0,0 @@ public abstract class IProjectile extends Entity {
|
||||
this.shoot((double) f5, (double) f6, (double) f7, f3, f4);
|
||||
Vec3D vec3d = entity.getMot();
|
||||
|
||||
- this.setMot(this.getMot().add(vec3d.x, entity.onGround ? 0.0D : vec3d.y, vec3d.z));
|
||||
+ if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(vec3d.x, entity.onGround ? 0.0D : vec3d.y, vec3d.z)); // Paper - allow disabling relative velocity
|
||||
- this.setMot(this.getMot().add(vec3d.x, entity.isOnGround() ? 0.0D : vec3d.y, vec3d.z));
|
||||
+ if (!entity.world.paperConfig.disableRelativeProjectileVelocity) this.setMot(this.getMot().add(vec3d.x, entity.isOnGround() ? 0.0D : vec3d.y, vec3d.z)); // Paper - allow disabling relative velocity
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void a(MovingObjectPosition movingobjectposition) {
|
||||
|
|
|
@ -6,41 +6,35 @@ Subject: [PATCH] Do less work if we have a custom Bukkit generator
|
|||
If the Bukkit generator already has a spawn, use it immediately instead
|
||||
of spending time generating one that we won't use
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
} else if (this.worldData.getType() == WorldType.DEBUG_ALL_BLOCK_STATES) {
|
||||
this.worldData.setSpawn(BlockPosition.ZERO.up());
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
} else if (flag1) {
|
||||
iworlddataserver.setSpawn(BlockPosition.ZERO.up());
|
||||
} else {
|
||||
- WorldChunkManager worldchunkmanager = this.getChunkProvider().getChunkGenerator().getWorldChunkManager();
|
||||
- List<BiomeBase> list = worldchunkmanager.a();
|
||||
- Random random = new Random(this.getSeed());
|
||||
- BlockPosition blockposition = worldchunkmanager.a(0, this.getSeaLevel(), 0, 256, list, random);
|
||||
- WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
|
||||
- List<BiomeBase> list = worldchunkmanager.b();
|
||||
- Random random = new Random(worldserver.getSeed());
|
||||
- BlockPosition blockposition = worldchunkmanager.a(0, worldserver.getSeaLevel(), 0, 256, list, random);
|
||||
- ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition);
|
||||
-
|
||||
+// Paper start - moved down
|
||||
+// WorldChunkManager worldchunkmanager = this.getChunkProvider().getChunkGenerator().getWorldChunkManager();
|
||||
+// List<BiomeBase> list = worldchunkmanager.a();
|
||||
+// Random random = new Random(this.getSeed());
|
||||
+// BlockPosition blockposition = worldchunkmanager.a(0, this.getSeaLevel(), 0, 256, list, random);
|
||||
+// ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition);
|
||||
+// Paper end
|
||||
+ // Paper start - moved down
|
||||
// CraftBukkit start
|
||||
if (this.generator != null) {
|
||||
Random rand = new Random(this.getSeed());
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
if (worldserver.generator != null) {
|
||||
Random rand = new Random(worldserver.getSeed());
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ // Paper start - this is useless if craftbukkit returns early
|
||||
+ WorldChunkManager worldchunkmanager = this.getChunkProvider().getChunkGenerator().getWorldChunkManager();
|
||||
+ List<BiomeBase> list = worldchunkmanager.a();
|
||||
+ Random random = new Random(this.getSeed());
|
||||
+ BlockPosition blockposition = worldchunkmanager.a(0, this.getSeaLevel(), 0, 256, list, random);
|
||||
+ // Paper start - if the generator created a spawn for us, then there is no need for us to also create a spawn -
|
||||
+ // only do it if the generator did not
|
||||
+ WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
|
||||
+ List<BiomeBase> list = worldchunkmanager.b();
|
||||
+ Random random = new Random(worldserver.getSeed());
|
||||
+ BlockPosition blockposition = worldchunkmanager.a(0, worldserver.getSeaLevel(), 0, 256, list, random);
|
||||
+ ChunkCoordIntPair chunkcoordintpair = blockposition == null ? new ChunkCoordIntPair(0, 0) : new ChunkCoordIntPair(blockposition);
|
||||
+ // Paper end
|
||||
|
||||
if (blockposition == null) {
|
||||
WorldServer.LOGGER.warn("Unable to find spawn biome");
|
||||
}
|
||||
MinecraftServer.LOGGER.warn("Unable to find spawn biome");
|
||||
|
|
|
@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/n
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityBee.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityBee.java
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird {
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
|
||||
if (this.hivePos == null) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
TileEntity tileentity = this.world.getTileEntity(this.hivePos);
|
||||
|
||||
return tileentity instanceof TileEntityBeehive && ((TileEntityBeehive) tileentity).d();
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird {
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
|
||||
}
|
||||
|
||||
private boolean i(BlockPosition blockposition) {
|
||||
|
@ -24,15 +24,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
TileEntity tileentity = this.world.getTileEntity(blockposition);
|
||||
|
||||
return tileentity instanceof TileEntityBeehive ? !((TileEntityBeehive) tileentity).isFull() : false;
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird {
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
|
||||
@Override
|
||||
public boolean g() {
|
||||
if (EntityBee.this.hasHivePos() && EntityBee.this.eI() && EntityBee.this.hivePos.a((IPosition) EntityBee.this.getPositionVector(), 2.0D)) {
|
||||
if (EntityBee.this.hasHivePos() && EntityBee.this.fe() && EntityBee.this.hivePos.a((IPosition) EntityBee.this.getPositionVector(), 2.0D)) {
|
||||
+ if (!EntityBee.this.world.isLoadedAndInBounds(EntityBee.this.hivePos)) return false; // Paper
|
||||
TileEntity tileentity = EntityBee.this.world.getTileEntity(EntityBee.this.hivePos);
|
||||
|
||||
if (tileentity instanceof TileEntityBeehive) {
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird {
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
|
||||
|
||||
@Override
|
||||
public void c() {
|
||||
|
|
|
@ -21,13 +21,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
} else {
|
||||
BlockPosition blockposition1 = blockposition.shift((EnumDirection) function1.apply(iblockdata));
|
||||
- IBlockData iblockdata1 = generatoraccess.getType(blockposition1);
|
||||
-
|
||||
+ // Paper start - don't load chunks if the other side of the chest is in unloaded chunk
|
||||
+ // Paper start
|
||||
+ IBlockData iblockdata1 = generatoraccess.getTypeIfLoaded(blockposition1);
|
||||
+ if (iblockdata1 == null) {
|
||||
+ return new DoubleBlockFinder.Result.Single<>(s0);
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (iblockdata1.getBlock() == iblockdata.getBlock()) {
|
||||
DoubleBlockFinder.BlockType doubleblockfinder_blocktype1 = (DoubleBlockFinder.BlockType) function.apply(iblockdata1);
|
||||
|
||||
if (iblockdata1.a(iblockdata.getBlock())) {
|
||||
DoubleBlockFinder.BlockType doubleblockfinder_blocktype1 = (DoubleBlockFinder.BlockType) function.apply(iblockdata1);
|
||||
|
|
|
@ -26,15 +26,15 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
Entity entity2;
|
||||
|
||||
try (co.aikar.timings.Timing ignored = this.timings.newEntities.startTiming()) { // Paper - timings
|
||||
while ((entity = (Entity) this.entitiesToAdd.poll()) != null) {
|
||||
+ if (!entity.isQueuedForRegister) continue; // Paper - ignore cancelled registers
|
||||
this.registerEntity(entity);
|
||||
while ((entity2 = (Entity) this.entitiesToAdd.poll()) != null) {
|
||||
+ if (!entity2.isQueuedForRegister) continue; // Paper - ignore cancelled registers
|
||||
this.registerEntity(entity2);
|
||||
}
|
||||
} // Paper - timings
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
|
||||
public void unregisterEntity(Entity entity) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity unregister"); // Spigot
|
||||
|
@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
// Spigot start
|
||||
if ( entity instanceof EntityHuman )
|
||||
{
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
|
||||
private void registerEntity(Entity entity) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity register"); // Spigot
|
||||
|
@ -76,4 +76,4 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ entity.isQueuedForRegister = false; // Paper
|
||||
this.entitiesById.put(entity.getId(), entity);
|
||||
if (entity instanceof EntityEnderDragon) {
|
||||
EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).eo();
|
||||
EntityComplexPart[] aentitycomplexpart = ((EntityEnderDragon) entity).eK();
|
||||
|
|
|
@ -17,13 +17,13 @@ diff --git a/src/main/java/net/minecraft/server/BehaviorController.java b/src/ma
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/BehaviorController.java
|
||||
+++ b/src/main/java/net/minecraft/server/BehaviorController.java
|
||||
@@ -0,0 +0,0 @@ public class BehaviorController<E extends EntityLiving> implements MinecraftSeri
|
||||
});
|
||||
@@ -0,0 +0,0 @@ public class BehaviorController<E extends EntityLiving> {
|
||||
|
||||
}
|
||||
|
||||
+ public boolean hasActivity(Activity activity) { return c(activity); } // Paper - OBFHELPER
|
||||
public boolean c(Activity activity) {
|
||||
return this.g.contains(activity);
|
||||
return this.j.contains(activity);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
@ -46,7 +46,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
if (vec3d.equals(Vec3D.a)) {
|
||||
return;
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
||||
this.y = Vec3D.a;
|
||||
this.x = Vec3D.a;
|
||||
this.setMot(Vec3D.a);
|
||||
}
|
||||
+ // Paper start - ignore movement changes while inactive.
|
||||
|
@ -58,13 +58,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
|
||||
vec3d = this.a(vec3d, enummovetype);
|
||||
Vec3D vec3d1 = this.e(vec3d);
|
||||
Vec3D vec3d1 = this.f(vec3d);
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
||||
return this.am;
|
||||
return this.al;
|
||||
}
|
||||
|
||||
+ public boolean isPushedByWater() { return this.bM(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it!
|
||||
public boolean bM() {
|
||||
+ public boolean isPushedByWater() { return this.bU(); } // Paper - OBFHELPER - the below is not an obfhelper, don't use it!
|
||||
public boolean bU() {
|
||||
// Paper start
|
||||
return this.pushedByWater();
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityCreature.java b/src/main/java/net/minecraft/server/EntityCreature.java
|
||||
|
@ -88,10 +88,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public long lootTableSeed;
|
||||
@Nullable
|
||||
- private Entity leashHolder;
|
||||
+ public Entity leashHolder; // Paper
|
||||
private int bF;
|
||||
+ public Entity leashHolder; // Paper - private -> public
|
||||
private int bE;
|
||||
@Nullable
|
||||
private NBTTagCompound bG;
|
||||
private NBTTagCompound bF;
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityInsentient extends EntityLiving {
|
||||
return this.lookController;
|
||||
}
|
||||
|
@ -115,25 +115,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
protected float aV;
|
||||
protected int aW; protected int getKillCount() { return this.aW; } // Paper - OBFHELPER
|
||||
protected float aU;
|
||||
protected int aV; protected int getKillCount() { return this.aV; } // Paper - OBFHELPER
|
||||
public float lastDamage;
|
||||
- protected boolean jumping;
|
||||
+ public boolean jumping; // Paper
|
||||
+ public boolean jumping; // Paper protected -> public
|
||||
public float aY;
|
||||
public float aZ;
|
||||
public float ba;
|
||||
public float bb;
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityLlama.java b/src/main/java/net/minecraft/server/EntityLlama.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityLlama.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLlama.java
|
||||
@@ -0,0 +0,0 @@ public class EntityLlama extends EntityHorseChestedAbstract implements IRangedEn
|
||||
return this.bK != null;
|
||||
return this.bJ != null;
|
||||
}
|
||||
|
||||
+ public boolean inCaravan() { return this.fd(); } // Paper - OBFHELPER
|
||||
public boolean fd() {
|
||||
return this.bJ != null;
|
||||
+ public final boolean inCaravan() { return this.fD(); } // Paper - OBFHELPER
|
||||
public boolean fD() {
|
||||
return this.bI != null;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
@ -148,14 +148,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper start
|
||||
+ if (this.getUnhappy() > 0) {
|
||||
+ this.setUnhappy(this.getUnhappy() - 1);
|
||||
+ }
|
||||
}
|
||||
+ if (this.doAITick()) {
|
||||
+ if (world.spigotConfig.tickInactiveVillagers) {
|
||||
+ this.mobTick();
|
||||
+ } else {
|
||||
+ this.mobTick(true);
|
||||
+ }
|
||||
}
|
||||
+ }
|
||||
+ doReputationTick();
|
||||
+ // Paper end
|
||||
+
|
||||
|
@ -163,30 +163,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
// Spigot End
|
||||
|
||||
- @Override
|
||||
@Override
|
||||
- protected void mobTick() {
|
||||
+ @Override // Paper start - tick trades while inactive
|
||||
+ protected void mobTick() { mobTick(false); }
|
||||
+ protected void mobTick(boolean inactive) {
|
||||
+ // Paper end
|
||||
this.world.getMethodProfiler().enter("brain");
|
||||
this.world.getMethodProfiler().enter("villagerBrain");
|
||||
- this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error
|
||||
- this.world.getMethodProfiler().exit();
|
||||
+ if (!inactive) this.getBehaviorController().a((WorldServer) this.world, this); // CraftBukkit - decompile error // Paper
|
||||
this.world.getMethodProfiler().exit();
|
||||
if (!this.et() && this.bB > 0) {
|
||||
--this.bB;
|
||||
if (this.bM) {
|
||||
this.bM = false;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
|
||||
this.bD = null;
|
||||
this.bC = null;
|
||||
}
|
||||
|
||||
- if (!this.isNoAI() && this.random.nextInt(100) == 0) {
|
||||
+ if (!inactive && !this.isNoAI() && this.random.nextInt(100) == 0) { // Paper
|
||||
Raid raid = ((WorldServer) this.world).c_(new BlockPosition(this));
|
||||
Raid raid = ((WorldServer) this.world).c_(this.getChunkCoordinates());
|
||||
|
||||
if (raid != null && raid.v() && !raid.a()) {
|
||||
@@ -0,0 +0,0 @@ public class EntityVillager extends EntityVillagerAbstract implements Reputation
|
||||
if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.et()) {
|
||||
this.ey();
|
||||
if (this.getVillagerData().getProfession() == VillagerProfession.NONE && this.eO()) {
|
||||
this.eT();
|
||||
}
|
||||
+ if (inactive) return; // Paper
|
||||
|
||||
|
@ -196,8 +195,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
}
|
||||
|
||||
+ private void doReputationTick() { fa(); } // Paper - OBFHELPER
|
||||
private void fa() {
|
||||
+ private void doReputationTick() { fv(); } // Paper - OBFHELPER
|
||||
private void fv() {
|
||||
long i = this.world.getTime();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityVillagerAbstract.java b/src/main/java/net/minecraft/server/EntityVillagerAbstract.java
|
||||
|
@ -208,14 +207,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
return super.prepare(generatoraccess, difficultydamagescaler, enummobspawn, (GroupDataEntity) groupdataentity, nbttagcompound);
|
||||
}
|
||||
|
||||
+ public final int getUnhappy() { return eq(); } // Paper - OBFHELPER
|
||||
public int eq() {
|
||||
return (Integer) this.datawatcher.get(EntityVillagerAbstract.bx);
|
||||
+ public final int getUnhappy() { return eL(); } // Paper - OBFHELPER
|
||||
public int eL() {
|
||||
return (Integer) this.datawatcher.get(EntityVillagerAbstract.bw);
|
||||
}
|
||||
|
||||
+ public final void setUnhappy(int i) { s(i); } // Paper - OBFHELPER
|
||||
public void s(int i) {
|
||||
this.datawatcher.set(EntityVillagerAbstract.bx, i);
|
||||
this.datawatcher.set(EntityVillagerAbstract.bw, i);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/PathfinderGoal.java b/src/main/java/net/minecraft/server/PathfinderGoal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
@ -267,7 +266,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public PathfinderGoalGotoTarget(EntityCreature entitycreature, double d0, int i, int j) {
|
||||
this.e = BlockPosition.ZERO;
|
||||
@@ -0,0 +0,0 @@ public abstract class PathfinderGoalGotoTarget extends PathfinderGoal {
|
||||
blockposition_mutableblockposition.g(blockposition).e(i1, k - 1, j1);
|
||||
blockposition_mutableblockposition.a((BaseBlockPosition) blockposition, i1, k - 1, j1);
|
||||
if (this.a.a((BlockPosition) blockposition_mutableblockposition) && this.a(this.a.world, blockposition_mutableblockposition)) {
|
||||
this.e = blockposition_mutableblockposition;
|
||||
+ setTarget(blockposition_mutableblockposition.immutableCopy()); // Paper
|
||||
|
@ -283,15 +282,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
};
|
||||
private final Map<PathfinderGoal.Type, PathfinderGoalWrapped> c = new EnumMap(PathfinderGoal.Type.class);
|
||||
- private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet();
|
||||
+ private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet();private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
|
||||
private final GameProfilerFiller e;
|
||||
+ private final Set<PathfinderGoalWrapped> d = Sets.newLinkedHashSet(); private Set<PathfinderGoalWrapped> getTasks() { return d; }// Paper - OBFHELPER
|
||||
private final Supplier<GameProfilerFiller> e;
|
||||
private final EnumSet<PathfinderGoal.Type> f = EnumSet.noneOf(PathfinderGoal.Type.class);
|
||||
- private int g = 3;
|
||||
+ private int g = 3;private int getTickRate() { return g; } // Paper - OBFHELPER
|
||||
+ private int curRate;private int getCurRate() { return curRate; } private void incRate() { this.curRate++; } // Paper TODO
|
||||
|
||||
public PathfinderGoalSelector(GameProfilerFiller gameprofilerfiller) {
|
||||
this.e = gameprofilerfiller;
|
||||
public PathfinderGoalSelector(Supplier<GameProfilerFiller> supplier) {
|
||||
this.e = supplier;
|
||||
@@ -0,0 +0,0 @@ public class PathfinderGoalSelector {
|
||||
this.d.add(new PathfinderGoalWrapped(i, pathfindergoal));
|
||||
}
|
||||
|
@ -593,8 +592,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
if ( !( entity instanceof EntityArrow ) )
|
||||
{
|
||||
- if ( !entity.onGround || !entity.passengers.isEmpty() || entity.isPassenger() )
|
||||
+ if ( (!entity.onGround && !(entity instanceof EntityFlying)) || !entity.passengers.isEmpty() || entity.isPassenger() ) // Paper
|
||||
- if ( !entity.isOnGround() || !entity.passengers.isEmpty() || entity.isPassenger() )
|
||||
+ if ( (!entity.isOnGround() && !(entity instanceof EntityFlying)) || !entity.passengers.isEmpty() || entity.isPassenger() )
|
||||
{
|
||||
- return true;
|
||||
+ return 10; // Paper
|
||||
|
|
|
@ -9,9 +9,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
} else if (this.aH()) {
|
||||
this.c(TagsFluid.LAVA);
|
||||
} else if ((this.onGround || this.N > 0.0D && this.N <= 0.4D) && this.jumpTicks == 0) {
|
||||
} else if (this.aN() && (!this.onGround || d7 > d8)) {
|
||||
this.c((Tag) TagsFluid.LAVA);
|
||||
} else if ((this.onGround || flag && d7 <= d8) && this.jumpTicks == 0) {
|
||||
+ if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper
|
||||
this.jump();
|
||||
this.jumpTicks = 10;
|
||||
|
@ -26,7 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public class EntityPanda extends EntityAnimal {
|
||||
EntityPanda entitypanda = (EntityPanda) iterator.next();
|
||||
|
||||
if (!entitypanda.isBaby() && entitypanda.onGround && !entitypanda.isInWater() && entitypanda.eL()) {
|
||||
if (!entitypanda.isBaby() && entitypanda.onGround && !entitypanda.isInWater() && entitypanda.fi()) {
|
||||
+ if (new com.destroystokyo.paper.event.entity.EntityJumpEvent(getBukkitLivingEntity()).callEvent()) { // Paper
|
||||
entitypanda.jump();
|
||||
+ } else { this.setJumping(false); } // Paper - setJumping(false) stops a potential loop
|
||||
|
|
|
@ -11,10 +11,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
return this.getEquipment(EnumItemSlot.OFFHAND);
|
||||
return predicate.test(this.getItemInMainHand().getItem()) || predicate.test(this.getItemInOffHand().getItem());
|
||||
}
|
||||
|
||||
+ public ItemStack getItemInHand(EnumHand enumhand) { return this.b(enumhand); } // Paper - OBFHELPER
|
||||
+ public final ItemStack getItemInHand(EnumHand enumhand) { return this.b(enumhand); } // Paper - OBFHELPER
|
||||
public ItemStack b(EnumHand enumhand) {
|
||||
if (enumhand == EnumHand.MAIN_HAND) {
|
||||
return this.getEquipment(EnumItemSlot.MAINHAND);
|
||||
|
@ -23,13 +23,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
||||
if (cancelled) {
|
||||
this.player.getBukkitEntity().updateInventory(); // SPIGOT-2524
|
||||
} else {
|
||||
+ // Paper start
|
||||
+ itemstack = this.player.getItemInHand(enumhand);
|
||||
+ if (itemstack.isEmpty()) return;
|
||||
+ // Paper end
|
||||
this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand);
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start
|
||||
+ itemstack = this.player.getItemInHand(enumhand);
|
||||
+ if (itemstack.isEmpty()) return;
|
||||
+ // Paper end
|
||||
EnumInteractionResult enuminteractionresult = this.player.playerInteractManager.a(this.player, worldserver, itemstack, enumhand);
|
||||
|
||||
if (enuminteractionresult.b()) {
|
||||
|
|
|
@ -142,14 +142,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- private NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException {
|
||||
+ public NBTTagCompound readChunkData(ChunkCoordIntPair chunkcoordintpair) throws IOException { // Paper - private -> public
|
||||
NBTTagCompound nbttagcompound = this.read(chunkcoordintpair);
|
||||
|
||||
- return nbttagcompound == null ? null : this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit
|
||||
+ // Paper start - Cache chunk status on disk
|
||||
+ if (nbttagcompound == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ nbttagcompound = this.getChunkData(this.world.getWorldProvider().getDimensionManager(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit
|
||||
+ nbttagcompound = this.getChunkData(this.world.getTypeKey(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit
|
||||
+ if (nbttagcompound == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
|
@ -165,12 +163,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ RegionFile regionFile = this.getIOWorker().getRegionFileCache().getRegionFileIfLoaded(chunkPos);
|
||||
+
|
||||
+ return regionFile == null ? null : regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
|
||||
}
|
||||
|
||||
+ public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException {
|
||||
+ RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false);
|
||||
+ }
|
||||
+
|
||||
+ if (!regionFile.chunkExists(chunkPos)) {
|
||||
+ public ChunkStatus getChunkStatusOnDisk(ChunkCoordIntPair chunkPos) throws IOException {
|
||||
+ RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, true);
|
||||
+
|
||||
+ if (regionFile == null || !regionFile.chunkExists(chunkPos)) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
|
@ -181,10 +179,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ this.readChunkData(chunkPos);
|
||||
+
|
||||
|
||||
- return nbttagcompound == null ? null : this.getChunkData(this.world.getTypeKey(), this.l, nbttagcompound, chunkcoordintpair, world); // CraftBukkit
|
||||
+ return regionFile.getStatusIfCached(chunkPos.x, chunkPos.z);
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
+ public void updateChunkStatusOnDisk(ChunkCoordIntPair chunkPos, @Nullable NBTTagCompound compound) throws IOException {
|
||||
+ RegionFile regionFile = this.getIOWorker().getRegionFileCache().getFile(chunkPos, false);
|
||||
+
|
||||
|
@ -232,8 +231,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public RegionFile(File file, File file1) throws IOException {
|
||||
this(file.toPath(), file1.toPath(), RegionFileCompression.b);
|
||||
public RegionFile(File file, File file1, boolean flag) throws IOException {
|
||||
this(file.toPath(), file1.toPath(), RegionFileCompression.b, flag);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class RegionFile implements AutoCloseable {
|
||||
return this.getOffset(chunkcoordintpair) != 0;
|
||||
|
@ -247,14 +246,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public void close() throws IOException {
|
||||
+ this.closed = true; // Paper
|
||||
try {
|
||||
this.c();
|
||||
this.d();
|
||||
} finally {
|
||||
diff --git a/src/main/java/net/minecraft/server/RegionFileCache.java b/src/main/java/net/minecraft/server/RegionFileCache.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/RegionFileCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/RegionFileCache.java
|
||||
@@ -0,0 +0,0 @@ public final class RegionFileCache implements AutoCloseable {
|
||||
this.b = file;
|
||||
this.c = flag;
|
||||
}
|
||||
|
||||
- private RegionFile getFile(ChunkCoordIntPair chunkcoordintpair, boolean existingOnly) throws IOException { // CraftBukkit
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Wed, 22 Jan 2020 21:00:21 +0000
|
||||
Subject: [PATCH] Fix comparator behavior for EntityPhanton goal
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityPhantom.java b/src/main/java/net/minecraft/server/EntityPhantom.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityPhantom.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityPhantom.java
|
||||
@@ -0,0 +0,0 @@ public class EntityPhantom extends EntityFlying implements IMonster {
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
list.sort((entityhuman, entityhuman1) -> {
|
||||
- return entityhuman.locY() > entityhuman1.locY() ? -1 : 1;
|
||||
+ return Double.compare(entityhuman1.locY(), entityhuman.locY()); // Paper
|
||||
});
|
||||
Iterator iterator = list.iterator();
|
||||
|
|
@ -19,12 +19,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
||||
|
||||
if (blockposition == null) { // CraftBukkit
|
||||
if (dimensionmanager1.getType() == DimensionManager.THE_END && dimensionmanager == DimensionManager.OVERWORLD) { // CraftBukkit
|
||||
if (this.world.getDimensionKey() == World.THE_END && worldserver.getDimensionKey() == World.OVERWORLD) {
|
||||
+ // Paper start - Ensure spawn chunk is always loaded before calculating Y coordinate
|
||||
+ if (!worldserver1.isLoaded(worldserver1.getSpawn())) {
|
||||
+ worldserver1.getChunkAtWorldCoords(worldserver1.getSpawn());
|
||||
+ }
|
||||
+ this.world.getChunkAtWorldCoords(this.world.getSpawn());
|
||||
+ // Paper end
|
||||
// CraftBukkit start
|
||||
EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver1, worldserver1.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver1.getSpawn()), 0);
|
||||
EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver, worldserver.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver.getSpawn()), 0);
|
||||
if (event == null) {
|
||||
|
|
|
@ -16,8 +16,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
itemstack1 = CraftItemStack.asNMSCopy(event.getItem());
|
||||
- EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack, d3, d4, d5, true);
|
||||
+ EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack1, d3, d4, d5, true); // Paper - GH-2871 - fix last firework in stack having no effects when dispensed
|
||||
- EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack, isourceblock.getX(), isourceblock.getY(), isourceblock.getX(), true);
|
||||
+ EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), itemstack1, isourceblock.getX(), isourceblock.getY(), isourceblock.getX(), true); // Paper - GH-2871 - fix last firework in stack having no effects when dispensed
|
||||
|
||||
entityfireworks.shoot(d0, d1, d2, 0.5F, 1.0F);
|
||||
isourceblock.getWorld().addEntity(entityfireworks);
|
||||
IDispenseBehavior.a(isourceblock, entityfireworks, enumdirection);
|
||||
entityfireworks.shoot((double) enumdirection.getAdjacentX(), (double) enumdirection.getAdjacentY(), (double) enumdirection.getAdjacentZ(), 0.5F, 1.0F);
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 15 Dec 2019 19:41:28 +0000
|
||||
Subject: [PATCH] Fix spawn radius being treated as 0
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||||
public final BlockPosition getSpawnPoint(WorldServer worldserver) {
|
||||
BlockPosition blockposition = worldserver.getSpawn();
|
||||
|
||||
- if (worldserver.worldProvider.g() && worldserver.getWorldData().getGameType() != EnumGamemode.ADVENTURE) {
|
||||
+ if (worldserver.worldProvider.f() && worldserver.getWorldData().getGameType() != EnumGamemode.ADVENTURE) { // Paper
|
||||
int i = Math.max(0, this.server.a(worldserver));
|
||||
int j = MathHelper.floor(worldserver.getWorldBorder().b((double) blockposition.getX(), (double) blockposition.getZ()));
|
||||
|
|
@ -18,7 +18,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
|
||||
private void removeEntityFromChunk(Entity entity) {
|
||||
|
|
|
@ -22,32 +22,68 @@ diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/sr
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java
|
||||
@@ -0,0 +0,0 @@ public abstract class ChunkGeneratorAbstract<T extends GeneratorSettingsDefault>
|
||||
@@ -0,0 +0,0 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator {
|
||||
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
||||
int i = ichunkaccess.getPos().d();
|
||||
int j = ichunkaccess.getPos().e();
|
||||
T t0 = this.getSettings();
|
||||
- int k = t0.u();
|
||||
- int l = t0.t();
|
||||
+ int k = t0.u(); final int floorHeight = k; // Paper
|
||||
+ int l = t0.t(); final int roofHeight = l; // Paper
|
||||
Iterator iterator = BlockPosition.b(i, 0, j, i + 15, 0, j + 15).iterator();
|
||||
- int k = this.h.f();
|
||||
- int l = this.x - 1 - this.h.e();
|
||||
+ int k = this.h.f(); final int floorHeight = k; // Paper
|
||||
+ int l = this.x - 1 - this.h.e(); final int roofHeight = l; // Paper
|
||||
boolean flag = true;
|
||||
boolean flag1 = l + 4 >= 0 && l < this.x;
|
||||
boolean flag2 = k + 4 >= 0 && k < this.x;
|
||||
@@ -0,0 +0,0 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator {
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -0,0 +0,0 @@ public abstract class ChunkGeneratorAbstract<T extends GeneratorSettingsDefault>
|
||||
|
||||
if (l > 0) {
|
||||
for (i1 = l; i1 >= l - 4; --i1) {
|
||||
- if (i1 >= l - random.nextInt(5)) {
|
||||
+ if (i1 >= (getWorld().paperConfig.generateFlatBedrock ? roofHeight : l - random.nextInt(5))) { // Paper - Configurable flat bedrock roof
|
||||
ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
|
||||
if (flag1) {
|
||||
for (i1 = 0; i1 < 5; ++i1) {
|
||||
- if (i1 <= random.nextInt(5)) {
|
||||
+ if (i1 <= (ichunkaccess.generateFlatBedrock() ? roofHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock roof
|
||||
ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), l - i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class ChunkGeneratorAbstract<T extends GeneratorSettingsDefault>
|
||||
@@ -0,0 +0,0 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator {
|
||||
|
||||
if (k < 256) {
|
||||
for (i1 = k + 4; i1 >= k; --i1) {
|
||||
- if (i1 <= k + random.nextInt(5)) {
|
||||
+ if (i1 <= (getWorld().paperConfig.generateFlatBedrock ? floorHeight : k + random.nextInt(5))) { // Paper - Configurable flat bedrock floor
|
||||
ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
|
||||
if (flag2) {
|
||||
for (i1 = 4; i1 >= 0; --i1) {
|
||||
- if (i1 <= random.nextInt(5)) {
|
||||
+ if (i1 <= (ichunkaccess.generateFlatBedrock() ? floorHeight : random.nextInt(5))) { // Paper - Configurable flat bedrock floor
|
||||
ichunkaccess.setType(blockposition_mutableblockposition.d(blockposition.getX(), k + i1, blockposition.getZ()), Blocks.BEDROCK.getBlockData(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/IChunkAccess.java b/src/main/java/net/minecraft/server/IChunkAccess.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/IChunkAccess.java
|
||||
+++ b/src/main/java/net/minecraft/server/IChunkAccess.java
|
||||
@@ -0,0 +0,0 @@ import org.apache.logging.log4j.LogManager;
|
||||
|
||||
public interface IChunkAccess extends IBlockAccess, IStructureAccess {
|
||||
|
||||
+ // Paper start
|
||||
+ default boolean generateFlatBedrock() {
|
||||
+ if (this instanceof ProtoChunk) {
|
||||
+ return ((ProtoChunk)this).world.paperConfig.generateFlatBedrock;
|
||||
+ } else if (this instanceof Chunk) {
|
||||
+ return ((Chunk)this).world.paperConfig.generateFlatBedrock;
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
IBlockData getType(final int x, final int y, final int z); // Paper
|
||||
@Nullable
|
||||
IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag);
|
||||
diff --git a/src/main/java/net/minecraft/server/ProtoChunk.java b/src/main/java/net/minecraft/server/ProtoChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ProtoChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/ProtoChunk.java
|
||||
@@ -0,0 +0,0 @@ public class ProtoChunk implements IChunkAccess {
|
||||
private long s;
|
||||
private final Map<WorldGenStage.Features, BitSet> t;
|
||||
private volatile boolean u;
|
||||
- private final World world; // Paper - Anti-Xray - Add world
|
||||
+ final World world; // Paper - Anti-Xray - Add world // Paper - private -> default
|
||||
|
||||
// Paper start - Anti-Xray - Add world
|
||||
@Deprecated public ProtoChunk(ChunkCoordIntPair chunkcoordintpair, ChunkConverter chunkconverter) { this(chunkcoordintpair, chunkconverter, null); } // Notice for updates: Please make sure this constructor isn't used anywhere
|
||||
|
|
|
@ -25,7 +25,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
@@ -0,0 +0,0 @@ public class ChunkRegionLoader {
|
||||
// Paper end
|
||||
ChunkGenerator<?> chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
|
||||
ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
|
||||
WorldChunkManager worldchunkmanager = chunkgenerator.getWorldChunkManager();
|
||||
- NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Level");
|
||||
- ChunkCoordIntPair chunkcoordintpair1 = new ChunkCoordIntPair(nbttagcompound1.getInt("xPos"), nbttagcompound1.getInt("zPos"));
|
||||
|
@ -38,8 +38,8 @@ diff --git a/src/main/java/net/minecraft/server/IChunkLoader.java b/src/main/jav
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/IChunkLoader.java
|
||||
+++ b/src/main/java/net/minecraft/server/IChunkLoader.java
|
||||
@@ -0,0 +0,0 @@ public class IChunkLoader extends RegionFileCache implements AutoCloseable {
|
||||
//
|
||||
@@ -0,0 +0,0 @@ public class IChunkLoader implements AutoCloseable {
|
||||
|
||||
public void a(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { write(chunkcoordintpair, nbttagcompound); } // Paper OBFHELPER
|
||||
public void write(ChunkCoordIntPair chunkcoordintpair, NBTTagCompound nbttagcompound) throws IOException { // Paper - OBFHELPER - (Switched around for safety)
|
||||
+ // Paper start
|
||||
|
@ -49,6 +49,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ + " but compound says coordinate is " + ChunkRegionLoader.getChunkCoordinate(nbttagcompound).toString() + (world == null ? " for an unknown world" : (" for world: " + world)));
|
||||
+ }
|
||||
+ // Paper end
|
||||
super.write(chunkcoordintpair, nbttagcompound);
|
||||
this.regionFileCache.write(chunkcoordintpair, nbttagcompound);
|
||||
if (this.c != null) {
|
||||
synchronized (this.persistentDataLock) { // Paper - Async chunk loading
|
||||
|
|
|
@ -123,5 +123,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public Packet<?> L() {
|
||||
public Packet<?> O() {
|
||||
return new PacketPlayOutSpawnEntity(this);
|
||||
|
|
|
@ -14,45 +14,45 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
private int jumpTicks;
|
||||
private float bD;
|
||||
public ItemStack activeItem; // Paper - public
|
||||
- protected int bl;
|
||||
+ protected int bl; protected final int getEatTimeTicks() { return this.bl; } protected final void setEatTimeTicks(int value) { this.bl = value; } // Paper - OBFHELPER
|
||||
protected int bm;
|
||||
- protected int bk;
|
||||
+ protected int bk; protected final int getEatTimeTicks() { return this.bk; } protected final void setEatTimeTicks(int value) { this.bk = value; } // Paper - OBFHELPER
|
||||
protected int bl;
|
||||
private BlockPosition bE;
|
||||
private DamageSource bF;
|
||||
private Optional<BlockPosition> bF;
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
return ((Byte) this.datawatcher.get(EntityLiving.ao) & 2) > 0 ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND;
|
||||
return ((Byte) this.datawatcher.get(EntityLiving.an) & 2) > 0 ? EnumHand.OFF_HAND : EnumHand.MAIN_HAND;
|
||||
}
|
||||
|
||||
+ // Paper start - lag compensate eating
|
||||
+ protected long eatStartTime;
|
||||
+ protected int totalEatTimeTicks;
|
||||
+ // Paper end
|
||||
private void o() {
|
||||
+
|
||||
private void u() {
|
||||
if (this.isHandRaised()) {
|
||||
if (ItemStack.d(this.b(this.getRaisedHand()), this.activeItem)) {
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
this.b(this.activeItem, 5);
|
||||
}
|
||||
|
||||
- if (--this.bl == 0 && !this.world.isClientSide && !this.activeItem.m()) {
|
||||
+
|
||||
- if (--this.bk == 0 && !this.world.isClientSide && !this.activeItem.m()) {
|
||||
+ // Paper start - lag compensate eating
|
||||
+ // we add 1 to the expected time to avoid lag compensating when we should not
|
||||
+ boolean shouldLagCompensate
|
||||
+ = this.activeItem.getItem().isFood() && this.eatStartTime != -1 && (System.nanoTime() - this.eatStartTime) > ((1 + this.totalEatTimeTicks) * 50 * (1000 * 1000));
|
||||
+ if ((--this.bl == 0 || shouldLagCompensate) && !this.world.isClientSide && !this.activeItem.m()) {
|
||||
+ if ((--this.bk == 0 || shouldLagCompensate) && !this.world.isClientSide && !this.activeItem.m()) {
|
||||
+ this.setEatTimeTicks(0);
|
||||
+ // Paper end
|
||||
this.q();
|
||||
this.s();
|
||||
}
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
|
||||
if (!itemstack.isEmpty() && !this.isHandRaised() || forceUpdate) { // Paper use override flag
|
||||
this.activeItem = itemstack;
|
||||
- this.bl = itemstack.k();
|
||||
- this.bk = itemstack.k();
|
||||
+ // Paper start - lag compensate eating
|
||||
+ this.bl = this.totalEatTimeTicks = itemstack.k();
|
||||
+ this.bk = this.totalEatTimeTicks = itemstack.k();
|
||||
+ this.eatStartTime = System.nanoTime();
|
||||
+ // Paper end
|
||||
if (!this.world.isClientSide) {
|
||||
|
@ -61,10 +61,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
}
|
||||
} else if (!this.isHandRaised() && !this.activeItem.isEmpty()) {
|
||||
this.activeItem = ItemStack.a;
|
||||
- this.bl = 0;
|
||||
this.activeItem = ItemStack.b;
|
||||
- this.bk = 0;
|
||||
+ // Paper start - lag compensate eating
|
||||
+ this.bl = this.totalEatTimeTicks = 0;
|
||||
+ this.bk = this.totalEatTimeTicks = 0;
|
||||
+ this.eatStartTime = -1L;
|
||||
+ // Paper end
|
||||
}
|
||||
|
@ -73,10 +73,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
}
|
||||
|
||||
this.activeItem = ItemStack.a;
|
||||
- this.bl = 0;
|
||||
this.activeItem = ItemStack.b;
|
||||
- this.bk = 0;
|
||||
+ // Paper start - lag compensate eating
|
||||
+ this.bl = this.totalEatTimeTicks = 0;
|
||||
+ this.bk = this.totalEatTimeTicks = 0;
|
||||
+ this.eatStartTime = -1L;
|
||||
+ // Paper end
|
||||
}
|
||||
|
|
|
@ -403,12 +403,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
private String motd;
|
||||
private int F;
|
||||
private int G;
|
||||
private int H;
|
||||
- public final long[] f = new long[100];
|
||||
+ public final long[] f = new long[100]; public long[] getTickTimes() { return f; } // Paper - OBFHELPER
|
||||
- public final long[] h;
|
||||
+ public final long[] h; public long[] getTickTimes() { return h; } // Paper - OBFHELPER
|
||||
@Nullable
|
||||
private KeyPair I;
|
||||
private KeyPair H;
|
||||
@Nullable
|
||||
diff --git a/src/main/java/net/minecraft/server/ServerGUI.java b/src/main/java/net/minecraft/server/ServerGUI.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
|
|
@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
VoxelShape voxelshape1 = iblockdata1.getCollisionShape(this, blockposition);
|
||||
|
||||
if (VoxelShapes.c(voxelshape, voxelshape1, OperatorBoolean.NOT_SAME)) {
|
||||
|
@ -16,7 +16,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
Iterator iterator = this.navigators.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,21 +37,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public boolean antiXray;
|
||||
public EngineMode engineMode;
|
||||
public int maxChunkSectionIndex;
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||||
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
EnumCreatureType enumcreaturetype = entity.getEntityType().e();
|
||||
|
||||
if (enumcreaturetype != EnumCreatureType.MISC && this.getChunkProvider().b(entity)) {
|
||||
if (enumcreaturetype != EnumCreatureType.MISC) {
|
||||
+ // Paper start - Only count natural spawns
|
||||
+ if (!this.paperConfig.countAllMobsForSpawning &&
|
||||
+ !(entity.spawnReason == CreatureSpawnEvent.SpawnReason.NATURAL ||
|
||||
+ entity.spawnReason == CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
|
||||
+ if (!entity.world.paperConfig.countAllMobsForSpawning &&
|
||||
+ !(entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL ||
|
||||
+ entity.spawnReason == org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.CHUNK_GEN)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end
|
||||
object2intmap.mergeInt(enumcreaturetype, 1, Integer::sum);
|
||||
}
|
||||
}
|
||||
BlockPosition blockposition = entity.getChunkCoordinates();
|
||||
long j = ChunkCoordIntPair.pair(blockposition.getX() >> 4, blockposition.getZ() >> 4);
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
return new Throwable(entity + " Added to world at " + new java.util.Date());
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
+ // Paper start - optimise getPlayerByUUID
|
||||
+ @Nullable
|
||||
|
@ -39,6 +39,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
// Paper start - Asynchronous IO
|
||||
public final com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController poiDataController = new com.destroystokyo.paper.io.PaperFileIOThread.ChunkDataController() {
|
||||
@Override
|
||||
// Add env and gen to constructor, WorldData -> WorldDataServer
|
||||
public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor
|
||||
|
|
|
@ -113,7 +113,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ private final WorldServer world;
|
||||
+ private final Predicate<T> excludeFromScheduling;
|
||||
+ private final Function<T, MinecraftKey> getMinecraftKeyFrom;
|
||||
+ private final Function<MinecraftKey, T> getObjectFronMinecraftKey;
|
||||
+ //private final Function<MinecraftKey, T> getObjectFronMinecraftKey;
|
||||
+ private final Consumer<NextTickListEntry<T>> tickFunction;
|
||||
+
|
||||
+ private final co.aikar.timings.Timing timingCleanup; // Paper
|
||||
|
@ -156,12 +156,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+
|
||||
+ public PaperTickList(final WorldServer world, final Predicate<T> excludeFromScheduling, final Function<T, MinecraftKey> getMinecraftKeyFrom,
|
||||
+ final Function<MinecraftKey, T> getObjectFronMinecraftKey, final Consumer<NextTickListEntry<T>> tickFunction, final String timingsType) {
|
||||
+ super(world, excludeFromScheduling, getMinecraftKeyFrom, getObjectFronMinecraftKey, tickFunction, timingsType);
|
||||
+ final Consumer<NextTickListEntry<T>> tickFunction, final String timingsType) {
|
||||
+ super(world, excludeFromScheduling, getMinecraftKeyFrom, tickFunction, timingsType);
|
||||
+ this.world = world;
|
||||
+ this.excludeFromScheduling = excludeFromScheduling;
|
||||
+ this.getMinecraftKeyFrom = getMinecraftKeyFrom;
|
||||
+ this.getObjectFronMinecraftKey = getObjectFronMinecraftKey;
|
||||
+ this.tickFunction = tickFunction;
|
||||
+ this.timingCleanup = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Cleanup"); // Paper
|
||||
+ this.timingTicking = co.aikar.timings.WorldTimingsHandler.getTickList(world, timingsType + " - Ticking"); // Paper
|
||||
|
@ -521,10 +520,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ this.addToSchedule(entry);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void scheduleAll(final Stream<NextTickListEntry<T>> stream) {
|
||||
+ this.scheduleAll(stream.iterator());
|
||||
+ }
|
||||
+ public void scheduleAll(final Iterator<NextTickListEntry<T>> iterator) {
|
||||
+ while (iterator.hasNext()) {
|
||||
+ this.schedule(iterator.next());
|
||||
|
@ -886,7 +881,7 @@ diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/ja
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
|
||||
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition {
|
||||
return i == 0 && j == 0 && k == 0 ? this : new BlockPosition(this.getX() + i, this.getY() + j, this.getZ() + k);
|
||||
}
|
||||
|
||||
|
@ -909,9 +904,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end - rewrite ticklistserver
|
||||
+
|
||||
|
||||
public ChunkProviderServer(WorldServer worldserver, File file, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator<?> chunkgenerator, int i, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier) {
|
||||
public ChunkProviderServer(WorldServer worldserver, Convertable.ConversionSession convertable_conversionsession, DataFixer datafixer, DefinedStructureManager definedstructuremanager, Executor executor, ChunkGenerator chunkgenerator, int i, boolean flag, WorldLoadListener worldloadlistener, Supplier<WorldPersistentData> supplier) {
|
||||
this.world = worldserver;
|
||||
this.serverThreadQueue = new ChunkProviderServer.a(worldserver);
|
||||
diff --git a/src/main/java/net/minecraft/server/NextTickListEntry.java b/src/main/java/net/minecraft/server/NextTickListEntry.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/NextTickListEntry.java
|
||||
|
@ -1030,7 +1025,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
return this.d >= structureboundingbox.a && this.a <= structureboundingbox.d && this.f >= structureboundingbox.c && this.c <= structureboundingbox.f && this.e >= structureboundingbox.b && this.b <= structureboundingbox.e;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class StructureBoundingBox {
|
||||
return new StructureBoundingBox(this.a + i, this.b + j, this.c + k, this.d + i, this.e + j, this.f + k);
|
||||
this.a(baseblockposition.getX(), baseblockposition.getY(), baseblockposition.getZ());
|
||||
}
|
||||
|
||||
+ public final boolean hasPoint(BaseBlockPosition baseblockposition) { return this.b(baseblockposition); } // Paper - OBFHELPER
|
||||
|
@ -1062,17 +1057,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ public boolean isPendingTickThisTick(BlockPosition blockposition, T t0) {
|
||||
+ // Paper end
|
||||
return this.g.contains(new NextTickListEntry<>(blockposition, t0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void a(Stream<NextTickListEntry<T>> stream) {
|
||||
+ // Paper start - allow overriding
|
||||
+ this.scheduleAll(stream);
|
||||
+ }
|
||||
+ public void scheduleAll(Stream<NextTickListEntry<T>> stream) {
|
||||
+ // Paper end
|
||||
stream.forEach(this::a);
|
||||
return this.f.contains(new NextTickListEntry<>(blockposition, t0));
|
||||
}
|
||||
|
||||
public List<NextTickListEntry<T>> a(ChunkCoordIntPair chunkcoordintpair, boolean flag, boolean flag1) {
|
||||
|
@ -1119,11 +1104,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ // Paper end
|
||||
List<NextTickListEntry<T>> list = this.a(chunkcoordintpair, false, true);
|
||||
|
||||
return a(this.b, list, this.f.getTime());
|
||||
return a(this.b, list, this.e.getTime());
|
||||
}
|
||||
|
||||
+ public static <T> NBTTagList serialize(Function<T, MinecraftKey> function, Iterable<NextTickListEntry<T>> iterable, long i) { return TickListServer.a(function, iterable, i); } // Paper - OBFHELPER
|
||||
public static <T> NBTTagList a(Function<T, MinecraftKey> function, Iterable<NextTickListEntry<T>> iterable, long i) {
|
||||
private static <T> NBTTagList a(Function<T, MinecraftKey> function, Iterable<NextTickListEntry<T>> iterable, long i) {
|
||||
NBTTagList nbttaglist = new NBTTagList();
|
||||
Iterator iterator = iterable.iterator();
|
||||
@@ -0,0 +0,0 @@ public class TickListServer<T> implements TickList<T> {
|
||||
|
@ -1146,7 +1131,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ public void schedule(BlockPosition blockposition, T t0, int i, TickListPriority ticklistpriority) {
|
||||
+ // Paper end
|
||||
if (!this.a.test(t0)) {
|
||||
this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.f.getTime(), ticklistpriority));
|
||||
this.a(new NextTickListEntry<>(blockposition, t0, (long) i + this.e.getTime(), ticklistpriority));
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TickListServer<T> implements TickList<T> {
|
||||
}
|
||||
|
@ -1164,7 +1149,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
// Paper end
|
||||
|
||||
|
@ -1177,35 +1162,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end - rewrite ticklistserver
|
||||
+
|
||||
// Add env and gen to constructor
|
||||
public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
super(worlddata, dimensionmanager, executor, (world, worldprovider) -> { // Paper - pass executor down
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
this.pvpMode = minecraftserver.getPVP();
|
||||
worlddata.world = this;
|
||||
// Add env and gen to constructor, WorldData -> WorldDataServer
|
||||
public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
super(iworlddataserver, resourcekey, resourcekey1, dimensionmanager, minecraftserver::getMethodProfiler, false, flag, i, gen, env, executor); // Paper pass executor
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
convertable = convertable_conversionsession;
|
||||
uuid = WorldUUID.getUUID(convertable_conversionsession.folder.toFile());
|
||||
// CraftBukkit end
|
||||
- this.nextTickListBlock = new TickListServer<>(this, (block) -> {
|
||||
- return block == null || block.getBlockData().isAir();
|
||||
- }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings
|
||||
- }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings
|
||||
- this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> {
|
||||
- return fluidtype == null || fluidtype == FluidTypes.EMPTY;
|
||||
- }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings
|
||||
- }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings
|
||||
+ if (com.destroystokyo.paper.PaperConfig.useOptimizedTickList) {
|
||||
+ this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> { // Paper - optimise TickListServer
|
||||
+ this.nextTickListBlock = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (block) -> {
|
||||
+ return block == null || block.getBlockData().isAir();
|
||||
+ }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings
|
||||
+ this.nextTickListFluid = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (fluidtype) -> { // Paper - optimise TickListServer
|
||||
+ }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings
|
||||
+ this.nextTickListFluid = new com.destroystokyo.paper.server.ticklist.PaperTickList<>(this, (fluidtype) -> {
|
||||
+ return fluidtype == null || fluidtype == FluidTypes.EMPTY;
|
||||
+ }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings
|
||||
+ }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings
|
||||
+ } else {
|
||||
+ this.nextTickListBlock = new TickListServer<>(this, (block) -> { // Paper - optimise TickListServer
|
||||
+ this.nextTickListBlock = new TickListServer<>(this, (block) -> {
|
||||
+ return block == null || block.getBlockData().isAir();
|
||||
+ }, IRegistry.BLOCK::getKey, IRegistry.BLOCK::get, this::b, "Blocks"); // Paper - Timings
|
||||
+ this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> { // Paper - optimise TickListServer
|
||||
+ }, IRegistry.BLOCK::getKey, this::b, "Blocks"); // Paper - Timings
|
||||
+ this.nextTickListFluid = new TickListServer<>(this, (fluidtype) -> {
|
||||
+ return fluidtype == null || fluidtype == FluidTypes.EMPTY;
|
||||
+ }, IRegistry.FLUID::getKey, IRegistry.FLUID::get, this::a, "Fluids"); // Paper - Timings
|
||||
+ }, IRegistry.FLUID::getKey, this::a, "Fluids"); // Paper - Timings
|
||||
+ }
|
||||
+
|
||||
this.navigators = Sets.newHashSet();
|
||||
this.I = new ObjectLinkedOpenHashSet();
|
||||
this.dataManager = worldnbtstorage;
|
||||
this.L = new ObjectLinkedOpenHashSet();
|
||||
this.Q = flag1;
|
||||
|
|
|
@ -70,39 +70,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ return fastRandomBounded(this.next(32) & 0xFFFFFFFFL, bound);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/Block.java
|
||||
+++ b/src/main/java/net/minecraft/server/Block.java
|
||||
@@ -0,0 +0,0 @@ public class Block implements IMaterial {
|
||||
return iblockdata.d(iblockaccess, blockposition, EnumDirection.UP) && this.n < 14;
|
||||
}
|
||||
|
||||
- @Deprecated
|
||||
- public boolean d(IBlockData iblockdata) {
|
||||
+ public final boolean isAir(IBlockData iblockdata) { return this.d(iblockdata); } // Paper - OBFHELPER
|
||||
+ @Deprecated public boolean d(IBlockData iblockdata) { // Paper - OBFHELPER
|
||||
return false;
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockFluids.java b/src/main/java/net/minecraft/server/BlockFluids.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockFluids.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockFluids.java
|
||||
@@ -0,0 +0,0 @@ public class BlockFluids extends Block implements IFluidSource {
|
||||
|
||||
@Override
|
||||
public void b(IBlockData iblockdata, WorldServer worldserver, BlockPosition blockposition, Random random) {
|
||||
- worldserver.getFluid(blockposition).b(worldserver, blockposition, random);
|
||||
+ iblockdata.getFluid().b(worldserver, blockposition, random); // Paper - avoid getType call
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/BlockPosition.java b/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
+++ b/src/main/java/net/minecraft/server/BlockPosition.java
|
||||
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition implements MinecraftSeriali
|
||||
@@ -0,0 +0,0 @@ public class BlockPosition extends BaseBlockPosition {
|
||||
return this.d(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2));
|
||||
}
|
||||
|
||||
|
@ -119,9 +91,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
|
||||
- @Override
|
||||
- public int a(HeightMap.Type heightmap_type, int i, int j) {
|
||||
+ public int getHighestBlockY(HeightMap.Type heightmap_type, int i, int j) { return this.a(heightmap_type, i, j) + 1; } // Paper - sort of an obfhelper, but without -1
|
||||
+ @Override public int a(HeightMap.Type heightmap_type, int i, int j) { // Paper
|
||||
- public int getHighestBlock(HeightMap.Type heightmap_type, int i, int j) {
|
||||
+ public final int getHighestBlockY(HeightMap.Type heightmap_type, int i, int j) { return this.getHighestBlock(heightmap_type, i, j) + 1; } // Paper - sort of an obfhelper, but without -1
|
||||
+ @Override public int getHighestBlock(HeightMap.Type heightmap_type, int i, int j) { // Paper
|
||||
return ((HeightMap) this.heightMap.get(heightmap_type)).a(i & 15, j & 15) - 1;
|
||||
}
|
||||
|
||||
|
@ -148,7 +120,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public ChunkSection(int i, IChunkAccess chunk, World world, boolean initializeBlocks) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkSection {
|
||||
--this.nonEmptyBlockCount;
|
||||
if (iblockdata1.q()) {
|
||||
if (iblockdata1.isTicking()) {
|
||||
--this.tickingBlockCount;
|
||||
+ // Paper start
|
||||
+ this.tickingList.remove(i, j, k);
|
||||
|
@ -158,7 +130,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
@@ -0,0 +0,0 @@ public class ChunkSection {
|
||||
++this.nonEmptyBlockCount;
|
||||
if (iblockdata.q()) {
|
||||
if (iblockdata.isTicking()) {
|
||||
++this.tickingBlockCount;
|
||||
+ // Paper start
|
||||
+ this.tickingList.add(i, j, k, iblockdata);
|
||||
|
@ -182,10 +154,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
if (!iblockdata.isAir()) {
|
||||
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); // Paper
|
||||
if (iblockdata.q()) {
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
||||
if (iblockdata.isTicking()) {
|
||||
- this.tickingBlockCount = (short) (this.tickingBlockCount + i);
|
||||
+ this.tickingBlockCount = (short) (this.tickingBlockCount + 1); // Paper
|
||||
+ this.tickingBlockCount = (short) (this.tickingBlockCount + 1);
|
||||
+ // Paper start
|
||||
+ this.tickingList.add(location, iblockdata);
|
||||
+ // Paper end
|
||||
|
@ -194,10 +166,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
if (!fluid.isEmpty()) {
|
||||
- this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + i);
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1); // Paper
|
||||
if (fluid.h()) {
|
||||
+ this.nonEmptyBlockCount = (short) (this.nonEmptyBlockCount + 1);
|
||||
if (fluid.f()) {
|
||||
- this.e = (short) (this.e + i);
|
||||
+ this.e = (short) (this.e + 1); // Paper
|
||||
+ this.e = (short) (this.e + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,41 +178,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/DataBits.java
|
||||
+++ b/src/main/java/net/minecraft/server/DataBits.java
|
||||
@@ -0,0 +0,0 @@ public class DataBits {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public final void forEach(DataBitConsumer consumer) {
|
||||
+ // Note: copied from above
|
||||
+ int i = this.a.length;
|
||||
+ int i = 0;
|
||||
+ long[] along = this.b;
|
||||
+ int j = along.length;
|
||||
+
|
||||
+ if (i != 0) {
|
||||
+ int j = 0;
|
||||
+ long k = this.a[0];
|
||||
+ long l = i > 1 ? this.a[1] : 0L;
|
||||
+ for (int k = 0; k < j; ++k) {
|
||||
+ long l = along[k];
|
||||
+
|
||||
+ for (int i1 = 0; i1 < this.d; ++i1) {
|
||||
+ int j1 = i1 * this.b;
|
||||
+ int k1 = j1 >> 6;
|
||||
+ int l1 = (i1 + 1) * this.b - 1 >> 6;
|
||||
+ int i2 = j1 ^ k1 << 6;
|
||||
+
|
||||
+ if (k1 != j) {
|
||||
+ k = l;
|
||||
+ l = k1 + 1 < i ? this.a[k1 + 1] : 0L;
|
||||
+ j = k1;
|
||||
+ }
|
||||
+
|
||||
+ if (k1 == l1) {
|
||||
+ consumer.accept(i1, (int) (k >>> i2 & this.c));
|
||||
+ } else {
|
||||
+ int j2 = 64 - i2;
|
||||
+
|
||||
+ consumer.accept(i1, (int) ((k >>> i2 | l << j2) & this.c));
|
||||
+ for (int i1 = 0; i1 < this.f; ++i1) {
|
||||
+ consumer.accept(i, (int) (l & this.d));
|
||||
+ l >>= this.c;
|
||||
+ ++i;
|
||||
+ if (i >= this.e) {
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
|
@ -277,72 +235,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+++ b/src/main/java/net/minecraft/server/EntityTurtle.java
|
||||
@@ -0,0 +0,0 @@ public class EntityTurtle extends EntityAnimal {
|
||||
|
||||
public final void setHome(BlockPosition pos) { g(pos); } // Paper - OBFHELPER
|
||||
public void g(BlockPosition blockposition) {
|
||||
- this.datawatcher.set(EntityTurtle.bx, blockposition);
|
||||
+ this.datawatcher.set(EntityTurtle.bx, blockposition.immutableCopy()); // Paper - make sure home position can't change
|
||||
public final void setHome(BlockPosition pos) { setHomePos(pos); } // Paper - OBFHELPER
|
||||
public void setHomePos(BlockPosition blockposition) {
|
||||
- this.datawatcher.set(EntityTurtle.bw, blockposition);
|
||||
+ this.datawatcher.set(EntityTurtle.bw, blockposition.immutableCopy()); // Paper - called with mutablepos...
|
||||
}
|
||||
|
||||
public final BlockPosition getHome() { return this.es(); } // Paper - OBFHELPER
|
||||
diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/IBlockData.java
|
||||
+++ b/src/main/java/net/minecraft/server/IBlockData.java
|
||||
@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
|
||||
private IBlockData.a c;
|
||||
private final int d;
|
||||
private final boolean e;
|
||||
+ private final boolean isAir; // Paper
|
||||
+ private final boolean isTicking; // Paper
|
||||
|
||||
public IBlockData(Block block, ImmutableMap<IBlockState<?>, Comparable<?>> immutablemap) {
|
||||
super(block, immutablemap);
|
||||
this.d = block.a(this);
|
||||
this.e = block.o(this);
|
||||
+ this.isAir = this.getBlock().isAir(this); // Paper
|
||||
+ this.isTicking = this.getBlock().isTicking(this); // Paper
|
||||
}
|
||||
|
||||
public void c() {
|
||||
@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
|
||||
return this.d;
|
||||
}
|
||||
|
||||
- public boolean isAir() {
|
||||
- return this.getBlock().d(this);
|
||||
+ public final boolean isAir() { // Paper - compile fail if the impl changes
|
||||
+ return this.isAir; // Paper - improve inlining of isAir
|
||||
}
|
||||
|
||||
public MaterialMapColor c(IBlockAccess iblockaccess, BlockPosition blockposition) {
|
||||
@@ -0,0 +0,0 @@ public class IBlockData extends BlockDataAbstract<Block, IBlockData> implements
|
||||
return this.getBlock().a(tag);
|
||||
}
|
||||
|
||||
+ private Fluid fluidData; // Paper - cache result
|
||||
public Fluid getFluid() {
|
||||
- return this.getBlock().a_(this);
|
||||
+ // Paper start
|
||||
+ // This can't be done during the constructor, order issues
|
||||
+ if (this.fluidData != null) {
|
||||
+ return this.fluidData;
|
||||
+ }
|
||||
+ return this.fluidData = this.getBlock().a_(this);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public boolean q() {
|
||||
- return this.getBlock().isTicking(this);
|
||||
+ return this.isTicking; // Paper
|
||||
}
|
||||
|
||||
public final SoundEffectType getStepSound() { return this.r(); } // Paper - OBFHELPER
|
||||
// TODO Paper: Obf helpers here can prolly be removed? check that no newer patches use them
|
||||
public final BlockPosition getHome() { return this.getHomePos(); } // Paper - OBFHELPER
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
public abstract TagRegistry t();
|
||||
public abstract TagRegistry p();
|
||||
|
||||
public BlockPosition a(int i, int j, int k, int l) {
|
||||
+ // Paper start - allow use of mutable pos
|
||||
|
@ -350,11 +255,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ this.getRandomBlockPosition(i, j, k, l, ret);
|
||||
+ return ret.immutableCopy();
|
||||
+ }
|
||||
+
|
||||
+ public final BlockPosition.MutableBlockPosition getRandomBlockPosition(int i, int j, int k, int l, BlockPosition.MutableBlockPosition out) {
|
||||
+ // Paper end
|
||||
this.i = this.i * 3 + 1013904223;
|
||||
int i1 = this.i >> 2;
|
||||
this.n = this.n * 3 + 1013904223;
|
||||
int i1 = this.n >> 2;
|
||||
|
||||
- return new BlockPosition(i + (i1 & 15), j + (i1 >> 16 & l), k + (i1 >> 8 & 15));
|
||||
+ out.setValues(i + (i1 & 15), j + (i1 >> 16 & l), k + (i1 >> 8 & 15)); // Paper - change to setValues call
|
||||
|
@ -366,7 +270,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -380,21 +284,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
ChunkCoordIntPair chunkcoordintpair = chunk.getPos();
|
||||
boolean flag = this.isRaining();
|
||||
int j = chunkcoordintpair.d();
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
GameProfilerFiller gameprofilerfiller = this.getMethodProfiler();
|
||||
|
||||
gameprofilerfiller.enter("thunder");
|
||||
- BlockPosition blockposition;
|
||||
+ final BlockPosition.MutableBlockPosition blockposition = this.chunkTickMutablePosition; // Paper - use mutable to reduce allocation rate, final to force compile fail on change
|
||||
|
||||
- if (!this.paperConfig.disableThunder && flag && this.U() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder
|
||||
if (!this.paperConfig.disableThunder && flag && this.T() && this.random.nextInt(100000) == 0) { // Paper - Disable thunder
|
||||
- blockposition = this.a(this.a(j, 0, k, 15));
|
||||
+ if (!this.paperConfig.disableThunder && flag && this.U() && this.randomTickRandom.nextInt(100000) == 0) { // Paper - Disable thunder // Paper - optimise random ticking
|
||||
+ blockposition.setValues(this.a(this.getRandomBlockPosition(j, 0, k, 15, blockposition))); // Paper
|
||||
+ blockposition.setValues(this.a(this.a(j, 0, k, 15))); // Paper
|
||||
if (this.isRainingAt(blockposition)) {
|
||||
DifficultyDamageScaler difficultydamagescaler = this.getDamageScaler(blockposition);
|
||||
boolean flag1 = this.getGameRules().getBoolean(GameRules.DO_MOB_SPAWNING) && this.random.nextDouble() < (double) difficultydamagescaler.b() * paperConfig.skeleHorseSpawnChance; // Paper
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
|
||||
gameprofilerfiller.exitEnter("iceandsnow");
|
||||
|
@ -469,10 +372,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ continue;
|
||||
+ }
|
||||
|
||||
- if (iblockdata.q()) {
|
||||
- iblockdata.getBlock().randomTick = true; // Paper - fix MC-113809
|
||||
- if (iblockdata.isTicking()) {
|
||||
- iblockdata.b(this, blockposition2, this.random);
|
||||
- iblockdata.getBlock().randomTick = false; // Paper - fix MC-113809
|
||||
- }
|
||||
+ long raw = section.tickingList.getRaw(index);
|
||||
+ int location = com.destroystokyo.paper.util.maplist.IBlockDataList.getLocationFromRaw(raw);
|
||||
|
@ -484,12 +385,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ BlockPosition blockposition2 = blockposition.setValues(j + randomX, randomY, k + randomZ);
|
||||
+ IBlockData iblockdata = com.destroystokyo.paper.util.maplist.IBlockDataList.getBlockDataFromRaw(raw);
|
||||
|
||||
- if (fluid.h()) {
|
||||
- if (fluid.f()) {
|
||||
- fluid.b(this, blockposition2, this.random);
|
||||
- }
|
||||
+ iblockdata.getBlock().randomTick = true; // Paper - fix MC-113809
|
||||
+ iblockdata.b(this, blockposition2, this.randomTickRandom);
|
||||
+ iblockdata.getBlock().randomTick = false; // Paper - fix MC-113809
|
||||
|
||||
- gameprofilerfiller.exit();
|
||||
- }
|
||||
|
|
|
@ -43,14 +43,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
World getWorld();
|
||||
+ default BlockPosition getBlockPosition() { return new BlockPosition(getX(), getY(), getZ()); } // Paper
|
||||
|
||||
- double x();
|
||||
+ double x(); default double getX() { return this.x(); } // Paper - OBFHELPER
|
||||
|
||||
- double z();
|
||||
+ double z();default double getX() { return z(); } // Paper - OBFHELPER
|
||||
+ double z(); default double getY() { return this.z(); } // Paper - OBFHELPER
|
||||
|
||||
- double A();
|
||||
+ double A();default double getY() { return A(); } // Paper - OBFHELPER
|
||||
|
||||
- double B();
|
||||
+ double B();default double getZ() { return B(); } // Paper - OBFHELPER
|
||||
+ double A(); default double getZ() { return this.A(); } // Paper - OBFHELPER
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ItemStack.java b/src/main/java/net/minecraft/server/ItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
@ -65,25 +65,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ public ItemStack cloneItemStack() { return cloneItemStack(false); } // Paper
|
||||
+ public ItemStack cloneItemStack(boolean origItem) { // Paper
|
||||
+ if (!origItem && this.isEmpty()) { // Paper
|
||||
return ItemStack.a;
|
||||
return ItemStack.b;
|
||||
} else {
|
||||
- ItemStack itemstack = new ItemStack(this.getItem(), this.count);
|
||||
+ ItemStack itemstack = new ItemStack(origItem ? this.item : this.getItem(), this.count); // Paper
|
||||
|
||||
itemstack.d(this.C());
|
||||
itemstack.d(this.D());
|
||||
if (this.tag != null) {
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
while (iterator.hasNext()) {
|
||||
WorldServer worldserver = (WorldServer) iterator.next();
|
||||
|
||||
worldserver.hasPhysicsEvent = org.bukkit.event.block.BlockPhysicsEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper
|
||||
+ TileEntityHopper.skipHopperEvents = worldserver.paperConfig.disableHopperMoveEvents || org.bukkit.event.inventory.InventoryMoveItemEvent.getHandlerList().getRegisteredListeners().length == 0; // Paper
|
||||
if (true || worldserver.worldProvider.getDimensionManager() == DimensionManager.OVERWORLD || this.getAllowNether()) { // CraftBukkit
|
||||
this.methodProfiler.a(() -> {
|
||||
return worldserver.getWorldData().getName() + " " + IRegistry.DIMENSION_TYPE.getKey(worldserver.worldProvider.getDimensionManager());
|
||||
|
||||
this.methodProfiler.a(() -> {
|
||||
return worldserver + " " + worldserver.getDimensionKey().a();
|
||||
diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/TileEntity.java
|
||||
|
@ -266,8 +266,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
private boolean j() {
|
||||
IInventory iinventory = this.k();
|
||||
private boolean k() {
|
||||
IInventory iinventory = this.l();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
||||
if (this.b(iinventory, enumdirection)) {
|
||||
|
@ -412,15 +412,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ IGNORE_TILE_UPDATES = true; // Paper
|
||||
iinventory1.setItem(i, itemstack);
|
||||
+ IGNORE_TILE_UPDATES = false; // Paper
|
||||
itemstack = ItemStack.a;
|
||||
itemstack = ItemStack.b;
|
||||
flag = true;
|
||||
} else if (a(itemstack1, itemstack)) {
|
||||
@@ -0,0 +0,0 @@ public class TileEntityHopper extends TileEntityLootable implements IHopper, ITi
|
||||
}
|
||||
|
||||
public static List<EntityItem> c(IHopper ihopper) {
|
||||
- return (List) ihopper.P_().d().stream().flatMap((axisalignedbb) -> {
|
||||
- return ihopper.getWorld().a(EntityItem.class, axisalignedbb.d(ihopper.z() - 0.5D, ihopper.A() - 0.5D, ihopper.B() - 0.5D), IEntitySelector.a).stream();
|
||||
- return (List) ihopper.ac_().d().stream().flatMap((axisalignedbb) -> {
|
||||
- return ihopper.getWorld().a(EntityItem.class, axisalignedbb.d(ihopper.x() - 0.5D, ihopper.z() - 0.5D, ihopper.A() - 0.5D), IEntitySelector.a).stream();
|
||||
- }).collect(Collectors.toList());
|
||||
+ // Paper start - Optimize item suck in. remove streams, restore 1.12 checks. Seriously checking the bowl?!
|
||||
+ World world = ihopper.getWorld();
|
||||
|
|
|
@ -14,6 +14,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
IBlockData iblockdata = this.world.getType(blockposition);
|
||||
- Fluid fluid = this.world.getFluid(blockposition);
|
||||
+ Fluid fluid = iblockdata.getFluid(); // Paper
|
||||
Optional<Float> optional = this.k.a(this, this.world, blockposition, iblockdata, fluid);
|
||||
|
||||
if (!iblockdata.isAir() || !fluid.isEmpty()) {
|
||||
float f2 = Math.max(iblockdata.getBlock().getDurability(), fluid.k());
|
||||
if (optional.isPresent()) {
|
||||
|
|
|
@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+++ b/src/main/java/net/minecraft/server/MobSpawnerPatrol.java
|
||||
@@ -0,0 +0,0 @@ import java.util.Random;
|
||||
|
||||
public class MobSpawnerPatrol {
|
||||
public class MobSpawnerPatrol implements MobSpawner {
|
||||
|
||||
+ private int getSpawnDelay() { return a; } // Paper - OBFHELPER
|
||||
+ private void setSpawnDelay(int spawnDelay) { this.a = spawnDelay; } // Paper - OBFHELPER
|
||||
|
@ -61,13 +61,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
public MobSpawnerPatrol() {}
|
||||
|
||||
@Override
|
||||
public int a(WorldServer worldserver, boolean flag, boolean flag1) {
|
||||
- if (worldserver.paperConfig.disablePillagerPatrols) return 0; // Paper
|
||||
+ if (worldserver.paperConfig.disablePillagerPatrols || worldserver.paperConfig.patrolSpawnChance == 0) return 0; // Paper
|
||||
if (!flag) {
|
||||
return 0;
|
||||
} else if (!worldserver.getGameRules().getBoolean(GameRules.DO_PATROL_SPAWNING)) {
|
||||
@@ -0,0 +0,0 @@ public class MobSpawnerPatrol {
|
||||
@@ -0,0 +0,0 @@ public class MobSpawnerPatrol implements MobSpawner {
|
||||
} else {
|
||||
Random random = worldserver.random;
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
||||
|
||||
this.releaseShoulderEntities();
|
||||
this.eW();
|
||||
}
|
||||
// SPIGOT-5478 must be called manually now
|
||||
- this.dropExperience();
|
||||
+ if (event.shouldDropExperience()) this.dropExperience(); // Paper - tie to event
|
||||
|
|
|
@ -49,7 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+
|
||||
+
|
||||
}
|
||||
world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemEgg.i.nextFloat() * 0.4F + 0.8F)); // CraftBukkit - from above
|
||||
world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemEgg.RANDOM.nextFloat() * 0.4F + 0.8F)); // CraftBukkit - from above
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
entityhuman.b(StatisticList.ITEM_USED.b(this));
|
||||
|
@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultWrapper.success(itemstack);
|
||||
return InteractionResultWrapper.a(itemstack, world.s_());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ItemEnderPearl.java b/src/main/java/net/minecraft/server/ItemEnderPearl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
@ -91,7 +91,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
}
|
||||
|
||||
- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.i.nextFloat() * 0.4F + 0.8F));
|
||||
- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
- entityhuman.getCooldownTracker().setCooldown(this, 20);
|
||||
- // CraftBukkit end
|
||||
-
|
||||
|
@ -100,7 +100,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- itemstack.subtract(1);
|
||||
- }
|
||||
+ // Paper start - moved up
|
||||
+// world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.i.nextFloat() * 0.4F + 0.8F));
|
||||
+// world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_ENDER_PEARL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemEnderPearl.RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+// entityhuman.getCooldownTracker().setCooldown(this, 20);
|
||||
+// // CraftBukkit end
|
||||
+//
|
||||
|
@ -108,9 +108,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+// if (!entityhuman.abilities.canInstantlyBuild) {
|
||||
+// itemstack.subtract(1);
|
||||
+// }
|
||||
+ // Paper end
|
||||
+ // Paper end - moved up
|
||||
|
||||
return InteractionResultWrapper.success(itemstack);
|
||||
return InteractionResultWrapper.a(itemstack, world.s_());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ItemExpBottle.java b/src/main/java/net/minecraft/server/ItemExpBottle.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
@ -120,8 +120,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public InteractionResultWrapper<ItemStack> a(World world, EntityHuman entityhuman, EnumHand enumhand) {
|
||||
ItemStack itemstack = entityhuman.b(enumhand);
|
||||
|
||||
- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.i.nextFloat() * 0.4F + 0.8F));
|
||||
+// world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.i.nextFloat() * 0.4F + 0.8F)); // Paper - moved down
|
||||
- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ //world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_EXPERIENCE_BOTTLE_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemExpBottle.RANDOM.nextFloat() * 0.4F + 0.8F)); // Paper - moved down
|
||||
if (!world.isClientSide) {
|
||||
EntityThrownExpBottle entitythrownexpbottle = new EntityThrownExpBottle(world, entityhuman);
|
||||
|
||||
|
@ -155,7 +155,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultWrapper.success(itemstack);
|
||||
return InteractionResultWrapper.a(itemstack, world.s_());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ItemLingeringPotion.java b/src/main/java/net/minecraft/server/ItemLingeringPotion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
@ -165,12 +165,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
@Override
|
||||
public InteractionResultWrapper<ItemStack> a(World world, EntityHuman entityhuman, EnumHand enumhand) {
|
||||
- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.i.nextFloat() * 0.4F + 0.8F));
|
||||
- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
- return super.a(world, entityhuman, enumhand);
|
||||
+ // Paper start
|
||||
+ InteractionResultWrapper<ItemStack> wrapper = super.a(world, entityhuman, enumhand);
|
||||
+ if (wrapper.getResult() != EnumInteractionResult.FAIL)
|
||||
+ world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.i.nextFloat() * 0.4F + 0.8F));
|
||||
+ if (wrapper.getResult() != EnumInteractionResult.FAIL) {
|
||||
+ world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_LINGERING_POTION_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemLingeringPotion.RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end
|
||||
}
|
||||
|
@ -210,7 +211,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultWrapper.success(itemstack);
|
||||
return InteractionResultWrapper.a(itemstack, world.s_());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ItemSnowball.java b/src/main/java/net/minecraft/server/ItemSnowball.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
|
@ -226,30 +227,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addEntity(entitysnowball)) {
|
||||
+ if (event.shouldConsume() && !entityhuman.abilities.canInstantlyBuild) {
|
||||
+ // Paper end
|
||||
itemstack.subtract(1);
|
||||
+ } else if (entityhuman instanceof EntityPlayer) {
|
||||
+ ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory();
|
||||
+ } else if (entityhuman instanceof EntityPlayer) { // Paper
|
||||
+ ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // Paper
|
||||
}
|
||||
|
||||
- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemSnowball.i.nextFloat() * 0.4F + 0.8F));
|
||||
world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (ItemSnowball.RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
- } else if (entityhuman instanceof EntityPlayer) {
|
||||
- ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory();
|
||||
+ world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ entityhuman.b(StatisticList.ITEM_USED.b(this));
|
||||
+ } else {
|
||||
+ if (entityhuman instanceof EntityPlayer) {
|
||||
+ ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+ return new InteractionResultWrapper<ItemStack>(EnumInteractionResult.FAIL, itemstack);
|
||||
+ } else { // Paper
|
||||
+ if (entityhuman instanceof EntityPlayer) ((EntityPlayer) entityhuman).getBukkitEntity().updateInventory(); // Paper
|
||||
+ return new InteractionResultWrapper<ItemStack>(EnumInteractionResult.FAIL, itemstack); // Paper
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
- entityhuman.b(StatisticList.ITEM_USED.b(this));
|
||||
+// entityhuman.b(StatisticList.ITEM_USED.b(this)); // Paper - moved up
|
||||
// CraftBukkit start - moved up
|
||||
/*
|
||||
if (!entityhuman.abilities.canInstantlyBuild) {
|
||||
diff --git a/src/main/java/net/minecraft/server/ItemSplashPotion.java b/src/main/java/net/minecraft/server/ItemSplashPotion.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ItemSplashPotion.java
|
||||
|
@ -258,12 +250,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
@Override
|
||||
public InteractionResultWrapper<ItemStack> a(World world, EntityHuman entityhuman, EnumHand enumhand) {
|
||||
- world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.i.nextFloat() * 0.4F + 0.8F));
|
||||
- return super.a(world, entityhuman, enumhand);
|
||||
+ // Paper start
|
||||
+ InteractionResultWrapper<ItemStack> wrapper = super.a(world, entityhuman, enumhand);
|
||||
+ if (wrapper.getResult() != EnumInteractionResult.FAIL)
|
||||
+ world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.i.nextFloat() * 0.4F + 0.8F));
|
||||
+ if (wrapper.getResult() != EnumInteractionResult.FAIL) {
|
||||
world.playSound((EntityHuman) null, entityhuman.locX(), entityhuman.locY(), entityhuman.locZ(), SoundEffects.ENTITY_SPLASH_POTION_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (ItemSplashPotion.RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
- return super.a(world, entityhuman, enumhand);
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end
|
||||
}
|
||||
|
|
|
@ -23,13 +23,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end
|
||||
if (!(entity instanceof EntityComplexPart)) {
|
||||
if (!(entity instanceof EntityLightning)) {
|
||||
EntityTypes<?> entitytypes = entity.getEntityType();
|
||||
EntityTypes<?> entitytypes = entity.getEntityType();
|
||||
int i = entitytypes.getChunkRange() * 16;
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
// CraftBukkit start - SPIGOT-5278
|
||||
if (entity instanceof EntityDrowned) {
|
||||
this.navigators.add(((EntityDrowned) entity).navigationWater);
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
this.navigators.add(((EntityInsentient) entity).getNavigation());
|
||||
}
|
||||
entity.valid = true; // CraftBukkit
|
||||
|
|
|
@ -8,7 +8,7 @@ diff --git a/src/main/java/net/minecraft/server/EntityBee.java b/src/main/java/n
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityBee.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityBee.java
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements EntityBird {
|
||||
@@ -0,0 +0,0 @@ public class EntityBee extends EntityAnimal implements IEntityAngerable, EntityB
|
||||
if (!this.hasHivePos()) {
|
||||
return false;
|
||||
} else {
|
||||
|
|
|
@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityLiving.java
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
this.datawatcher.set(EntityLiving.ao, (byte) j);
|
||||
this.datawatcher.set(EntityLiving.an, (byte) j);
|
||||
}
|
||||
|
||||
- public void c(EnumHand enumhand) {
|
||||
|
@ -22,10 +22,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- if (!itemstack.isEmpty() && !this.isHandRaised()) {
|
||||
+ if (!itemstack.isEmpty() && !this.isHandRaised() || forceUpdate) { // Paper use override flag
|
||||
this.activeItem = itemstack;
|
||||
this.bl = itemstack.k();
|
||||
this.bk = itemstack.k();
|
||||
if (!this.world.isClientSide) {
|
||||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
this.clearActiveItem();
|
||||
this.releaseActiveItem();
|
||||
} else {
|
||||
if (!this.activeItem.isEmpty() && this.isHandRaised()) {
|
||||
+ this.updateActiveItem(this.getRaisedHand(), true); // Paper
|
||||
|
@ -35,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
@@ -0,0 +0,0 @@ public abstract class EntityLiving extends Entity {
|
||||
this.a(this.getRaisedHand(), itemstack);
|
||||
// CraftBukkit end
|
||||
this.dH();
|
||||
this.clearActiveItem();
|
||||
- // Paper start - if the replacement is anything but the default, update the client inventory
|
||||
- if (this instanceof EntityPlayer && !com.google.common.base.Objects.equal(defaultReplacement, itemstack)) {
|
||||
+ // Paper start
|
||||
|
|
|
@ -9,12 +9,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/BehaviorSleep.java
|
||||
+++ b/src/main/java/net/minecraft/server/BehaviorSleep.java
|
||||
@@ -0,0 +0,0 @@ public class BehaviorSleep extends Behavior<EntityLiving> {
|
||||
if (optional.isPresent() && worldserver.getTime() - ((MinecraftSerializableLong) optional.get()).a() < 100L) {
|
||||
return false;
|
||||
} else {
|
||||
- IBlockData iblockdata = worldserver.getType(globalpos.getBlockPosition());
|
||||
+ IBlockData iblockdata = worldserver.getTypeIfLoaded(globalpos.getBlockPosition()); // Paper
|
||||
+ if(iblockdata == null) return false; // Paper
|
||||
|
||||
return globalpos.getBlockPosition().a((IPosition) entityliving.getPositionVector(), 2.0D) && iblockdata.getBlock().a(TagsBlock.BEDS) && !(Boolean) iblockdata.get(BlockBed.OCCUPIED);
|
||||
}
|
||||
}
|
||||
|
||||
- IBlockData iblockdata = worldserver.getType(globalpos.getBlockPosition());
|
||||
+ IBlockData iblockdata = worldserver.getTypeIfLoaded(globalpos.getBlockPosition()); // Paper
|
||||
+ if (iblockdata == null) { return false; } // Paper
|
||||
|
||||
return globalpos.getBlockPosition().a((IPosition) entityliving.getPositionVector(), 2.0D) && iblockdata.getBlock().a((Tag) TagsBlock.BEDS) && !(Boolean) iblockdata.get(BlockBed.OCCUPIED);
|
||||
}
|
||||
|
|
|
@ -267,7 +267,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ final ThrowableWithEquals other = (ThrowableWithEquals)obj;
|
||||
+ final StackTraceElement[] otherStackTrace = other.stacktrace;
|
||||
+
|
||||
+ if (this.stacktrace.length != otherStackTrace.length) {
|
||||
+ if (this.stacktrace.length != otherStackTrace.length || this.hash != other.hash) {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
|
@ -305,7 +305,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
for (int i1 = i; i1 <= j; ++i1) {
|
||||
for (int j1 = k; j1 <= l; ++j1) {
|
||||
- Chunk chunk = this.getChunkProvider().getChunkAt(i1, j1, false);
|
||||
- Chunk chunk = ichunkprovider.getChunkAt(i1, j1, false);
|
||||
+ Chunk chunk = (Chunk)this.getChunkIfLoadedImmediately(i1, j1); // Paper
|
||||
|
||||
if (chunk != null) {
|
||||
|
@ -332,7 +332,7 @@ diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
};
|
||||
public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager;
|
||||
// Paper end
|
||||
|
@ -343,5 +343,5 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ }
|
||||
+ // Paper end
|
||||
|
||||
// Add env and gen to constructor
|
||||
public WorldServer(MinecraftServer minecraftserver, Executor executor, WorldNBTStorage worldnbtstorage, WorldData worlddata, DimensionManager dimensionmanager, GameProfilerFiller gameprofilerfiller, WorldLoadListener worldloadlistener, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
// Add env and gen to constructor, WorldData -> WorldDataServer
|
||||
public WorldServer(MinecraftServer minecraftserver, Executor executor, Convertable.ConversionSession convertable_conversionsession, IWorldDataServer iworlddataserver, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, WorldLoadListener worldloadlistener, ChunkGenerator chunkgenerator, boolean flag, long i, List<MobSpawner> list, boolean flag1, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) {
|
||||
|
|
|
@ -1,110 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Phoenix616 <mail@moep.tv>
|
||||
Date: Mon, 13 Jan 2020 15:40:32 +0100
|
||||
Subject: [PATCH] Seed based feature search
|
||||
|
||||
This fixes the issue where the server will load surrounding chunks up to
|
||||
a radius of 100 chunks in order to search for features e.g. when running
|
||||
the /locate command or for treasure maps (issue #2312).
|
||||
This is done by using the same seed checking functionality that is used
|
||||
by the server when generating these features before actually attempting
|
||||
to load the chunk to check if a feature is available in it.
|
||||
|
||||
The only downside of this is that it breaks once the seed or generator
|
||||
changes but this should usually not happen. A config option to disable
|
||||
this improvement is added though in case that should ever be necessary.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
|
||||
}
|
||||
}
|
||||
|
||||
+ public boolean seedBasedFeatureSearch = true;
|
||||
+ private void seedBasedFeatureSearch() {
|
||||
+ seedBasedFeatureSearch = getBoolean("seed-based-feature-search", seedBasedFeatureSearch);
|
||||
+ log("Feature search is based on seed: " + seedBasedFeatureSearch);
|
||||
+ }
|
||||
+
|
||||
public int maxCollisionsPerEntity;
|
||||
private void maxEntityCollision() {
|
||||
maxCollisionsPerEntity = getInt( "max-entity-collisions", this.spigotConfig.getInt("max-entity-collisions", 8) );
|
||||
diff --git a/src/main/java/net/minecraft/server/BiomeManager.java b/src/main/java/net/minecraft/server/BiomeManager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/BiomeManager.java
|
||||
+++ b/src/main/java/net/minecraft/server/BiomeManager.java
|
||||
@@ -0,0 +0,0 @@ public class BiomeManager {
|
||||
this.c = genlayerzoomer;
|
||||
}
|
||||
|
||||
+ public BiomeManager withProvider(WorldChunkManager worldchunkmanager) { return a(worldchunkmanager); } // Paper - OBFHELPER
|
||||
public BiomeManager a(WorldChunkManager worldchunkmanager) {
|
||||
return new BiomeManager(worldchunkmanager, this.b, this.c);
|
||||
}
|
||||
|
||||
+ public BiomeBase getBiome(BlockPosition blockposition) { return a(blockposition); } // Paper - OBFHELPER
|
||||
public BiomeBase a(BlockPosition blockposition) {
|
||||
return this.c.a(this.b, blockposition.getX(), blockposition.getY(), blockposition.getZ(), this.a);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkCoordIntPair.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkCoordIntPair.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkCoordIntPair {
|
||||
}
|
||||
}
|
||||
|
||||
+ public int getBlockX() { return d(); } // Paper - OBFHELPER
|
||||
public int d() {
|
||||
return this.x << 4;
|
||||
}
|
||||
|
||||
+ public int getBlockZ() { return e(); } // Paper - OBFHELPER
|
||||
public int e() {
|
||||
return this.z << 4;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/StructureGenerator.java b/src/main/java/net/minecraft/server/StructureGenerator.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/StructureGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/server/StructureGenerator.java
|
||||
@@ -0,0 +0,0 @@ public abstract class StructureGenerator<C extends WorldGenFeatureConfiguration>
|
||||
if (flag1 || flag2) {
|
||||
ChunkCoordIntPair chunkcoordintpair = this.a(chunkgenerator, seededrandom, j, k, i1, j1);
|
||||
if (!world.getWorldBorder().isChunkInBounds(chunkcoordintpair.x, chunkcoordintpair.z)) { continue; } // Paper
|
||||
+ // Paper start - seed based feature search
|
||||
+ if (world.paperConfig.seedBasedFeatureSearch) {
|
||||
+ BiomeManager biomeManager = world.getBiomeManager().withProvider(chunkgenerator.getWorldChunkManager());
|
||||
+ BiomeBase biomeBase = biomeManager.getBiome(new BlockPosition(chunkcoordintpair.getBlockX() + 9, 0, chunkcoordintpair.getBlockZ() + 9));
|
||||
+ if (!shouldGenerate(biomeManager, chunkgenerator, seededrandom, chunkcoordintpair.x, chunkcoordintpair.z, biomeBase)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
StructureStart structurestart = world.getChunkAt(chunkcoordintpair.x, chunkcoordintpair.z, ChunkStatus.STRUCTURE_STARTS).a(this.b());
|
||||
|
||||
if (structurestart != null && structurestart.e()) {
|
||||
@@ -0,0 +0,0 @@ public abstract class StructureGenerator<C extends WorldGenFeatureConfiguration>
|
||||
return new ChunkCoordIntPair(i + k, j + l);
|
||||
}
|
||||
|
||||
+ public boolean shouldGenerate(BiomeManager biomemanager, ChunkGenerator<?> chunkgenerator, Random random, int chunkX, int chunkZ, BiomeBase biomebase) { return a(biomemanager, chunkgenerator, random, chunkX, chunkZ, biomebase); } // Paper - OBFHELPER
|
||||
public abstract boolean a(BiomeManager biomemanager, ChunkGenerator<?> chunkgenerator, Random random, int i, int j, BiomeBase biomebase);
|
||||
|
||||
public abstract StructureGenerator.a a();
|
||||
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
return this.methodProfiler;
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public BiomeManager d() {
|
||||
+ public BiomeManager getBiomeManager() { return d(); } // Paper - OBFHELPER
|
||||
+ @Override public BiomeManager d() {
|
||||
return this.biomeManager;
|
||||
}
|
||||
}
|
|
@ -88,7 +88,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
- public void a(NBTTagList nbttaglist, long[] along) {
|
||||
+ public synchronized void a(NBTTagList nbttaglist, long[] along) { // Paper - synchronize
|
||||
this.a();
|
||||
int i = Math.max(4, MathHelper.d(nbttaglist.size()));
|
||||
int i = Math.max(4, MathHelper.e(nbttaglist.size()));
|
||||
|
||||
@@ -0,0 +0,0 @@ public class DataPaletteBlock<T> implements DataPaletteExpandable<T> {
|
||||
this.b();
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sat, 22 Jun 2019 04:20:47 -0700
|
||||
Subject: [PATCH] Use ChunkStatus cache when saving protochunks
|
||||
|
||||
The cache should contain the chunk status when saving. If not it
|
||||
will load it.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
NBTTagCompound nbttagcompound;
|
||||
|
||||
if (chunkstatus.getType() != ChunkStatus.Type.LEVELCHUNK) {
|
||||
- nbttagcompound = this.readChunkData(chunkcoordintpair);
|
||||
- if (nbttagcompound != null && ChunkRegionLoader.a(nbttagcompound) == ChunkStatus.Type.LEVELCHUNK) {
|
||||
+ // Paper start - Optimize save by using status cache
|
||||
+ ChunkStatus statusOnDisk = this.getChunkStatusOnDisk(chunkcoordintpair);
|
||||
+ if (statusOnDisk != null && statusOnDisk.getType() == ChunkStatus.Type.LEVELCHUNK) {
|
||||
+ // Paper end
|
||||
return false;
|
||||
}
|
||||
|
|
@ -25,39 +25,35 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/World.java
|
||||
+++ b/src/main/java/net/minecraft/server/World.java
|
||||
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
return (CraftServer) Bukkit.getServer();
|
||||
}
|
||||
|
||||
public Chunk getChunkIfLoaded(int x, int z) {
|
||||
- return ((ChunkProviderServer) this.chunkProvider).getChunkAt(x, z, false);
|
||||
+ return ((ChunkProviderServer) this.chunkProvider).getChunkAtIfLoadedImmediately(x, z); // Paper
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isChunkLoaded(int x, int z) {
|
||||
+ return getChunkIfLoaded(x, z) != null;
|
||||
+ return ((WorldServer)this).getChunkIfLoaded(x, z) != null;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ // Paper end
|
||||
|
||||
protected World(WorldData worlddata, DimensionManager dimensionmanager, java.util.concurrent.Executor executor, BiFunction<World, WorldProvider, IChunkProvider> bifunction, GameProfilerFiller gameprofilerfiller, boolean flag, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env) { // Paper - executor
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig( worlddata.getName() ); // Spigot
|
||||
+
|
||||
protected World(WorldDataMutable worlddatamutable, ResourceKey<World> resourcekey, ResourceKey<DimensionManager> resourcekey1, DimensionManager dimensionmanager, Supplier<GameProfilerFiller> supplier, boolean flag, boolean flag1, long i, org.bukkit.generator.ChunkGenerator gen, org.bukkit.World.Environment env, java.util.concurrent.Executor executor) {
|
||||
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((WorldDataServer) worlddatamutable).getName()); // Spigot
|
||||
this.paperConfig = new com.destroystokyo.paper.PaperWorldConfig((((WorldDataServer)worlddatamutable).getName()), this.spigotConfig); // Paper
|
||||
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
}
|
||||
|
||||
public boolean n(BlockPosition blockposition) {
|
||||
- return isOutsideWorld(blockposition) ? false : this.chunkProvider.b(blockposition.getX() >> 4, blockposition.getZ() >> 4);
|
||||
public boolean p(BlockPosition blockposition) {
|
||||
- return isOutsideWorld(blockposition) ? false : this.getChunkProvider().b(blockposition.getX() >> 4, blockposition.getZ() >> 4);
|
||||
+ return isOutsideWorld(blockposition) ? false : isChunkLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper
|
||||
}
|
||||
|
||||
public boolean a(BlockPosition blockposition, Entity entity) {
|
||||
public boolean a(BlockPosition blockposition, Entity entity, EnumDirection enumdirection) {
|
||||
if (isOutsideWorld(blockposition)) {
|
||||
return false;
|
||||
} else {
|
||||
- IChunkAccess ichunkaccess = this.getChunkAt(blockposition.getX() >> 4, blockposition.getZ() >> 4, ChunkStatus.FULL, false);
|
||||
+ IChunkAccess ichunkaccess = this.getChunkIfLoadedImmediately(blockposition.getX() >> 4, blockposition.getZ() >> 4); // Paper
|
||||
|
||||
return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).a((IBlockAccess) this, blockposition, entity);
|
||||
return ichunkaccess == null ? false : ichunkaccess.getType(blockposition).a((IBlockAccess) this, blockposition, entity, enumdirection);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
||||
|
||||
|
@ -68,6 +64,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
if (chunk != null) {
|
||||
chunk.a(oclass, axisalignedbb, list, predicate);
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
}
|
||||
|
||||
public Chunk getChunkIfLoaded(int x, int z) {
|
||||
- return this.chunkProvider.getChunkAt(x, z, false);
|
||||
+ return this.chunkProvider.getChunkAtIfLoadedImmediately(x, z); // Paper
|
||||
}
|
||||
|
||||
// Paper start - Asynchronous IO
|
||||
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
||||
|
|
|
@ -549,12 +549,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
this.world.getMethodProfiler().enter("naturalSpawnCount");
|
||||
this.world.timings.countNaturalMobs.startTiming(); // Paper - timings
|
||||
int l = this.chunkMapDistance.b();
|
||||
EnumCreatureType[] aenumcreaturetype = EnumCreatureType.values();
|
||||
- Object2IntMap<EnumCreatureType> object2intmap = this.world.l();
|
||||
- SpawnerCreature.d spawnercreature_d = SpawnerCreature.a(l, this.world.z(), this::a);
|
||||
+ // Paper start - per player mob spawning
|
||||
+ int[] worldMobCount;
|
||||
+ SpawnerCreature.d spawnercreature_d; // moved down
|
||||
+ if (this.playerChunkMap.playerMobDistanceMap != null) {
|
||||
+ // update distance map
|
||||
+ this.world.timings.playerMobDistanceMapUpdate.startTiming();
|
||||
|
@ -564,40 +564,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
+ for (EntityPlayer player : this.world.players) {
|
||||
+ Arrays.fill(player.mobCounts, 0);
|
||||
+ }
|
||||
+ worldMobCount = this.world.countMobs(true);
|
||||
+ spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, true);
|
||||
+ } else {
|
||||
+ worldMobCount = this.world.countMobs(false);
|
||||
+ spawnercreature_d = SpawnerCreature.countMobs(l, this.world.z(), this::a, false);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
this.world.timings.countNaturalMobs.stopTiming(); // Paper - timings
|
||||
this.world.getMethodProfiler().exit();
|
||||
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
if (enumcreaturetype != EnumCreatureType.MISC && (!enumcreaturetype.c() || this.allowAnimals) && (enumcreaturetype.c() || this.allowMonsters) && (!enumcreaturetype.d() || flag2)) {
|
||||
int k1 = limit * l / ChunkProviderServer.b; // CraftBukkit - use per-world limits
|
||||
|
||||
- if (object2intmap.getInt(enumcreaturetype) <= k1) {
|
||||
- SpawnerCreature.a(enumcreaturetype, this.world, chunk, blockposition);
|
||||
+ // Paper start - only allow spawns upto the limit per chunk and update count afterwards
|
||||
+ int currEntityCount = worldMobCount[enumcreaturetype.ordinal()];
|
||||
+ int difference = k1 - currEntityCount;
|
||||
+
|
||||
+ if (this.world.paperConfig.perPlayerMobSpawns) {
|
||||
+ int minDiff = Integer.MAX_VALUE;
|
||||
+ for (EntityPlayer entityplayer : this.playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) {
|
||||
+ minDiff = Math.min(limit - this.playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff);
|
||||
+ }
|
||||
+ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
|
||||
+ }
|
||||
+
|
||||
+ if (difference > 0) {
|
||||
+ int spawnCount = SpawnerCreature.spawnMobs(enumcreaturetype, this.world, chunk, blockposition, difference,
|
||||
+ this.world.paperConfig.perPlayerMobSpawns ? this.playerChunkMap::updatePlayerMobTypeMap : null);
|
||||
+ worldMobCount[enumcreaturetype.ordinal()] += spawnCount;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
}
|
||||
this.p = spawnercreature_d;
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
|
||||
|
@ -626,30 +600,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
}
|
||||
|
||||
+ public SectionPosition getPlayerMapSection() { return this.K(); } // Paper - OBFHELPER
|
||||
public SectionPosition K() {
|
||||
return this.cs;
|
||||
+ public final SectionPosition getPlayerMapSection() { return this.N(); } // Paper - OBFHELPER
|
||||
public SectionPosition N() {
|
||||
return this.cq;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/EntityTypes.java b/src/main/java/net/minecraft/server/EntityTypes.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/EntityTypes.java
|
||||
+++ b/src/main/java/net/minecraft/server/EntityTypes.java
|
||||
@@ -0,0 +0,0 @@ public class EntityTypes<T extends Entity> {
|
||||
return this.bf;
|
||||
return this.bk;
|
||||
}
|
||||
|
||||
+ public EnumCreatureType getEnumCreatureType() { return this.e(); } // Paper - OBFHELPER
|
||||
+ public final EnumCreatureType getEnumCreatureType() { return this.e(); } // Paper - OBFHELPER
|
||||
public EnumCreatureType e() {
|
||||
return this.bb;
|
||||
return this.bf;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
private final PlayerMap playerMap;
|
||||
public final Int2ObjectMap<PlayerChunkMap.EntityTracker> trackedEntities;
|
||||
private final Queue<Runnable> z;
|
||||
private final Long2ByteMap z;
|
||||
private final Queue<Runnable> A; private final Queue<Runnable> getUnloadQueueTasks() { return this.A; } // Paper - OBFHELPER
|
||||
- private int viewDistance;
|
||||
+ int viewDistance; // Paper - private -> package private
|
||||
+ public final com.destroystokyo.paper.util.PlayerMobDistanceMap playerMobDistanceMap; // Paper
|
||||
|
@ -658,7 +632,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
public final CallbackExecutor callbackExecutor = new CallbackExecutor();
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
this.l = supplier;
|
||||
this.m = new VillagePlace(new File(this.w, "poi"), datafixer, this.world); // Paper
|
||||
this.m = new VillagePlace(new File(this.w, "poi"), datafixer, flag, this.world); // Paper
|
||||
this.setViewDistance(i);
|
||||
+ this.playerMobDistanceMap = this.world.paperConfig.perPlayerMobSpawns ? new com.destroystokyo.paper.util.PlayerMobDistanceMap() : null; // Paper
|
||||
+ }
|
||||
|
@ -685,117 +659,167 @@ diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/
|
|||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||||
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
|
||||
@@ -0,0 +0,0 @@ package net.minecraft.server;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
+import java.util.function.Consumer; // Paper
|
||||
import javax.annotation.Nullable;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
});
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
+ // Paper start - add maxSpawns parameter and return spawned mobs
|
||||
public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, BlockPosition blockposition) {
|
||||
+ spawnMobs(enumcreaturetype, worldserver, chunk, blockposition, Integer.MAX_VALUE, null);
|
||||
public static SpawnerCreature.d a(int i, Iterable<Entity> iterable, SpawnerCreature.b spawnercreature_b) {
|
||||
+ // Paper start - add countMobs parameter
|
||||
+ return countMobs(i, iterable, spawnercreature_b, false);
|
||||
+ }
|
||||
+ public static int spawnMobs(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, BlockPosition blockposition, int maxSpawns, Consumer<Entity> trackEntity) {
|
||||
+ // Paper end
|
||||
ChunkGenerator<?> chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
|
||||
- int i = 0;
|
||||
+ int i = 0; // Paper - force diff on name change
|
||||
BlockPosition blockposition1 = getRandomPosition(worldserver, chunk);
|
||||
int j = blockposition1.getX();
|
||||
int k = blockposition1.getY();
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
);
|
||||
if (!event.callEvent()) {
|
||||
if (event.shouldAbortSpawn()) {
|
||||
- return;
|
||||
+ return i; // Paper
|
||||
}
|
||||
++i2;
|
||||
continue;
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
} catch (Exception exception) {
|
||||
SpawnerCreature.LOGGER.warn("Failed to create mob", exception);
|
||||
ServerInternalException.reportInternalException(exception); // Paper
|
||||
- return;
|
||||
+ return i; // Paper
|
||||
}
|
||||
|
||||
entityinsentient.setPositionRotation((double) f, (double) k, (double) f1, worldserver.random.nextFloat() * 360.0F, 0.0F);
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(new BlockPosition(entityinsentient)), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
|
||||
// CraftBukkit start
|
||||
if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) {
|
||||
- ++i;
|
||||
+ ++i; // Paper - force diff on name change
|
||||
++i2;
|
||||
+ if (trackEntity != null) {
|
||||
+ trackEntity.accept(entityinsentient); // Paper
|
||||
+ }
|
||||
}
|
||||
+ if (i >= maxSpawns) { return i; } // Paper
|
||||
// CraftBukkit end
|
||||
if (i >= entityinsentient.getMaxSpawnGroup()) {
|
||||
- return;
|
||||
+ return i; // Paper
|
||||
}
|
||||
|
||||
if (entityinsentient.c(i2)) {
|
||||
+ public static SpawnerCreature.d countMobs(int i, Iterable<Entity> iterable, SpawnerCreature.b spawnercreature_b, boolean countMobs) {
|
||||
+ // Paper end - add countMobs parameter
|
||||
SpawnerCreatureProbabilities spawnercreatureprobabilities = new SpawnerCreatureProbabilities();
|
||||
Object2IntOpenHashMap<EnumCreatureType> object2intopenhashmap = new Object2IntOpenHashMap();
|
||||
Iterator iterator = iterable.iterator();
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
}
|
||||
|
||||
object2intopenhashmap.addTo(enumcreaturetype, 1);
|
||||
+ // Paper start
|
||||
+ if (countMobs) {
|
||||
+ ((WorldServer)chunk.world).getChunkProvider().playerChunkMap.updatePlayerMobTypeMap(entity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
});
|
||||
}
|
||||
}
|
||||
+ return i; // Paper
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
continue;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
}
|
||||
|
||||
public Object2IntMap<EnumCreatureType> l() {
|
||||
- Object2IntMap<EnumCreatureType> object2intmap = new Object2IntOpenHashMap();
|
||||
+ // Paper start
|
||||
+ int[] values = this.countMobs(false);
|
||||
+ EnumCreatureType[] byId = EnumCreatureType.values();
|
||||
+ Object2IntMap<EnumCreatureType> ret = new Object2IntOpenHashMap<>();
|
||||
+ // Paper start - only allow spawns upto the limit per chunk and update count afterwards
|
||||
+ int currEntityCount = spawnercreature_d.getEntityCountsByType().getInt(enumcreaturetype);
|
||||
+ int k1 = limit * spawnercreature_d.getSpawnerChunks() / SpawnerCreature.b;
|
||||
+ int difference = k1 - currEntityCount;
|
||||
+
|
||||
+ for (int i = 0, len = values.length; i < len; ++i) {
|
||||
+ ret.put(byId[i], values[i]);
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+ }
|
||||
+ public int[] countMobs(boolean updatePlayerCounts) {
|
||||
+ int[] ret = new int[EntityPlayer.ENUMCREATURETYPE_TOTAL_ENUMS];
|
||||
+ // Paper end
|
||||
ObjectIterator objectiterator = this.entitiesById.values().iterator();
|
||||
|
||||
while (objectiterator.hasNext()) {
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World {
|
||||
continue;
|
||||
}
|
||||
// Paper end
|
||||
- object2intmap.mergeInt(enumcreaturetype, 1, Integer::sum);
|
||||
+ // Paper start - rework mob spawning
|
||||
+ if (updatePlayerCounts) {
|
||||
+ this.getChunkProvider().playerChunkMap.updatePlayerMobTypeMap(entity);
|
||||
+ if (worldserver.paperConfig.perPlayerMobSpawns) {
|
||||
+ int minDiff = Integer.MAX_VALUE;
|
||||
+ for (EntityPlayer entityplayer : worldserver.getChunkProvider().playerChunkMap.playerMobDistanceMap.getPlayersInRange(chunk.getPos())) {
|
||||
+ minDiff = Math.min(limit - worldserver.getChunkProvider().playerChunkMap.getMobCountNear(entityplayer, enumcreaturetype), minDiff);
|
||||
+ }
|
||||
+ ++ret[enumcreaturetype.ordinal()];
|
||||
+ // Paper end
|
||||
+ difference = (minDiff == Integer.MAX_VALUE) ? 0 : minDiff;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ if (difference > 0) { // Paper
|
||||
if ((flag || !enumcreaturetype.d()) && (flag1 || enumcreaturetype.d()) && (flag2 || !enumcreaturetype.e()) && spawnercreature_d.a(enumcreaturetype, limit)) {
|
||||
// CraftBukkit end
|
||||
- a(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> {
|
||||
+ int spawnCount = spawnMobs(enumcreaturetype, worldserver, chunk, (entitytypes, blockposition, ichunkaccess) -> {
|
||||
return spawnercreature_d.a(entitytypes, blockposition, ichunkaccess);
|
||||
}, (entityinsentient, ichunkaccess) -> {
|
||||
spawnercreature_d.a(entityinsentient, ichunkaccess);
|
||||
+ },
|
||||
+ limit, worldserver.paperConfig.perPlayerMobSpawns ? worldserver.getChunkProvider().playerChunkMap::updatePlayerMobTypeMap : null);
|
||||
+ spawnercreature_d.getEntityCountsByType().mergeInt(enumcreaturetype, 0, (keyInMap, valueInMap) -> {
|
||||
+ return Integer.valueOf(spawnCount + valueInMap.intValue());
|
||||
});
|
||||
+ } // Paper
|
||||
}
|
||||
}
|
||||
|
||||
- return object2intmap;
|
||||
+ return ret;
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
}
|
||||
|
||||
@Override
|
||||
public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) {
|
||||
+ // Paper start - add parameters and int ret type
|
||||
+ spawnMobs(enumcreaturetype, worldserver, chunk, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null);
|
||||
+ }
|
||||
+ public static int spawnMobs(EnumCreatureType enumcreaturetype, WorldServer worldserver, Chunk chunk, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer<Entity> trackEntity) {
|
||||
+ // Paper end - add parameters and int ret type
|
||||
BlockPosition blockposition = getRandomPosition(worldserver, chunk);
|
||||
|
||||
if (blockposition.getY() >= 1) {
|
||||
- a(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a);
|
||||
+ return spawnMobsInternal(enumcreaturetype, worldserver, (IChunkAccess) chunk, blockposition, spawnercreature_c, spawnercreature_a, maxSpawns, trackEntity);
|
||||
}
|
||||
+ return 0; // Paper
|
||||
}
|
||||
|
||||
public static void a(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a) {
|
||||
+ // Paper start - add maxSpawns parameter and return spawned mobs
|
||||
+ spawnMobsInternal(enumcreaturetype, worldserver, ichunkaccess, blockposition, spawnercreature_c, spawnercreature_a, Integer.MAX_VALUE, null);
|
||||
+ }
|
||||
+ public static int spawnMobsInternal(EnumCreatureType enumcreaturetype, WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition blockposition, SpawnerCreature.c spawnercreature_c, SpawnerCreature.a spawnercreature_a, int maxSpawns, Consumer<Entity> trackEntity) {
|
||||
+ // Paper end - add maxSpawns parameter and return spawned mobs
|
||||
StructureManager structuremanager = worldserver.getStructureManager();
|
||||
ChunkGenerator chunkgenerator = worldserver.getChunkProvider().getChunkGenerator();
|
||||
int i = blockposition.getY();
|
||||
IBlockData iblockdata = worldserver.getTypeIfLoadedAndInBounds(blockposition); // Paper - don't load chunks for mob spawn
|
||||
+ int j = 0; // Paper - moved up
|
||||
|
||||
if (iblockdata != null && !iblockdata.isOccluding(ichunkaccess, blockposition)) { // Paper - don't load chunks for mob spawn
|
||||
BlockPosition.MutableBlockPosition blockposition_mutableblockposition = new BlockPosition.MutableBlockPosition();
|
||||
- int j = 0;
|
||||
+ // Paper - moved up
|
||||
int k = 0;
|
||||
|
||||
while (k < 3) {
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
// Paper start
|
||||
Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomebase_biomemeta, blockposition_mutableblockposition, d2);
|
||||
if (doSpawning == null) {
|
||||
- return;
|
||||
+ return j; // Paper
|
||||
}
|
||||
if (doSpawning.booleanValue() && spawnercreature_c.test(biomebase_biomemeta.c, blockposition_mutableblockposition, ichunkaccess)) { // Paper end
|
||||
EntityInsentient entityinsentient = a(worldserver, biomebase_biomemeta.c);
|
||||
|
||||
if (entityinsentient == null) {
|
||||
- return;
|
||||
+ return j; // Paper
|
||||
}
|
||||
|
||||
entityinsentient.setPositionRotation(d0, (double) i, d1, worldserver.random.nextFloat() * 360.0F, 0.0F);
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
groupdataentity = entityinsentient.prepare(worldserver, worldserver.getDamageScaler(entityinsentient.getChunkCoordinates()), EnumMobSpawn.NATURAL, groupdataentity, (NBTTagCompound) null);
|
||||
// CraftBukkit start
|
||||
if (worldserver.addEntity(entityinsentient, SpawnReason.NATURAL)) {
|
||||
- ++j;
|
||||
+ ++j; // Paper - force diff on name change - we expect this to be the total amount spawned
|
||||
++k1;
|
||||
spawnercreature_a.run(entityinsentient, ichunkaccess);
|
||||
+ // Paper start
|
||||
+ if (trackEntity != null) {
|
||||
+ trackEntity.accept(entityinsentient);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
// CraftBukkit end
|
||||
- if (j >= entityinsentient.getMaxSpawnGroup()) {
|
||||
- return;
|
||||
+ if (j >= entityinsentient.getMaxSpawnGroup() || j >= maxSpawns) { // Paper
|
||||
+ return j; // Paper
|
||||
}
|
||||
|
||||
if (entityinsentient.c(k1)) {
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
}
|
||||
|
||||
}
|
||||
+ return j; // Paper
|
||||
}
|
||||
|
||||
private static boolean a(WorldServer worldserver, IChunkAccess ichunkaccess, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) {
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
|
||||
public static class d {
|
||||
|
||||
- private final int a;
|
||||
+ private final int a; final int getSpawnerChunks() { return this.a; } // Paper - OBFHELPER
|
||||
private final Object2IntOpenHashMap<EnumCreatureType> b;
|
||||
private final SpawnerCreatureProbabilities c;
|
||||
- private final Object2IntMap<EnumCreatureType> d;
|
||||
+ private final Object2IntMap<EnumCreatureType> d; final Object2IntMap<EnumCreatureType> getEntityCountsByType() { return this.d; } // Paper - OBFHELPER
|
||||
@Nullable
|
||||
private BlockPosition e;
|
||||
@Nullable
|
||||
@@ -0,0 +0,0 @@ public final class SpawnerCreature {
|
||||
|
||||
// CraftBukkit start
|
||||
private boolean a(EnumCreatureType enumcreaturetype, int limit) {
|
||||
- int i = limit * this.a / SpawnerCreature.b;
|
||||
+ int i = limit * this.a / SpawnerCreature.b; // Paper - diff on change, needed in the spawn method
|
||||
// CraftBukkit end
|
||||
|
||||
return this.b.getInt(enumcreaturetype) < i;
|
||||
|
|
319
Spigot-Server-Patches/incremental-chunk-saving.patch
Normal file
319
Spigot-Server-Patches/incremental-chunk-saving.patch
Normal file
|
@ -0,0 +1,319 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 9 Jun 2019 03:53:22 +0100
|
||||
Subject: [PATCH] incremental chunk saving
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class PaperWorldConfig {
|
||||
keepLoadedRange = (short) (getInt("keep-spawn-loaded-range", Math.min(spigotConfig.viewDistance, 10)) * 16);
|
||||
log( "Keep Spawn Loaded Range: " + (keepLoadedRange/16));
|
||||
}
|
||||
+
|
||||
+ public int autoSavePeriod = -1;
|
||||
+ private void autoSavePeriod() {
|
||||
+ autoSavePeriod = getInt("auto-save-interval", -1);
|
||||
+ if (autoSavePeriod > 0) {
|
||||
+ log("Auto Save Interval: " +autoSavePeriod + " (" + (autoSavePeriod / 20) + "s)");
|
||||
+ } else if (autoSavePeriod < 0) {
|
||||
+ autoSavePeriod = net.minecraft.server.MinecraftServer.getServer().autosavePeriod;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public int maxAutoSaveChunksPerTick = 24;
|
||||
+ private void maxAutoSaveChunksPerTick() {
|
||||
+ maxAutoSaveChunksPerTick = getInt("max-auto-save-chunks-per-tick", 24);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/Chunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
||||
@@ -0,0 +0,0 @@ public class Chunk implements IChunkAccess {
|
||||
private TickList<Block> o;
|
||||
private TickList<FluidType> p;
|
||||
private boolean q;
|
||||
- private long lastSaved;
|
||||
+ public long lastSaved; // Paper
|
||||
private volatile boolean s;
|
||||
private long inhabitedTime;
|
||||
@Nullable
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
} // Paper - Timings
|
||||
}
|
||||
|
||||
+ // Paper start - duplicate save, but call incremental
|
||||
+ public void saveIncrementally() {
|
||||
+ this.tickDistanceManager();
|
||||
+ try (co.aikar.timings.Timing timed = world.timings.chunkSaveData.startTiming()) { // Paper - Timings
|
||||
+ this.playerChunkMap.saveIncrementally();
|
||||
+ } // Paper - Timings
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
// CraftBukkit start
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
public static int currentTick = 0; // Paper - Further improve tick loop
|
||||
public java.util.Queue<Runnable> processQueue = new java.util.concurrent.ConcurrentLinkedQueue<Runnable>();
|
||||
public int autosavePeriod;
|
||||
+ public boolean serverAutoSave = false; // Paper
|
||||
public File bukkitDataPackFolder;
|
||||
public CommandDispatcher vanillaCommandDispatcher;
|
||||
private boolean forceTicks;
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends IAsyncTaskHandlerReentrant<TickTas
|
||||
this.serverPing.b().a(agameprofile);
|
||||
}
|
||||
|
||||
- if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit
|
||||
- MinecraftServer.LOGGER.debug("Autosave started");
|
||||
+ //if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // CraftBukkit // Paper - move down
|
||||
+ //MinecraftServer.LOGGER.debug("Autosave started"); // Paper
|
||||
+ serverAutoSave = (autosavePeriod > 0 && this.ticks % autosavePeriod == 0); // Paper
|
||||
this.methodProfiler.enter("save");
|
||||
+ if (autosavePeriod > 0 && this.ticks % autosavePeriod == 0) { // Paper
|
||||
this.playerList.savePlayers();
|
||||
- this.saveChunks(true, false, false);
|
||||
+ }// Paper
|
||||
+ // Paper start
|
||||
+ for (WorldServer world : getWorlds()) {
|
||||
+ if (world.paperConfig.autoSavePeriod > 0) {
|
||||
+ try {
|
||||
+ world.saveIncrementally(serverAutoSave);
|
||||
+ } catch (ExceptionWorldConflict exceptionWorldConflict) {
|
||||
+ MinecraftServer.LOGGER.warn(exceptionWorldConflict.getMessage());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
this.methodProfiler.exit();
|
||||
- MinecraftServer.LOGGER.debug("Autosave finished");
|
||||
- }
|
||||
+ //MinecraftServer.LOGGER.debug("Autosave finished"); // Paper
|
||||
+ //} // Paper
|
||||
|
||||
this.methodProfiler.enter("snooper");
|
||||
if (((DedicatedServer) this).getDedicatedServerProperties().snooperEnabled && !this.snooper.d() && this.ticks > 100) { // Spigot
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunk {
|
||||
|
||||
private final PlayerChunkMap chunkMap; // Paper
|
||||
|
||||
+ long lastAutoSaveTime; // Paper - incremental autosave
|
||||
+ long inactiveTimeStart; // Paper - incremental autosave
|
||||
+
|
||||
public PlayerChunk(ChunkCoordIntPair chunkcoordintpair, int i, LightEngine lightengine, PlayerChunk.c playerchunk_c, PlayerChunk.d playerchunk_d) {
|
||||
this.statusFutures = new AtomicReferenceArray(PlayerChunk.CHUNK_STATUSES.size());
|
||||
this.fullChunkFuture = PlayerChunk.UNLOADED_CHUNK_FUTURE;
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunk {
|
||||
boolean flag2 = playerchunk_state.isAtLeast(PlayerChunk.State.BORDER);
|
||||
boolean flag3 = playerchunk_state1.isAtLeast(PlayerChunk.State.BORDER);
|
||||
|
||||
+ boolean prevHasBeenLoaded = this.hasBeenLoaded; // Paper
|
||||
this.hasBeenLoaded |= flag3;
|
||||
+ // Paper start - incremental autosave
|
||||
+ if (this.hasBeenLoaded & !prevHasBeenLoaded) {
|
||||
+ long timeSinceAutoSave = this.inactiveTimeStart - this.lastAutoSaveTime;
|
||||
+ if (timeSinceAutoSave < 0) {
|
||||
+ // safest bet is to assume autosave is needed here
|
||||
+ timeSinceAutoSave = this.chunkMap.world.paperConfig.autoSavePeriod;
|
||||
+ }
|
||||
+ this.lastAutoSaveTime = this.chunkMap.world.getTime() - timeSinceAutoSave;
|
||||
+ this.chunkMap.autoSaveQueue.add(this);
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (!flag2 && flag3) {
|
||||
// Paper start - cache ticking ready status
|
||||
int expectCreateCount = ++this.fullChunkCreateCount;
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunk {
|
||||
}
|
||||
|
||||
public void m() {
|
||||
+ boolean prev = this.hasBeenLoaded; // Paper
|
||||
+ this.hasBeenLoaded = getChunkState(this.ticketLevel).isAtLeast(PlayerChunk.State.BORDER);
|
||||
+ // Paper start - incremental autosave
|
||||
+ if (prev != this.hasBeenLoaded) {
|
||||
+ if (this.hasBeenLoaded) {
|
||||
+ long timeSinceAutoSave = this.inactiveTimeStart - this.lastAutoSaveTime;
|
||||
+ if (timeSinceAutoSave < 0) {
|
||||
+ // safest bet is to assume autosave is needed here
|
||||
+ timeSinceAutoSave = this.chunkMap.world.paperConfig.autoSavePeriod;
|
||||
+ }
|
||||
+ this.lastAutoSaveTime = this.chunkMap.world.getTime() - timeSinceAutoSave;
|
||||
+ this.chunkMap.autoSaveQueue.add(this);
|
||||
+ } else {
|
||||
+ this.inactiveTimeStart = this.chunkMap.world.getTime();
|
||||
+ this.chunkMap.autoSaveQueue.remove(this);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - incremental autosave
|
||||
+ public boolean setHasBeenLoaded() {
|
||||
this.hasBeenLoaded = getChunkState(this.ticketLevel).isAtLeast(PlayerChunk.State.BORDER);
|
||||
+ return this.hasBeenLoaded;
|
||||
}
|
||||
+ // Paper end
|
||||
|
||||
public void a(ProtoChunkExtension protochunkextension) {
|
||||
for (int i = 0; i < this.statusFutures.length(); ++i) {
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - incremental autosave
|
||||
+ final it.unimi.dsi.fastutil.objects.ObjectRBTreeSet<PlayerChunk> autoSaveQueue = new it.unimi.dsi.fastutil.objects.ObjectRBTreeSet<>((playerchunk1, playerchunk2) -> {
|
||||
+ int timeCompare = Long.compare(playerchunk1.lastAutoSaveTime, playerchunk2.lastAutoSaveTime);
|
||||
+ if (timeCompare != 0) {
|
||||
+ return timeCompare;
|
||||
+ }
|
||||
+
|
||||
+ return Long.compare(MCUtil.getCoordinateKey(playerchunk1.location), MCUtil.getCoordinateKey(playerchunk2.location));
|
||||
+ });
|
||||
+
|
||||
+ protected void saveIncrementally() {
|
||||
+ int savedThisTick = 0;
|
||||
+ // optimized since we search far less chunks to hit ones that need to be saved
|
||||
+ List<PlayerChunk> reschedule = new java.util.ArrayList<>(this.world.paperConfig.maxAutoSaveChunksPerTick);
|
||||
+ long currentTick = this.world.getTime();
|
||||
+ long maxSaveTime = currentTick - this.world.paperConfig.autoSavePeriod;
|
||||
+
|
||||
+ for (Iterator<PlayerChunk> iterator = this.autoSaveQueue.iterator(); iterator.hasNext();) {
|
||||
+ PlayerChunk playerchunk = iterator.next();
|
||||
+ if (playerchunk.lastAutoSaveTime > maxSaveTime) {
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ iterator.remove();
|
||||
+
|
||||
+ IChunkAccess ichunkaccess = playerchunk.getChunkSave().getNow(null);
|
||||
+ if (ichunkaccess instanceof Chunk) {
|
||||
+ boolean shouldSave = ((Chunk)ichunkaccess).lastSaved <= maxSaveTime;
|
||||
+
|
||||
+ if (shouldSave && this.saveChunk(ichunkaccess)) {
|
||||
+ ++savedThisTick;
|
||||
+
|
||||
+ if (!playerchunk.setHasBeenLoaded()) {
|
||||
+ // do not fall through to reschedule logic
|
||||
+ playerchunk.inactiveTimeStart = currentTick;
|
||||
+ if (savedThisTick >= this.world.paperConfig.maxAutoSaveChunksPerTick) {
|
||||
+ break;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ reschedule.add(playerchunk);
|
||||
+
|
||||
+ if (savedThisTick >= this.world.paperConfig.maxAutoSaveChunksPerTick) {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ for (int i = 0, len = reschedule.size(); i < len; ++i) {
|
||||
+ PlayerChunk playerchunk = reschedule.get(i);
|
||||
+ playerchunk.lastAutoSaveTime = this.world.getTime();
|
||||
+ this.autoSaveQueue.add(playerchunk);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
protected void save(boolean flag) {
|
||||
if (flag) {
|
||||
List<PlayerChunk> list = (List) this.visibleChunks.values().stream().filter(PlayerChunk::hasBeenLoaded).peek(PlayerChunk::m).collect(Collectors.toList());
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
|
||||
this.world.unloadChunk(chunk);
|
||||
}
|
||||
+ this.autoSaveQueue.remove(playerchunk); // Paper
|
||||
|
||||
this.lightEngine.a(ichunkaccess.getPos());
|
||||
this.lightEngine.queueUpdate();
|
||||
@@ -0,0 +0,0 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
playerchunk.a(new ProtoChunkExtension(chunk));
|
||||
}
|
||||
|
||||
+ chunk.setLastSaved(this.world.getTime() - 1); // Paper - avoid autosaving newly generated/loaded chunks
|
||||
+
|
||||
chunk.a(() -> {
|
||||
return PlayerChunk.getChunkState(playerchunk.getTicketLevel());
|
||||
});
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
return !this.server.a(this, blockposition, entityhuman) && this.getWorldBorder().a(blockposition);
|
||||
}
|
||||
|
||||
+ // Paper start - derived from below
|
||||
+ public void saveIncrementally(boolean doFull) {
|
||||
+ ChunkProviderServer chunkproviderserver = this.getChunkProvider();
|
||||
+
|
||||
+ if (doFull) {
|
||||
+ org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld()));
|
||||
+ }
|
||||
+
|
||||
+ try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) {
|
||||
+ if (doFull) {
|
||||
+ this.saveData();
|
||||
+ }
|
||||
+
|
||||
+ timings.worldSaveChunks.startTiming(); // Paper
|
||||
+ if (!this.isSavingDisabled()) chunkproviderserver.saveIncrementally();
|
||||
+ timings.worldSaveChunks.stopTiming(); // Paper
|
||||
+
|
||||
+
|
||||
+ // Copied from save()
|
||||
+ // CraftBukkit start - moved from MinecraftServer.saveChunks
|
||||
+ if (doFull) { // Paper
|
||||
+ WorldServer worldserver1 = this;
|
||||
+
|
||||
+ worldDataServer.a(worldserver1.getWorldBorder().t());
|
||||
+ worldDataServer.setCustomBossEvents(this.server.getBossBattleCustomData().save());
|
||||
+ convertable.a(this.server.f, this.worldDataServer, this.server.getPlayerList().save());
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public void save(@Nullable IProgressUpdate iprogressupdate, boolean flag, boolean flag1) {
|
||||
ChunkProviderServer chunkproviderserver = this.getChunkProvider();
|
||||
|
||||
if (!flag1) {
|
||||
- org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit
|
||||
+ if (flag) org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(getWorld())); // CraftBukkit // Paper
|
||||
try (co.aikar.timings.Timing ignored = timings.worldSave.startTiming()) { // Paper
|
||||
if (iprogressupdate != null) {
|
||||
iprogressupdate.a(new ChatMessage("menu.savingLevel"));
|
||||
@@ -0,0 +0,0 @@ public class WorldServer extends World implements GeneratorAccessSeed {
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
+ private void saveData() { this.ag(); } // Paper - OBFHELPER
|
||||
private void ag() {
|
||||
if (this.dragonBattle != null) {
|
||||
this.server.getSaveData().a(this.dragonBattle.a());
|
|
@ -94,7 +94,7 @@ done
|
|||
|
||||
# import FileName
|
||||
|
||||
|
||||
import VoxelShapeSpliterator
|
||||
|
||||
########################################################
|
||||
########################################################
|
||||
|
|
Loading…
Reference in a new issue