13
0
geforkt von Mirrors/Paper

hate jmp and his gradle

Dieser Commit ist enthalten in:
Spottedleaf 2022-06-07 17:15:06 -07:00
Ursprung a4ed02355a
Commit e83c74a0a0
13 geänderte Dateien mit 195 neuen und 171 gelöschten Zeilen

Datei anzeigen

@ -846,16 +846,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ write = this.inProgressWrite; + write = this.inProgressWrite;
+ } + }
+ +
+ // check if another process is writing
+ /*try { TODO: Can we restore this?
+ ((WorldServer)this.world).checkSession();
+ } catch (final Exception ex) {
+ LOGGER.fatal("Couldn't save chunk; already in use by another instance of Minecraft?", ex);
+ // we don't need to set the write counter to -1 as we know at this stage there's no point in re-scheduling
+ // writes since they'll fail anyways.
+ return;
+ }
+*/
+ for (;;) { + for (;;) {
+ final long writeCounter; + final long writeCounter;
+ final CompoundTag data; + final CompoundTag data;
@ -1487,13 +1477,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+import com.destroystokyo.paper.io.IOUtil; +import com.destroystokyo.paper.io.IOUtil;
+import java.util.ArrayDeque; +import java.util.ArrayDeque;
+import java.util.function.Consumer; +import java.util.function.Consumer;
+import com.mojang.logging.LogUtils;
+import net.minecraft.server.level.ChunkMap; +import net.minecraft.server.level.ChunkMap;
+import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerLevel;
+import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.chunk.storage.ChunkSerializer; +import net.minecraft.world.level.chunk.storage.ChunkSerializer;
+import org.slf4j.Logger;
+ +
+public final class ChunkLoadTask extends ChunkTask { +public final class ChunkLoadTask extends ChunkTask {
+ +
+ private static final Logger LOGGER = LogUtils.getLogger();
+
+ public boolean cancelled; + public boolean cancelled;
+ +
+ Consumer<ChunkSerializer.InProgressChunkHolder> onComplete; + Consumer<ChunkSerializer.InProgressChunkHolder> onComplete;
@ -1519,7 +1513,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ try { + try {
+ this.executeTask(); + this.executeTask();
+ } catch (final Throwable ex) { + } catch (final Throwable ex) {
+ PaperFileIOThread.LOGGER.error("Failed to execute chunk load task: " + this.toString(), ex); + LOGGER.error("Failed to execute chunk load task: " + this.toString(), ex);
+ if (!this.hasCompleted) { + if (!this.hasCompleted) {
+ this.complete(ChunkLoadTask.createEmptyHolder()); + this.complete(ChunkLoadTask.createEmptyHolder());
+ } + }
@ -1552,7 +1546,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ final PaperFileIOThread.ChunkData chunkData = this.chunkData; + final PaperFileIOThread.ChunkData chunkData = this.chunkData;
+ +
+ if (chunkData.poiData == PaperFileIOThread.FAILURE_VALUE || chunkData.chunkData == PaperFileIOThread.FAILURE_VALUE) { + if (chunkData.poiData == PaperFileIOThread.FAILURE_VALUE || chunkData.chunkData == PaperFileIOThread.FAILURE_VALUE) {
+ PaperFileIOThread.LOGGER.error("Could not load chunk for task: " + this.toString() + ", file IO thread has dumped the relevant exception above"); + LOGGER.error("Could not load chunk for task: " + this.toString() + ", file IO thread has dumped the relevant exception above");
+ this.complete(ChunkLoadTask.createEmptyHolder()); + this.complete(ChunkLoadTask.createEmptyHolder());
+ return; + return;
+ } + }
@ -1563,6 +1557,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return; + return;
+ } + }
+ +
+ if (!ChunkMap.isChunkDataValid(chunkData.chunkData)) {
+ LOGGER.error("Chunk file at {} is missing level data, skipping", new ChunkPos(this.chunkX, this.chunkZ));
+ this.complete(ChunkLoadTask.createEmptyHolder());
+ return;
+ }
+
+ final ChunkPos chunkPos = new ChunkPos(this.chunkX, this.chunkZ); + final ChunkPos chunkPos = new ChunkPos(this.chunkX, this.chunkZ);
+ +
+ final ChunkMap chunkManager = this.world.getChunkSource().chunkMap; + final ChunkMap chunkManager = this.world.getChunkSource().chunkMap;
@ -1576,7 +1576,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ chunkData.chunkData = chunkManager.upgradeChunkTag(this.world.getTypeKey(), + chunkData.chunkData = chunkManager.upgradeChunkTag(this.world.getTypeKey(),
+ chunkManager.overworldDataStorage, chunkData.chunkData, chunkManager.generator.getTypeNameForDataFixer(), chunkPos, this.world); // clone data for safety, file IO thread does not clone + chunkManager.overworldDataStorage, chunkData.chunkData, chunkManager.generator.getTypeNameForDataFixer(), chunkPos, this.world); // clone data for safety, file IO thread does not clone
+ } catch (final Throwable ex) { + } catch (final Throwable ex) {
+ PaperFileIOThread.LOGGER.error("Could not apply datafixers for chunk task: " + this.toString(), ex); + LOGGER.error("Could not apply datafixers for chunk task: " + this.toString(), ex);
+ this.complete(ChunkLoadTask.createEmptyHolder()); + this.complete(ChunkLoadTask.createEmptyHolder());
+ return; + return;
+ } + }
@ -1589,7 +1589,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ chunkHolder = ChunkSerializer.loadChunk(this.world, chunkManager.getPoiManager(), chunkPos, + chunkHolder = ChunkSerializer.loadChunk(this.world, chunkManager.getPoiManager(), chunkPos,
+ chunkData.chunkData, true); + chunkData.chunkData, true);
+ } catch (final Throwable ex) { + } catch (final Throwable ex) {
+ PaperFileIOThread.LOGGER.error("Could not de-serialize chunk data for task: " + this.toString(), ex); + LOGGER.error("Could not de-serialize chunk data for task: " + this.toString(), ex);
+ this.complete(ChunkLoadTask.createEmptyHolder()); + this.complete(ChunkLoadTask.createEmptyHolder());
+ return; + return;
+ } + }
@ -1612,7 +1612,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ try { + try {
+ ChunkLoadTask.this.onComplete.accept(holder); + ChunkLoadTask.this.onComplete.accept(holder);
+ } catch (final Throwable thr) { + } catch (final Throwable thr) {
+ PaperFileIOThread.LOGGER.error("Failed to complete chunk data for task: " + this.toString(), thr); + LOGGER.error("Failed to complete chunk data for task: " + this.toString(), thr);
+ } + }
+ return null; + return null;
+ }); + });
@ -2315,7 +2315,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
*/ */
+ Class.forName(net.minecraft.world.entity.npc.VillagerTrades.class.getName());// Paper - load this sync so it won't fail later async + Class.forName(net.minecraft.world.entity.npc.VillagerTrades.class.getName());// Paper - load this sync so it won't fail later async
final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.spin((thread) -> { final DedicatedServer dedicatedserver = (DedicatedServer) MinecraftServer.spin((thread) -> {
DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, config.get(), ops.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), minecraftsessionservice, gameprofilerepository, usercache, LoggerChunkProgressListener::new); DedicatedServer dedicatedserver1 = new DedicatedServer(optionset, config.get(), ops.get(), thread, convertable_conversionsession, resourcepackrepository, worldstem, dedicatedserversettings, DataFixers.getDataFixer(), services, LoggerChunkProgressListener::new);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.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 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
@ -2330,19 +2330,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
public String getLocalIp() { public String getLocalIp() {
diff --git a/src/main/java/net/minecraft/server/level/ChunkHolder.java b/src/main/java/net/minecraft/server/level/ChunkHolder.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkHolder.java
+++ b/src/main/java/net/minecraft/server/level/ChunkHolder.java
@@ -0,0 +0,0 @@ public class ChunkHolder {
ChunkStatus chunkstatus = ChunkHolder.getStatus(this.oldTicketLevel);
ChunkStatus chunkstatus1 = ChunkHolder.getStatus(this.ticketLevel);
boolean flag = this.oldTicketLevel <= ChunkMap.MAX_CHUNK_DISTANCE;
- boolean flag1 = this.ticketLevel <= ChunkMap.MAX_CHUNK_DISTANCE;
+ boolean flag1 = this.ticketLevel <= ChunkMap.MAX_CHUNK_DISTANCE; // Paper - diff on change: (flag1 = new ticket level is in loadable range)
ChunkHolder.FullChunkStatus playerchunk_state = ChunkHolder.getFullChunkStatus(this.oldTicketLevel);
ChunkHolder.FullChunkStatus playerchunk_state1 = ChunkHolder.getFullChunkStatus(this.ticketLevel);
// CraftBukkit start
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java --- a/src/main/java/net/minecraft/server/level/ChunkMap.java
@ -2403,41 +2390,32 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> scheduleChunkLoad(ChunkPos pos) { private CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> scheduleChunkLoad(ChunkPos pos) {
- return CompletableFuture.supplyAsync(() -> { - return this.readChunk(pos).thenApply((optional) -> {
- return optional.filter((nbttagcompound) -> {
- boolean flag = ChunkMap.isChunkDataValid(nbttagcompound);
+ // Paper start - Async chunk io + // Paper start - Async chunk io
+ final java.util.function.BiFunction<ChunkSerializer.InProgressChunkHolder, Throwable, Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> syncLoadComplete = (chunkHolder, ioThrowable) -> { + final java.util.function.BiFunction<ChunkSerializer.InProgressChunkHolder, Throwable, Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> syncLoadComplete = (chunkHolder, ioThrowable) -> {
try (Timing ignored = this.level.timings.chunkLoad.startTimingIfSync()) { // Paper + try (Timing ignored = this.level.timings.chunkLoad.startTimingIfSync()) { // Paper
this.level.getProfiler().incrementCounter("chunkLoad"); + this.level.getProfiler().incrementCounter("chunkLoad");
- CompoundTag nbttagcompound; // Paper
- try (Timing ignored2 = this.level.timings.chunkIO.startTimingIfSync()) { // Paper start - timings
- nbttagcompound = this.readChunk(pos);
- } // Paper end
-
- if (nbttagcompound != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings
- boolean flag = nbttagcompound.contains("Status", 8);
-
- if (flag) {
- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.poiManager, pos, nbttagcompound);
+ // Paper start
+ if (ioThrowable != null) { + if (ioThrowable != null) {
+ com.destroystokyo.paper.util.SneakyThrow.sneaky(ioThrowable); + return this.handleChunkLoadFailure(ioThrowable, pos);
+ } + }
+ this.poiManager.loadInData(pos, chunkHolder.poiData); + this.poiManager.loadInData(pos, chunkHolder.poiData);
+ chunkHolder.tasks.forEach(Runnable::run); + chunkHolder.tasks.forEach(Runnable::run);
+ // Paper end
+ if (chunkHolder.protoChunk != null) {try (Timing ignored2 = this.level.timings.chunkLoadLevelTimer.startTimingIfSync()) { // Paper start - timings // Paper - chunk is created async - if (!flag) {
+ if (true) { - ChunkMap.LOGGER.error("Chunk file at {} is missing level data, skipping", pos);
+ ProtoChunk protochunk = chunkHolder.protoChunk; + if (chunkHolder.protoChunk != null) {
this.markPosition(pos, protochunk.getStatus().getChunkType()); + ProtoChunk protochunk = chunkHolder.protoChunk;
return Either.left(protochunk); + this.markPosition(pos, protochunk.getStatus().getChunkType());
} + return Either.left(protochunk);
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider }
+ } catch (Exception ex) {
+ return this.handleChunkLoadFailure(ex, pos);
+ }
this.markPositionReplaceable(pos); - return flag;
return Either.left(new ProtoChunk(pos, UpgradeData.EMPTY, this.level, this.level.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY), (BlendingData) null)); + return Either.left(this.createEmptyChunk(pos));
- }, this.mainThreadExecutor);
+ // Paper start - Async chunk io
+ }; + };
+ CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> ret = new CompletableFuture<>(); + CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> ret = new CompletableFuture<>();
+ +
@ -2449,9 +2427,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } catch (Exception e) { + } catch (Exception e) {
+ ret.completeExceptionally(e); + ret.completeExceptionally(e);
+ } + }
+ }); });
- }).thenApplyAsync((optional) -> {
- this.level.getProfiler().incrementCounter("chunkLoad");
- if (optional.isPresent()) {
- ProtoChunk protochunk = ChunkSerializer.read(this.level, this.poiManager, pos, (CompoundTag) optional.get());
+ }; + };
+
- this.markPosition(pos, protochunk.getStatus().getChunkType());
- return Either.<ChunkAccess, ChunkHolder.ChunkLoadingFailure>left(protochunk); // CraftBukkit - decompile error
- } else {
- return Either.<ChunkAccess, ChunkHolder.ChunkLoadingFailure>left(this.createEmptyChunk(pos)); // CraftBukkit - decompile error
- }
- }, this.mainThreadExecutor).exceptionallyAsync((throwable) -> {
- return this.handleChunkLoadFailure(throwable, pos);
- }, this.mainThreadExecutor);
+ CompletableFuture<CompoundTag> chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z); + CompletableFuture<CompoundTag> chunkSaveFuture = this.level.asyncChunkTaskManager.getChunkSaveFuture(pos.x, pos.z);
+ if (chunkSaveFuture != null) { + if (chunkSaveFuture != null) {
+ this.level.asyncChunkTaskManager.scheduleChunkLoad(pos.x, pos.z, + this.level.asyncChunkTaskManager.scheduleChunkLoad(pos.x, pos.z,
@ -2462,10 +2452,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY, chunkHolderConsumer, false); + com.destroystokyo.paper.io.PrioritizedTaskQueue.NORMAL_PRIORITY, chunkHolderConsumer, false);
+ } + }
+ return ret; + return ret;
+ // Paper end + // Paper end - Async chunk io
}
- private static boolean isChunkDataValid(CompoundTag nbt) {
+ public static boolean isChunkDataValid(CompoundTag nbt) { // Paper - async chunk loading
return nbt.contains("Status", 8);
} }
private void markPositionReplaceable(ChunkPos pos) {
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
} }
} }
@ -2557,7 +2551,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - Asynchronous chunk io + // Paper start - Asynchronous chunk io
+ @Nullable + @Nullable
+ @Override + @Override
+ public CompoundTag read(ChunkPos chunkcoordintpair) throws IOException { + public CompoundTag readSync(ChunkPos chunkcoordintpair) throws IOException {
+ if (Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) { + if (Thread.currentThread() != com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE) {
+ CompoundTag ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE + CompoundTag ret = com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE
+ .loadChunkDataAsyncFuture(this.level, chunkcoordintpair.x, chunkcoordintpair.z, com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread(), + .loadChunkDataAsyncFuture(this.level, chunkcoordintpair.x, chunkcoordintpair.z, com.destroystokyo.paper.io.IOUtil.getPriorityForCurrentThread(),
@ -2568,7 +2562,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ return ret; + return ret;
+ } + }
+ return super.read(chunkcoordintpair); + return super.readSync(chunkcoordintpair);
+ } + }
+ +
+ @Override + @Override
@ -2583,9 +2577,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ } + }
+ // Paper end + // Paper end
+ +
@Nullable private CompletableFuture<Optional<CompoundTag>> readChunk(ChunkPos chunkPos) {
public CompoundTag readChunk(ChunkPos pos) throws IOException { return this.read(chunkPos).thenApplyAsync((optional) -> {
CompoundTag nbttagcompound = this.read(pos); return optional.map((nbttagcompound) -> this.upgradeChunkTag(nbttagcompound, chunkPos)); // CraftBukkit
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java --- a/src/main/java/net/minecraft/server/level/DistanceManager.java
@ -2814,7 +2808,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ @Override + @Override
+ public net.minecraft.nbt.CompoundTag readData(int x, int z) throws java.io.IOException { + public net.minecraft.nbt.CompoundTag readData(int x, int z) throws java.io.IOException {
+ return ServerLevel.this.getChunkSource().chunkMap.read(new ChunkPos(x, z)); + return ServerLevel.this.getChunkSource().chunkMap.readSync(new ChunkPos(x, z));
+ } + }
+ +
+ @Override + @Override
@ -2843,7 +2837,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager; + public final com.destroystokyo.paper.io.chunk.ChunkTaskManager asyncChunkTaskManager;
// Paper end // Paper end
// Add env and gen to constructor, WorldData -> WorldDataServer // Add env and gen to constructor, IWorldDataServer -> WorldDataServer
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel { @@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.sleepStatus = new SleepStatus(); this.sleepStatus = new SleepStatus();
@ -2870,13 +2864,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java --- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser @@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]))); // Paper server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper
return; return;
} }
+ // Paper start + // Paper start
+ String str = packet.getCommand(); int index = -1; + String str = packet.getCommand(); int index = -1;
+ if (str.length() > 64 && ((index = str.indexOf(' ')) == -1 || index >= 64)) { + if (str.length() > 64 && ((index = str.indexOf(' ')) == -1 || index >= 64)) {
+ server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]))); // Paper + server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper
+ return; + return;
+ } + }
+ // Paper end + // Paper end
@ -2893,8 +2887,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private final LongSet loadedChunks = new LongOpenHashSet(); private final LongSet loadedChunks = new LongOpenHashSet();
+ private final net.minecraft.server.level.ServerLevel world; // Paper + private final net.minecraft.server.level.ServerLevel world; // Paper
public PoiManager(Path path, DataFixer dataFixer, boolean dsync, LevelHeightAccessor world) { public PoiManager(Path path, DataFixer dataFixer, boolean dsync, RegistryAccess registryManager, LevelHeightAccessor world) {
super(path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, world); super(path, PoiSection::codec, PoiSection::new, dataFixer, DataFixTypes.POI_CHUNK, dsync, registryManager, world);
+ this.world = (net.minecraft.server.level.ServerLevel)world; // Paper + this.world = (net.minecraft.server.level.ServerLevel)world; // Paper
this.distanceTracker = new PoiManager.DistanceTracker(); this.distanceTracker = new PoiManager.DistanceTracker();
} }
@ -2992,17 +2986,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (!Objects.equals(chunkPos, chunkcoordintpair1)) { if (!Objects.equals(chunkPos, chunkcoordintpair1)) {
@@ -0,0 +0,0 @@ public class ChunkSerializer { @@ -0,0 +0,0 @@ public class ChunkSerializer {
LevelLightEngine lightengine = chunkproviderserver.getLightEngine(); LevelChunkSection chunksection = new LevelChunkSection(b0, datapaletteblock, (PalettedContainer) object); // CraftBukkit - read/write
if (flag) {
+ tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main
lightengine.retainData(chunkPos, true);
+ }); // Paper - delay this task since we're executing off-main
}
Registry<Biome> iregistry = world.registryAccess().registryOrThrow(Registry.BIOME_REGISTRY);
@@ -0,0 +0,0 @@ public class ChunkSerializer {
LevelChunkSection chunksection = new LevelChunkSection(b0, datapaletteblock, datapaletteblock1);
achunksection[k] = chunksection; achunksection[k] = chunksection;
+ tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main + tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main
@ -3010,23 +2994,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ }); // Paper - delay this task since we're executing off-main + }); // Paper - delay this task since we're executing off-main
} }
if (flag) { boolean flag3 = nbttagcompound1.contains("BlockLight", 7);
if (nbttagcompound1.contains("BlockLight", 7)) { @@ -0,0 +0,0 @@ public class ChunkSerializer {
if (flag3 || flag4) {
if (!flag2) {
+ tasksToExecuteOnMain.add(() -> { // Paper - delay this task since we're executing off-main
lightengine.retainData(chunkPos, true);
+ }); // Paper - delay this task since we're executing off-main
flag2 = true;
}
if (flag3) {
- lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("BlockLight")), true); - lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("BlockLight")), true);
+ // Paper start - delay this task since we're executing off-main + // Paper start - delay this task since we're executing off-main
+ DataLayer blockLight = new DataLayer(nbttagcompound1.getByteArray("BlockLight")); + DataLayer blockLight = new DataLayer(nbttagcompound1.getByteArray("BlockLight").clone());
+ tasksToExecuteOnMain.add(() -> { + tasksToExecuteOnMain.add(() -> {
+ lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkcoordintpair1, b0), blockLight, true); + lightengine.queueSectionData(LightLayer.BLOCK, SectionPos.of(chunkPos, b0), blockLight, true);
+ }); + });
+ // Paper end - delay this task since we're executing off-main + // Paper end - delay this task since we're executing off-main
} }
if (flag1 && nbttagcompound1.contains("SkyLight", 7)) { if (flag4) {
- lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("SkyLight")), true); - lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, b0), new DataLayer(nbttagcompound1.getByteArray("SkyLight")), true);
+ // Paper start - delay this task since we're executing off-main + // Paper start - delay this task since we're executing off-main
+ DataLayer skyLight = new DataLayer(nbttagcompound1.getByteArray("SkyLight")); + DataLayer skyLight = new DataLayer(nbttagcompound1.getByteArray("SkyLight").clone());
+ tasksToExecuteOnMain.add(() -> { + tasksToExecuteOnMain.add(() -> {
+ lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkcoordintpair1, b0), skyLight, true); + lightengine.queueSectionData(LightLayer.SKY, SectionPos.of(chunkPos, b0), skyLight, true);
+ }); + });
+ // Paper end - delay this task since we're executing off-mai + // Paper end - delay this task since we're executing off-mai
} }
@ -3036,13 +3030,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
if (chunkstatus_type == ChunkStatus.ChunkType.LEVELCHUNK) { if (chunkstatus_type == ChunkStatus.ChunkType.LEVELCHUNK) {
- return new ImposterProtoChunk((LevelChunk) object, false); - return new ImposterProtoChunk((LevelChunk) object1, false);
+ return new InProgressChunkHolder(new ImposterProtoChunk((LevelChunk) object, false), tasksToExecuteOnMain); // Paper - Async chunk loading + return new InProgressChunkHolder(new ImposterProtoChunk((LevelChunk) object1, false), tasksToExecuteOnMain); // Paper - Async chunk loading
} else { } else {
ProtoChunk protochunk1 = (ProtoChunk) object; ProtoChunk protochunk1 = (ProtoChunk) object1;
@@ -0,0 +0,0 @@ public class ChunkSerializer { @@ -0,0 +0,0 @@ public class ChunkSerializer {
protochunk1.setCarvingMask(worldgenstage_features, new CarvingMask(nbttagcompound4.getLongArray(s1), ((ChunkAccess) object).getMinBuildHeight())); protochunk1.setCarvingMask(worldgenstage_features, new CarvingMask(nbttagcompound4.getLongArray(s1), ((ChunkAccess) object1).getMinBuildHeight()));
} }
- return protochunk1; - return protochunk1;
@ -3111,7 +3105,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
private static void logErrors(ChunkPos chunkPos, int y, String message) { private static void logErrors(ChunkPos chunkPos, int y, String message) {
ChunkSerializer.LOGGER.error("Recoverable errors when loading section [" + chunkPos.x + ", " + y + ", " + chunkPos.z + "]: " + message); ChunkSerializer.LOGGER.error("Recoverable errors when loading section [" + chunkPos.x + ", " + y + ", " + chunkPos.z + "]: " + message);
@@ -0,0 +0,0 @@ public class ChunkSerializer { @@ -0,0 +0,0 @@ public class ChunkSerializer {
} // CraftBukkit end
public static CompoundTag write(ServerLevel world, ChunkAccess chunk) { public static CompoundTag write(ServerLevel world, ChunkAccess chunk) {
+ // Paper start + // Paper start
@ -3198,9 +3192,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper - nuke IO worker + // Paper - nuke IO worker
protected final DataFixer fixerUpper; protected final DataFixer fixerUpper;
@Nullable @Nullable
- private LegacyStructureDataHandler legacyStructureHandler; private volatile LegacyStructureDataHandler legacyStructureHandler;
+ // Paper start - async chunk loading + // Paper start - async chunk loading
+ private volatile LegacyStructureDataHandler legacyStructureHandler;
+ private final Object persistentDataLock = new Object(); // Paper + private final Object persistentDataLock = new Object(); // Paper
+ public final RegionFileStorage regionFileCache; + public final RegionFileStorage regionFileCache;
+ // Paper end - async chunk loading + // Paper end - async chunk loading
@ -3214,8 +3207,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper end - async chunk io + // Paper end - async chunk io
} }
public boolean isOldChunkAround(ChunkPos chunkPos, int checkRadius) {
- return this.worker.isOldChunkAround(chunkPos, checkRadius);
+ return true; // Paper - (for now, old unoptimised behavior) TODO implement later? the chunk status that blender uses SHOULD already have this radius loaded, no need to go back for it...
}
// CraftBukkit start // CraftBukkit start
private boolean check(ServerChunkCache cps, int x, int z) throws IOException { private boolean check(ServerChunkCache cps, int x, int z) {
ChunkPos pos = new ChunkPos(x, z); ChunkPos pos = new ChunkPos(x, z);
if (cps != null) { if (cps != null) {
- com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread"); - com.google.common.base.Preconditions.checkState(org.bukkit.Bukkit.isPrimaryThread(), "primary thread");
@ -3225,19 +3223,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
return true; return true;
} }
} }
- CompoundTag nbt = this.read(pos);
+ // Paper start - prioritize
+ CompoundTag nbt = cps == null ? read(pos) :
+ com.destroystokyo.paper.io.PaperFileIOThread.Holder.INSTANCE.loadChunkData((ServerLevel)cps.getLevel(), x, z,
+ com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGHER_PRIORITY, false, true).chunkData;
+ // Paper end
if (nbt != null) {
CompoundTag level = nbt.getCompound("Level");
if (level.getBoolean("TerrainPopulated")) {
@@ -0,0 +0,0 @@ public class ChunkStorage implements AutoCloseable { @@ -0,0 +0,0 @@ public class ChunkStorage implements AutoCloseable {
public CompoundTag upgradeChunkTag(ResourceKey<LevelStem> resourcekey, Supplier<DimensionDataStorage> supplier, CompoundTag nbttagcompound, Optional<ResourceKey<Codec<? extends ChunkGenerator>>> optional, ChunkPos pos, @Nullable LevelAccessor generatoraccess) throws IOException { public CompoundTag upgradeChunkTag(ResourceKey<LevelStem> resourcekey, Supplier<DimensionDataStorage> supplier, CompoundTag nbttagcompound, Optional<ResourceKey<Codec<? extends ChunkGenerator>>> optional, ChunkPos pos, @Nullable LevelAccessor generatoraccess) {
// CraftBukkit end // CraftBukkit end
+ nbttagcompound = nbttagcompound.copy(); // Paper - defensive copy, another thread might modify this + nbttagcompound = nbttagcompound.copy(); // Paper - defensive copy, another thread might modify this
int i = ChunkStorage.getVersion(nbttagcompound); int i = ChunkStorage.getVersion(nbttagcompound);
@ -3248,23 +3236,40 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
nbttagcompound = NbtUtils.update(this.fixerUpper, DataFixTypes.CHUNK, nbttagcompound, i, 1493); nbttagcompound = NbtUtils.update(this.fixerUpper, DataFixTypes.CHUNK, nbttagcompound, i, 1493);
if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) { if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
+ synchronized (this.persistentDataLock) { // Paper - Async chunk loading + synchronized (this.persistentDataLock) { // Paper - Async chunk loading
if (this.legacyStructureHandler == null) { LegacyStructureDataHandler persistentstructurelegacy = this.getLegacyStructureHandler(resourcekey, supplier);
this.legacyStructureHandler = LegacyStructureDataHandler.getLegacyStructureHandler(resourcekey, (DimensionDataStorage) supplier.get());
}
nbttagcompound = this.legacyStructureHandler.updateFromLegacy(nbttagcompound); nbttagcompound = persistentstructurelegacy.updateFromLegacy(nbttagcompound);
+ } // Paper - Async chunk loading + } // Paper - Async chunk loading
} }
} }
@@ -0,0 +0,0 @@ public class ChunkStorage implements AutoCloseable { @@ -0,0 +0,0 @@ public class ChunkStorage implements AutoCloseable {
LegacyStructureDataHandler persistentstructurelegacy = this.legacyStructureHandler;
@Nullable if (persistentstructurelegacy == null) {
public CompoundTag read(ChunkPos chunkPos) throws IOException { - synchronized (this) {
- return this.worker.load(chunkPos); + synchronized (this.persistentDataLock) { // Paper - async chunk loading
+ return this.regionFileCache.read(chunkPos); // Paper - async chunk io persistentstructurelegacy = this.legacyStructureHandler;
if (persistentstructurelegacy == null) {
this.legacyStructureHandler = persistentstructurelegacy = LegacyStructureDataHandler.getLegacyStructureHandler(resourcekey, (DimensionDataStorage) supplier.get());
@@ -0,0 +0,0 @@ public class ChunkStorage implements AutoCloseable {
} }
public CompletableFuture<Optional<CompoundTag>> read(ChunkPos chunkPos) {
- return this.worker.loadAsync(chunkPos);
+ // Paper start - async chunk io
+ try {
+ return CompletableFuture.completedFuture(Optional.ofNullable(this.readSync(chunkPos)));
+ } catch (Throwable thr) {
+ return CompletableFuture.failedFuture(thr);
+ }
+ }
+ @Nullable
+ public CompoundTag readSync(ChunkPos chunkPos) throws IOException {
+ return this.regionFileCache.read(chunkPos);
}
+ // Paper end - async chunk io
- public void write(ChunkPos chunkPos, CompoundTag nbt) { - public void write(ChunkPos chunkPos, CompoundTag nbt) {
- this.worker.store(chunkPos, nbt); - this.worker.store(chunkPos, nbt);
+ // Paper start - async chunk io + // Paper start - async chunk io
@ -3475,12 +3480,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable { @@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
protected final LevelHeightAccessor levelHeightAccessor; protected final LevelHeightAccessor levelHeightAccessor;
public SectionStorage(Path path, Function<Runnable, Codec<R>> codecFactory, Function<Runnable, R> factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, LevelHeightAccessor world) { public SectionStorage(Path path, Function<Runnable, Codec<R>> codecFactory, Function<Runnable, R> factory, DataFixer dataFixer, DataFixTypes dataFixTypes, boolean dsync, RegistryAccess dynamicRegistryManager, LevelHeightAccessor world) {
+ super(path, dsync); + super(path, dsync); // Paper - remove mojang I/O thread
this.codec = codecFactory; this.codec = codecFactory;
this.factory = factory; this.factory = factory;
this.fixerUpper = dataFixer; this.fixerUpper = dataFixer;
this.type = dataFixTypes; this.type = dataFixTypes;
this.registryAccess = dynamicRegistryManager;
this.levelHeightAccessor = world; this.levelHeightAccessor = world;
- this.worker = new IOWorker(path, dsync, path.getFileName().toString()); - this.worker = new IOWorker(path, dsync, path.getFileName().toString());
+ // Paper - remove mojang I/O thread + // Paper - remove mojang I/O thread
@ -3490,34 +3496,43 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable { @@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
} }
private void readColumn(ChunkPos chunkPos) { private CompletableFuture<Optional<CompoundTag>> tryRead(ChunkPos pos) {
- this.readColumn(chunkPos, NbtOps.INSTANCE, this.tryRead(chunkPos)); - return this.worker.loadAsync(pos).exceptionally((throwable) -> {
+ // Paper start - expose function to load in data - if (throwable instanceof IOException iOException) {
+ this.loadInData(chunkPos, this.tryRead(chunkPos)); - LOGGER.error("Error reading chunk {} data from disk", pos, iOException);
- return Optional.empty();
- } else {
- throw new CompletionException(throwable);
- }
- });
+ // Paper start - async chunk io
+ try {
+ return CompletableFuture.completedFuture(Optional.ofNullable(this.read(pos)));
+ } catch (Throwable thr) {
+ return CompletableFuture.failedFuture(thr);
+ }
+ // Paper end - async chunk io
+ } + }
+
+ // Paper start - async chunk io
+ public void loadInData(ChunkPos chunkPos, CompoundTag compound) { + public void loadInData(ChunkPos chunkPos, CompoundTag compound) {
+ this.readColumn(chunkPos, NbtOps.INSTANCE, compound); + this.readColumn(chunkPos, NbtOps.INSTANCE, compound);
+ // Paper end - expose function to load in data
} }
+ // Paper end - aync chnnk i
@Nullable private <T> void readColumn(ChunkPos pos, DynamicOps<T> ops, @Nullable T data) {
private CompoundTag tryRead(ChunkPos pos) { if (data == null) {
try {
- return this.worker.load(pos);
+ return this.read(pos); // Paper - nuke IOWorker
} catch (IOException var3) {
LOGGER.error("Error reading chunk {} data from disk", pos, var3);
return null;
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable { @@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
Dynamic<Tag> dynamic = this.writeColumn(chunkPos, NbtOps.INSTANCE); Dynamic<Tag> dynamic = this.writeColumn(pos, registryOps);
Tag tag = dynamic.getValue(); Tag tag = dynamic.getValue();
if (tag instanceof CompoundTag) { if (tag instanceof CompoundTag) {
- this.worker.store(chunkPos, (CompoundTag)tag); - this.worker.store(pos, (CompoundTag)tag);
+ try { this.write(chunkPos, (CompoundTag)tag); } catch (IOException ioexception) { SectionStorage.LOGGER.error("Error writing data to disk", ioexception); } // Paper - nuke IOWorker + try { this.write(pos, (CompoundTag)tag); } catch (IOException ioexception) { SectionStorage.LOGGER.error("Error writing data to disk", ioexception); } // Paper - nuke IOWorker
} else { } else {
LOGGER.error("Expected compound tag, got {}", (Object)tag); LOGGER.error("Expected compound tag, got {}", (Object)tag);
} }
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
return new Dynamic<>(ops, ops.createMap(ImmutableMap.of(ops.createString("Sections"), ops.createMap(map), ops.createString("DataVersion"), ops.createInt(SharedConstants.getCurrentVersion().getWorldVersion()))));
} }
+ // Paper start - internal get data function, copied from above + // Paper start - internal get data function, copied from above
@ -3533,9 +3548,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ return null; + return null;
+ } + }
+ // Paper end + // Paper end
private <T> Dynamic<T> writeColumn(ChunkPos chunkPos, DynamicOps<T> dynamicOps) { +
Map<T, T> map = Maps.newHashMap(); private static long getKey(ChunkPos chunkPos, int y) {
return SectionPos.asLong(chunkPos.x, y, chunkPos.z);
}
@@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable { @@ -0,0 +0,0 @@ public class SectionStorage<R> implements AutoCloseable {
@Override @Override
@ -3604,14 +3620,6 @@ diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -0,0 +0,0 @@ import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ChunkMap;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
+import net.minecraft.server.level.TicketType;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.AreaEffectCloud;
import net.minecraft.world.entity.Entity;
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
this.entity.setYHeadRot(yaw); this.entity.setYHeadRot(yaw);
} }

Datei anzeigen

@ -22,6 +22,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
public int cookingProgress; public int cookingProgress;
public int cookingTotalTime; public int cookingTotalTime;
protected final ContainerData dataAccess; protected final ContainerData dataAccess;
public final Object2IntOpenHashMap<ResourceLocation> recipesUsed;
private final RecipeManager.CachedCheck<Container, ? extends AbstractCookingRecipe> quickCheck;
+ public final RecipeType<? extends AbstractCookingRecipe> recipeType; // Paper
protected AbstractFurnaceBlockEntity(BlockEntityType<?> blockEntityType, BlockPos pos, BlockState state, RecipeType<? extends AbstractCookingRecipe> recipeType) {
super(blockEntityType, pos, state);
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
};
this.recipesUsed = new Object2IntOpenHashMap();
this.quickCheck = RecipeManager.createCheck((RecipeType<AbstractCookingRecipe>) recipeType); // CraftBukkit - decompile error // Eclipse fail
+ this.recipeType = recipeType; // Paper
}
public static Map<Item, Integer> getFuel() {
@@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit @@ -0,0 +0,0 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
this.recipesUsed.put(new ResourceLocation(s), nbttagcompound1.getInt(s)); this.recipesUsed.put(new ResourceLocation(s), nbttagcompound1.getInt(s));
} }
@ -58,8 +72,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- if (blockEntity.cookingProgress == blockEntity.cookingTotalTime) { - if (blockEntity.cookingProgress == blockEntity.cookingTotalTime) {
+ if (blockEntity.cookingProgress >= blockEntity.cookingTotalTime) { // Paper - cook speed multiplier API + if (blockEntity.cookingProgress >= blockEntity.cookingTotalTime) { // Paper - cook speed multiplier API
blockEntity.cookingProgress = 0; blockEntity.cookingProgress = 0;
- blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity.recipeType, blockEntity); - blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity);
+ blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity.recipeType, blockEntity, blockEntity.cookSpeedMultiplier); + blockEntity.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(world, blockEntity.recipeType, blockEntity, blockEntity.cookSpeedMultiplier); // Paper
if (AbstractFurnaceBlockEntity.burn(blockEntity.level, blockEntity.worldPosition, irecipe, blockEntity.items, i)) { // CraftBukkit if (AbstractFurnaceBlockEntity.burn(blockEntity.level, blockEntity.worldPosition, irecipe, blockEntity.items, i)) { // CraftBukkit
blockEntity.setRecipeUsed(irecipe); blockEntity.setRecipeUsed(irecipe);
} }
@ -67,12 +81,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
} }
- private static int getTotalCookTime(Level world, RecipeType<? extends AbstractCookingRecipe> recipeType, Container inventory) { - private static int getTotalCookTime(Level world, AbstractFurnaceBlockEntity furnace) {
- return (world != null) ? (Integer) world.getRecipeManager().getRecipeFor((RecipeType<AbstractCookingRecipe>) recipeType, inventory, world).map(AbstractCookingRecipe::getCookingTime).orElse(200) : 200; // CraftBukkit - SPIGOT-4302 // Eclipse fail - return (world != null) ? (Integer) furnace.quickCheck.getRecipeFor(furnace, world).map(AbstractCookingRecipe::getCookingTime).orElse(200) : 200; // CraftBukkit - SPIGOT-4302
+ // Paper begin - Expose this function so CraftFurnace can correctly scale the total cooking time to a new multiplier + // Paper start
+ public static int getTotalCookTime(@Nullable Level world, RecipeType<? extends AbstractCookingRecipe> recipeType, Container inventory, final double cookSpeedMultiplier) { + public static int getTotalCookTime(Level world, RecipeType<? extends AbstractCookingRecipe> recipeType, AbstractFurnaceBlockEntity furnace, double cookSpeedMultiplier) {
+ /* Scale the recipe's cooking time to the current cookSpeedMultiplier */ + /* Scale the recipe's cooking time to the current cookSpeedMultiplier */
+ int cookTime = (world != null ? world.getRecipeManager() : net.minecraft.server.MinecraftServer.getServer().getRecipeManager()).getRecipeFor(recipeType, inventory, world /* passing a null level here is safe. world is only used for map extending recipes which won't happen here */).map(AbstractCookingRecipe::getCookingTime).orElse(200); // CraftBukkit - SPIGOT-4302 // Eclipse fail + int cookTime = world == null ? furnace.quickCheck.getRecipeFor(furnace, world).map(AbstractCookingRecipe::getCookingTime).orElse(200) : (net.minecraft.server.MinecraftServer.getServer().getRecipeManager().getRecipeFor(recipeType, furnace, world /* passing a null level here is safe. world is only used for map extending recipes which won't happen here */).map(AbstractCookingRecipe::getCookingTime).orElse(200));
+ return (int) Math.ceil (cookTime / cookSpeedMultiplier); + return (int) Math.ceil (cookTime / cookSpeedMultiplier);
} }
+ // Paper end + // Paper end
@ -83,8 +97,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
} }
if (slot == 0 && !flag) { if (slot == 0 && !flag) {
- this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.level, this.recipeType, this); - this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.level, this);
+ this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.level, this.recipeType, this, this.cookSpeedMultiplier); + this.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.level, this.recipeType, this, this.cookSpeedMultiplier); // Paper
this.cookingProgress = 0; this.cookingProgress = 0;
this.setChanged(); this.setChanged();
} }

Datei anzeigen

@ -101,12 +101,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
this.playHurtSound(source); this.playHurtSound(source);
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { @@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
if (!this.isRemoved() && !this.dead) { if (!this.isRemoved() && !this.dead) {
Entity entity = source.getEntity(); Entity entity = damageSource.getEntity();
LivingEntity entityliving = this.getKillCredit(); LivingEntity entityliving = this.getKillCredit();
- -
+ /* // Paper - move down to make death event cancellable - this is the awardKillScore below + /* // Paper - move down to make death event cancellable - this is the awardKillScore below
if (this.deathScore >= 0 && entityliving != null) { if (this.deathScore >= 0 && entityliving != null) {
entityliving.awardKillScore(this, this.deathScore, source); entityliving.awardKillScore(this, this.deathScore, damageSource);
} }
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity { @@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity {
if (!this.level.isClientSide && this.hasCustomName()) { if (!this.level.isClientSide && this.hasCustomName()) {
@ -118,17 +118,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- this.getCombatTracker().recheckStatus(); - this.getCombatTracker().recheckStatus();
+ // Paper - moved into if below + // Paper - moved into if below
if (this.level instanceof ServerLevel) { if (this.level instanceof ServerLevel) {
if (entity != null) { - if (entity == null || entity.wasKilled((ServerLevel) this.level, this)) {
- entity.killed((ServerLevel) this.level, this); + // Paper - move below into if for onKill
+ // Paper - move below into if for onKill +
}
- this.dropAllDeathLoot(source);
+ // Paper start + // Paper start
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(source); + org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(damageSource);
+ if (deathEvent == null || !deathEvent.isCancelled()) { + if (deathEvent == null || !deathEvent.isCancelled()) {
+ if (this.deathScore >= 0 && entityliving != null) { + if (this.deathScore >= 0 && entityliving != null) {
+ entityliving.awardKillScore(this, this.deathScore, source); + entityliving.awardKillScore(this, this.deathScore, damageSource);
+ } + }
+ // Paper start - clear equipment if event is not cancelled + // Paper start - clear equipment if event is not cancelled
+ if (this instanceof Mob) { + if (this instanceof Mob) {
@ -149,18 +146,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ +
+ this.getCombatTracker().recheckStatus(); + this.getCombatTracker().recheckStatus();
+ if (entity != null) { + if (entity != null) {
+ entity.killed((ServerLevel) this.level, this); + entity.wasKilled((ServerLevel) this.level, this);
+ } + }
this.gameEvent(GameEvent.ENTITY_DIE);
- this.dropAllDeathLoot(damageSource);
- this.createWitherRose(entityliving);
+ } else { + } else {
+ this.dead = false; + this.dead = false;
+ this.setHealth((float) deathEvent.getReviveHealth()); + this.setHealth((float) deathEvent.getReviveHealth());
+ } }
-
- this.level.broadcastEntityEvent(this, (byte) 3);
+ // Paper end + // Paper end
this.createWitherRose(entityliving); + this.createWitherRose(entityliving);
} }
+ if (this.dead) { // Paper + if (this.dead) { // Paper
this.level.broadcastEntityEvent(this, (byte) 3); + this.level.broadcastEntityEvent(this, (byte) 3);
this.setPose(Pose.DYING); this.setPose(Pose.DYING);
+ } // Paper + } // Paper
} }
@ -305,8 +307,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, drops); // CraftBukkit - call event // Paper - make cancellable + org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, drops); // CraftBukkit - call event // Paper - make cancellable
+ if (event.isCancelled()) return; // Paper - make cancellable + if (event.isCancelled()) return; // Paper - make cancellable
this.remove(Entity.RemovalReason.KILLED); this.remove(Entity.RemovalReason.KILLED);
this.gameEvent(GameEvent.ENTITY_DIE);
} }
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java

Datei anzeigen

@ -10,7 +10,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java --- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java +++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
@@ -0,0 +0,0 @@ public final class NaturalSpawner { @@ -0,0 +0,0 @@ public final class NaturalSpawner {
StructureFeatureManager structuremanager = world.structureFeatureManager(); StructureManager structuremanager = world.structureManager();
ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator(); ChunkGenerator chunkgenerator = world.getChunkSource().getGenerator();
int i = pos.getY(); int i = pos.getY();
- BlockState iblockdata = chunk.getBlockState(pos); - BlockState iblockdata = chunk.getBlockState(pos);