mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-30 22:44:17 +01:00
Adding chunk serialization events
This commit is contained in:
parent
2182d47792
commit
d361728f2a
@ -0,0 +1,204 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: derverdox <mail.ysp@web.de>
|
||||||
|
Date: Thu, 30 Nov 2023 01:22:24 +0100
|
||||||
|
Subject: [PATCH] Adding ChunkSerialization and Generation events.
|
||||||
|
|
||||||
|
This patch adds new Chunk events that are called during the serialization / generation process of chunks.
|
||||||
|
A problem some developers may face while using the ChunkLoad or ChunkUnload events is the fact that they are called synchronously.
|
||||||
|
These proposed events are called during the process.
|
||||||
|
|
||||||
|
The use case of such events is that heavy saving / loading tasks from cache to the chunk nbt container or vice versa are executed asynchronously aswell but in the same thread
|
||||||
|
that saves / loads / generates the chunk.
|
||||||
|
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/event/chunk/ChunkDataEvent.java b/src/main/java/io/papermc/paper/event/chunk/ChunkDataEvent.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..73c94926c975360f9b7c79f910dd09a0f3346058
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/event/chunk/ChunkDataEvent.java
|
||||||
|
@@ -0,0 +1,61 @@
|
||||||
|
+package io.papermc.paper.event.chunk;
|
||||||
|
+
|
||||||
|
+import org.bukkit.Bukkit;
|
||||||
|
+import org.bukkit.Chunk;
|
||||||
|
+import org.bukkit.World;
|
||||||
|
+import org.bukkit.event.Event;
|
||||||
|
+import org.bukkit.event.HandlerList;
|
||||||
|
+import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+import org.jetbrains.annotations.Nullable;
|
||||||
|
+
|
||||||
|
+public abstract class ChunkDataEvent extends Event {
|
||||||
|
+ private static final HandlerList handlers = new HandlerList();
|
||||||
|
+ private final World world;
|
||||||
|
+ private final Chunk chunk;
|
||||||
|
+ private final int chunkX;
|
||||||
|
+ private final int chunkZ;
|
||||||
|
+ private final PersistentDataContainer persistentDataContainer;
|
||||||
|
+
|
||||||
|
+ public ChunkDataEvent(@NotNull World world, @Nullable Chunk chunk, int chunkX, int chunkZ, @NotNull PersistentDataContainer chunkPersistentDataContainer) {
|
||||||
|
+ super(!Bukkit.isPrimaryThread());
|
||||||
|
+ this.world = world;
|
||||||
|
+ this.chunk = chunk;
|
||||||
|
+ this.chunkX = chunkX;
|
||||||
|
+ this.chunkZ = chunkZ;
|
||||||
|
+ this.persistentDataContainer = chunkPersistentDataContainer;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public int getChunkX() {
|
||||||
|
+ return chunkX;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public int getChunkZ() {
|
||||||
|
+ return chunkZ;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Nullable
|
||||||
|
+ public Chunk getChunk() {
|
||||||
|
+ return this.chunk;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ public World getWorld() {
|
||||||
|
+ return this.world;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ public PersistentDataContainer getPersistentDataContainer() {
|
||||||
|
+ return this.persistentDataContainer;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ public static HandlerList getHandlerList() {
|
||||||
|
+ return handlers;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ public HandlerList getHandlers() {
|
||||||
|
+ return handlers;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/event/chunk/ChunkDeserializeEvent.java b/src/main/java/io/papermc/paper/event/chunk/ChunkDeserializeEvent.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..e90357708c7d06150f446161d7761b6e22fb64d5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/event/chunk/ChunkDeserializeEvent.java
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+package io.papermc.paper.event.chunk;
|
||||||
|
+
|
||||||
|
+import org.bukkit.Chunk;
|
||||||
|
+import org.bukkit.World;
|
||||||
|
+import org.bukkit.event.HandlerList;
|
||||||
|
+import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+import org.jetbrains.annotations.Nullable;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Called when a chunk is loaded from disk.
|
||||||
|
+ * You can use this event to manipulate the persistent data container of the chunk after it is loaded.
|
||||||
|
+ * Since by default chunk loading is asynchronously on paper this might be an alternative to the ChunkLoadEvent in some cases.
|
||||||
|
+ * This event might get called asynchronously.
|
||||||
|
+ */
|
||||||
|
+public class ChunkDeserializeEvent extends ChunkDataEvent {
|
||||||
|
+ private static final HandlerList handlers = new HandlerList();
|
||||||
|
+ public ChunkDeserializeEvent(@NotNull final World world, @Nullable final Chunk chunk, final int chunkX, final int chunkZ, @NotNull final PersistentDataContainer chunkPersistentDataContainer) {
|
||||||
|
+ super(world, chunk, chunkX, chunkZ, chunkPersistentDataContainer);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ @Override
|
||||||
|
+ public HandlerList getHandlers() {
|
||||||
|
+ return handlers;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ public static HandlerList getHandlerList() {
|
||||||
|
+ return handlers;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/event/chunk/ChunkGenerateEvent.java b/src/main/java/io/papermc/paper/event/chunk/ChunkGenerateEvent.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..1f279d528ce2be534911686a4574596334ea944a
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/event/chunk/ChunkGenerateEvent.java
|
||||||
|
@@ -0,0 +1,32 @@
|
||||||
|
+package io.papermc.paper.event.chunk;
|
||||||
|
+
|
||||||
|
+import org.bukkit.Chunk;
|
||||||
|
+import org.bukkit.World;
|
||||||
|
+import org.bukkit.event.HandlerList;
|
||||||
|
+import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+import org.jetbrains.annotations.Nullable;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Called when a chunk is generated.
|
||||||
|
+ * You can use this event to manipulate the persistent data container of the chunk before it is generated.
|
||||||
|
+ * Since by default chunk generation is asynchronously on paper this might be an alternative to the ChunkLoadEvent in some cases.
|
||||||
|
+ * This event is might get called asynchronously.
|
||||||
|
+ */
|
||||||
|
+public class ChunkGenerateEvent extends ChunkDataEvent {
|
||||||
|
+ private static final HandlerList handlers = new HandlerList();
|
||||||
|
+ public ChunkGenerateEvent(@NotNull final World world, @Nullable final Chunk chunk, final int chunkX, final int chunkZ, @NotNull final PersistentDataContainer chunkPersistentDataContainer) {
|
||||||
|
+ super(world, chunk, chunkX, chunkZ, chunkPersistentDataContainer);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ @Override
|
||||||
|
+ public HandlerList getHandlers() {
|
||||||
|
+ return handlers;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ public static HandlerList getHandlerList() {
|
||||||
|
+ return handlers;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/event/chunk/ChunkSerializeEvent.java b/src/main/java/io/papermc/paper/event/chunk/ChunkSerializeEvent.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..77d7711f1c8513e4f1895a187cc758c376ab93e7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/io/papermc/paper/event/chunk/ChunkSerializeEvent.java
|
||||||
|
@@ -0,0 +1,43 @@
|
||||||
|
+package io.papermc.paper.event.chunk;
|
||||||
|
+
|
||||||
|
+import org.bukkit.Chunk;
|
||||||
|
+import org.bukkit.World;
|
||||||
|
+import org.bukkit.event.HandlerList;
|
||||||
|
+import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
+import org.jetbrains.annotations.NotNull;
|
||||||
|
+import org.jetbrains.annotations.Nullable;
|
||||||
|
+
|
||||||
|
+/**
|
||||||
|
+ * Called when a chunk is saved to disk.
|
||||||
|
+ * You can use this event to manipulate the persistent data container of the chunk after it is loaded.
|
||||||
|
+ * Since by default chunk saving is asynchronously on paper this might be an alternative to the ChunkUnloadEvent in some cases.
|
||||||
|
+ * This event might get called asynchronously.
|
||||||
|
+ */
|
||||||
|
+public class ChunkSerializeEvent extends ChunkDataEvent {
|
||||||
|
+ private static final HandlerList handlers = new HandlerList();
|
||||||
|
+ private final boolean unloaded;
|
||||||
|
+
|
||||||
|
+ public ChunkSerializeEvent(@NotNull final World world, @Nullable final Chunk chunk, final int chunkX, final int chunkZ, @NotNull final PersistentDataContainer chunkPersistentDataContainer, boolean unloaded) {
|
||||||
|
+ super(world, chunk, chunkX, chunkZ, chunkPersistentDataContainer);
|
||||||
|
+ this.unloaded = unloaded;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /**
|
||||||
|
+ * Gets if this chunk was unloaded after being saved
|
||||||
|
+ * @return true if the chunk is also unloaded
|
||||||
|
+ */
|
||||||
|
+ public boolean isUnloaded() {
|
||||||
|
+ return this.unloaded;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ @Override
|
||||||
|
+ public HandlerList getHandlers() {
|
||||||
|
+ return handlers;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @NotNull
|
||||||
|
+ public static HandlerList getHandlerList() {
|
||||||
|
+ return handlers;
|
||||||
|
+ }
|
||||||
|
+}
|
@ -0,0 +1,226 @@
|
|||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: derverdox <mail.ysp@web.de>
|
||||||
|
Date: Thu, 30 Nov 2023 01:22:23 +0100
|
||||||
|
Subject: [PATCH] Adding ChunkSerialization and Generation events.
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/src/main/java/de/verdox/mccreativelab/worldgen/ChunkDataUtil.java b/src/main/java/de/verdox/mccreativelab/worldgen/ChunkDataUtil.java
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..682f4ac0708ba8bff474f8dedb14df03dd8e2189
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/main/java/de/verdox/mccreativelab/worldgen/ChunkDataUtil.java
|
||||||
|
@@ -0,0 +1,37 @@
|
||||||
|
+package de.verdox.mccreativelab.worldgen;
|
||||||
|
+
|
||||||
|
+import io.papermc.paper.event.chunk.ChunkGenerateEvent;
|
||||||
|
+import io.papermc.paper.event.chunk.ChunkDeserializeEvent;
|
||||||
|
+import io.papermc.paper.event.chunk.ChunkSerializeEvent;
|
||||||
|
+import net.minecraft.server.level.ServerLevel;
|
||||||
|
+import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
+import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
+import org.bukkit.Bukkit;
|
||||||
|
+import org.bukkit.craftbukkit.CraftChunk;
|
||||||
|
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
|
+import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
+
|
||||||
|
+public class ChunkDataUtil {
|
||||||
|
+
|
||||||
|
+ public static void callChunkDataCreateEvent(ServerLevel serverLevel, ChunkAccess chunkAccess, PersistentDataContainer persistentDataContainer) {
|
||||||
|
+ Bukkit.getPluginManager()
|
||||||
|
+ .callEvent(new ChunkGenerateEvent(serverLevel.getWorld(), getCraftChunk(chunkAccess), chunkAccess.locX, chunkAccess.locZ, persistentDataContainer));
|
||||||
|
+ chunkAccess.persistentDataContainer.dirty(true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void callChunkDataLoadEvent(ServerLevel serverLevel, ChunkAccess chunkAccess, PersistentDataContainer persistentDataContainer) {
|
||||||
|
+ Bukkit.getPluginManager().
|
||||||
|
+ callEvent(new ChunkDeserializeEvent(serverLevel.getWorld(), getCraftChunk(chunkAccess), chunkAccess.locX, chunkAccess.locZ, persistentDataContainer));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void callChunkDataSaveEvent(ServerLevel serverLevel, ChunkAccess chunkAccess, PersistentDataContainer persistentDataContainer, boolean unloadingChunk) {
|
||||||
|
+ Bukkit.getPluginManager()
|
||||||
|
+ .callEvent(new ChunkSerializeEvent(serverLevel.getWorld(), getCraftChunk(chunkAccess), chunkAccess.locX, chunkAccess.locZ, persistentDataContainer, unloadingChunk));
|
||||||
|
+ chunkAccess.persistentDataContainer.dirty(true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static CraftChunk getCraftChunk(ChunkAccess chunkAccess) {
|
||||||
|
+ return chunkAccess instanceof LevelChunk chunk ? new CraftChunk(chunk) : null;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
diff --git a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java
|
||||||
|
index b66a7d4aab887309579154815a0d4abf9de506b0..9c403423551db5280edaca5869e42e23ae6aa5c2 100644
|
||||||
|
--- a/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java
|
||||||
|
+++ b/src/main/java/io/papermc/paper/chunk/system/scheduling/NewChunkHolder.java
|
||||||
|
@@ -1817,7 +1817,9 @@ public final class NewChunkHolder {
|
||||||
|
public void run() {
|
||||||
|
final CompoundTag toSerialize;
|
||||||
|
try {
|
||||||
|
- toSerialize = ChunkSerializer.saveChunk(this.world, this.chunk, this.asyncSaveData);
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
+ toSerialize = ChunkSerializer.saveChunk(this.world, this.chunk, this.asyncSaveData, false);
|
||||||
|
+ // Paper end - add ChunkDataEvents
|
||||||
|
} catch (final ThreadDeath death) {
|
||||||
|
throw death;
|
||||||
|
} catch (final Throwable throwable) {
|
||||||
|
@@ -1825,7 +1827,9 @@ public final class NewChunkHolder {
|
||||||
|
this.world.chunkTaskScheduler.scheduleChunkTask(this.chunk.locX, this.chunk.locZ, () -> {
|
||||||
|
final CompoundTag synchronousSave;
|
||||||
|
try {
|
||||||
|
- synchronousSave = ChunkSerializer.saveChunk(AsyncChunkSerializeTask.this.world, AsyncChunkSerializeTask.this.chunk, AsyncChunkSerializeTask.this.asyncSaveData);
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
+ synchronousSave = ChunkSerializer.saveChunk(AsyncChunkSerializeTask.this.world, AsyncChunkSerializeTask.this.chunk, AsyncChunkSerializeTask.this.asyncSaveData, false);
|
||||||
|
+ // Paper end - add ChunkDataEvents
|
||||||
|
} catch (final ThreadDeath death) {
|
||||||
|
throw death;
|
||||||
|
} catch (final Throwable throwable2) {
|
||||||
|
@@ -1881,7 +1885,9 @@ public final class NewChunkHolder {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- final CompoundTag save = ChunkSerializer.saveChunk(this.world, chunk, null);
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
+ final CompoundTag save = ChunkSerializer.saveChunk(this.world, chunk, null, unloading);
|
||||||
|
+ // Paper end - add ChunkDataEvents
|
||||||
|
|
||||||
|
if (unloading) {
|
||||||
|
completing = true;
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java
|
||||||
|
index a907b79fd8291a0e92db138f37239d17424188a1..802735bf4f34ed225ab08252c0f10b4c5bb915a0 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkStatus.java
|
||||||
|
@@ -27,6 +27,7 @@ import net.minecraft.world.level.levelgen.GenerationStep;
|
||||||
|
import net.minecraft.world.level.levelgen.Heightmap;
|
||||||
|
import net.minecraft.world.level.levelgen.blending.Blender;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||||
|
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
|
|
||||||
|
public class ChunkStatus {
|
||||||
|
|
||||||
|
@@ -68,6 +69,9 @@ public class ChunkStatus {
|
||||||
|
}
|
||||||
|
|
||||||
|
worldserver.onStructureStartsAvailable(ichunkaccess);
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
+ CraftEventFactory.callChunkGenerateEvent(worldserver, ichunkaccess, ichunkaccess.persistentDataContainer);
|
||||||
|
+ // Paper end - add ChunkDataEvents
|
||||||
|
return CompletableFuture.completedFuture(Either.left(ichunkaccess));
|
||||||
|
}, (chunkstatus, worldserver, structuretemplatemanager, lightenginethreaded, function, ichunkaccess) -> {
|
||||||
|
worldserver.onStructureStartsAvailable(ichunkaccess);
|
||||||
|
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||||
|
index 1379084a80ce25644f13736b4a5ee5fabbd9ec1f..fedfdcf893478d9df9e35851d0ab4edb9a30856f 100644
|
||||||
|
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||||
|
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkSerializer.java
|
||||||
|
@@ -67,6 +67,7 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import net.minecraft.world.ticks.LevelChunkTicks;
|
||||||
|
import net.minecraft.world.ticks.ProtoChunkTicks;
|
||||||
|
+import org.bukkit.craftbukkit.event.CraftEventFactory;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
|
public class ChunkSerializer {
|
||||||
|
@@ -366,6 +367,9 @@ public class ChunkSerializer {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chunkstatus_type == ChunkStatus.ChunkType.LEVELCHUNK) {
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
+ CraftEventFactory.callChunkDeserializeEvent(world, (ChunkAccess) object1, ((ChunkAccess) object1).persistentDataContainer);
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
return new InProgressChunkHolder(new ImposterProtoChunk((LevelChunk) object1, false)); // Paper - Async chunk loading
|
||||||
|
} else {
|
||||||
|
ProtoChunk protochunk1 = (ProtoChunk) object1;
|
||||||
|
@@ -401,6 +405,9 @@ public class ChunkSerializer {
|
||||||
|
protochunk1.setCarvingMask(worldgenstage_features, new CarvingMask(nbttagcompound5.getLongArray(s1), ((ChunkAccess) object1).getMinBuildHeight()));
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
+ CraftEventFactory.callChunkDeserializeEvent(world, (ChunkAccess) object1, ((ChunkAccess) object1).persistentDataContainer);
|
||||||
|
+ // Paper end - add ChunkDataEvents
|
||||||
|
return new InProgressChunkHolder(protochunk1); // Paper - Async chunk loading
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -452,11 +459,12 @@ public class ChunkSerializer {
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
|
public static CompoundTag write(ServerLevel world, ChunkAccess chunk) {
|
||||||
|
- // Paper start
|
||||||
|
- return saveChunk(world, chunk, null);
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
+ return saveChunk(world, chunk, null, false);
|
||||||
|
+
|
||||||
|
}
|
||||||
|
- public static CompoundTag saveChunk(ServerLevel world, ChunkAccess chunk, @org.checkerframework.checker.nullness.qual.Nullable AsyncSaveData asyncsavedata) {
|
||||||
|
- // Paper end
|
||||||
|
+ public static CompoundTag saveChunk(ServerLevel world, ChunkAccess chunk, @org.checkerframework.checker.nullness.qual.Nullable AsyncSaveData asyncsavedata, boolean unloadingChunk) {
|
||||||
|
+ // Paper end - add ChunkDataEvents
|
||||||
|
// Paper start - rewrite light impl
|
||||||
|
final int minSection = io.papermc.paper.util.WorldUtil.getMinLightSection(world);
|
||||||
|
final int maxSection = io.papermc.paper.util.WorldUtil.getMaxLightSection(world);
|
||||||
|
@@ -637,6 +645,9 @@ public class ChunkSerializer {
|
||||||
|
|
||||||
|
nbttagcompound.put("Heightmaps", nbttagcompound3);
|
||||||
|
nbttagcompound.put("structures", ChunkSerializer.packStructureData(StructurePieceSerializationContext.fromLevel(world), chunkcoordintpair, chunk.getAllStarts(), chunk.getAllReferences()));
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
+ CraftEventFactory.callChunkSaveEvent(world, chunk, chunk.persistentDataContainer, unloadingChunk);
|
||||||
|
+ // Paper end - add ChunkDataEvents
|
||||||
|
// CraftBukkit start - store chunk persistent data in nbt
|
||||||
|
if (!chunk.persistentDataContainer.isEmpty()) { // SPIGOT-6814: Always save PDC to account for 1.17 to 1.18 chunk upgrading.
|
||||||
|
nbttagcompound.put("ChunkBukkitValues", chunk.persistentDataContainer.toTagCompound());
|
||||||
|
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||||
|
index 5dc160b743534665c6b3efb10b10f7c36e2da5ab..039383f4a17c7ace34a2cf93b75e89bf519c1612 100644
|
||||||
|
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||||
|
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||||
|
@@ -16,6 +16,9 @@ import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
+import io.papermc.paper.event.chunk.ChunkDeserializeEvent;
|
||||||
|
+import io.papermc.paper.event.chunk.ChunkGenerateEvent;
|
||||||
|
+import io.papermc.paper.event.chunk.ChunkSerializeEvent;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.network.protocol.game.ServerboundContainerClosePacket;
|
||||||
|
@@ -56,6 +59,8 @@ import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
|
import net.minecraft.world.level.block.entity.SignBlockEntity;
|
||||||
|
import net.minecraft.world.level.block.state.properties.NoteBlockInstrument;
|
||||||
|
+import net.minecraft.world.level.chunk.ChunkAccess;
|
||||||
|
+import net.minecraft.world.level.chunk.LevelChunk;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootContext;
|
||||||
|
import net.minecraft.world.level.storage.loot.LootTable;
|
||||||
|
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
|
||||||
|
@@ -242,6 +247,7 @@ import org.bukkit.inventory.EquipmentSlot;
|
||||||
|
import org.bukkit.inventory.InventoryView;
|
||||||
|
import org.bukkit.inventory.Recipe;
|
||||||
|
import org.bukkit.inventory.meta.BookMeta;
|
||||||
|
+import org.bukkit.persistence.PersistentDataContainer;
|
||||||
|
import org.bukkit.potion.PotionEffect;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
|
@@ -2166,4 +2172,27 @@ public class CraftEventFactory {
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
// Paper end - add EntityFertilizeEggEvent
|
||||||
|
+
|
||||||
|
+ // Paper start - add ChunkDataEvents
|
||||||
|
+ public static void callChunkGenerateEvent(ServerLevel serverLevel, ChunkAccess chunkAccess, PersistentDataContainer persistentDataContainer) {
|
||||||
|
+ Bukkit.getPluginManager()
|
||||||
|
+ .callEvent(new ChunkGenerateEvent(serverLevel.getWorld(), getCraftChunk(chunkAccess), chunkAccess.locX, chunkAccess.locZ, persistentDataContainer));
|
||||||
|
+ chunkAccess.persistentDataContainer.dirty(true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void callChunkDeserializeEvent(ServerLevel serverLevel, ChunkAccess chunkAccess, PersistentDataContainer persistentDataContainer) {
|
||||||
|
+ Bukkit.getPluginManager().
|
||||||
|
+ callEvent(new ChunkDeserializeEvent(serverLevel.getWorld(), getCraftChunk(chunkAccess), chunkAccess.locX, chunkAccess.locZ, persistentDataContainer));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static void callChunkSaveEvent(ServerLevel serverLevel, ChunkAccess chunkAccess, PersistentDataContainer persistentDataContainer, boolean unloadingChunk) {
|
||||||
|
+ Bukkit.getPluginManager()
|
||||||
|
+ .callEvent(new ChunkSerializeEvent(serverLevel.getWorld(), getCraftChunk(chunkAccess), chunkAccess.locX, chunkAccess.locZ, persistentDataContainer, unloadingChunk));
|
||||||
|
+ chunkAccess.persistentDataContainer.dirty(true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ private static CraftChunk getCraftChunk(ChunkAccess chunkAccess) {
|
||||||
|
+ return chunkAccess instanceof LevelChunk chunk ? new CraftChunk(chunk) : null;
|
||||||
|
+ }
|
||||||
|
+ // Paper end - add ChunkDataEvents
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user