mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-18 12:48:53 +01:00
8c5b837e05
Firstly, the old methods all routed to the CompletableFuture method. However, the CF method could not guarantee that if the caller was off-main that the future would be "completed" on-main. Since the callback methods used the CF one, this meant that the callback methods did not guarantee that the callbacks were to be called on the main thread. Now, all methods route to getChunkAtAsync(x, z, gen, urgent, cb) so that the methods with the callback are guaranteed to invoke the callback on the main thread. The CF behavior remains unchanged; it may still appear to complete on main if invoked off-main. Secondly, remove the scheduleOnMain invocation in the async chunk completion. This unnecessarily delays the callback by 1 tick. Thirdly, add getChunksAtAsync(minX, minZ, maxX, maxZ, ...) which will load chunks within an area. This method is provided as a helper as keeping all chunks loaded within an area can be complicated to implement for plugins (due to the lacking ticket API), and is already implemented internally anyways. Fourthly, remove the ticket addition that occured with getChunkAt and getChunkAtAsync. The ticket addition may delay the unloading of the chunk unnecessarily. It also fixes a very rare timing bug where the future/callback would be completed after the chunk unloads.
73 lines
4.8 KiB
Diff
73 lines
4.8 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: masmc05 <masmc05@gmail.com>
|
|
Date: Sun, 11 Aug 2024 03:01:52 +0300
|
|
Subject: [PATCH] Item serialization as json
|
|
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/item/component/CustomData.java b/src/main/java/net/minecraft/world/item/component/CustomData.java
|
|
index c80fd4960dfbb0fde37363e7df25b0a5411bdb11..ff7f6916f65466c25a7bde35d64682c15b211697 100644
|
|
--- a/src/main/java/net/minecraft/world/item/component/CustomData.java
|
|
+++ b/src/main/java/net/minecraft/world/item/component/CustomData.java
|
|
@@ -28,7 +28,17 @@ import org.slf4j.Logger;
|
|
public final class CustomData {
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
public static final CustomData EMPTY = new CustomData(new CompoundTag());
|
|
- public static final Codec<CustomData> CODEC = Codec.withAlternative(CompoundTag.CODEC, TagParser.AS_CODEC)
|
|
+ // Paper start - Item serialization as json
|
|
+ public static ThreadLocal<Boolean> SERIALIZE_CUSTOM_AS_SNBT = ThreadLocal.withInitial(() -> false);
|
|
+ public static final Codec<CustomData> CODEC = Codec.either(CompoundTag.CODEC, TagParser.AS_CODEC)
|
|
+ .xmap(com.mojang.datafixers.util.Either::unwrap, data -> { // Both will be used for deserialization, but we decide which one to use for serialization
|
|
+ if (!SERIALIZE_CUSTOM_AS_SNBT.get()) {
|
|
+ return com.mojang.datafixers.util.Either.left(data); // First codec
|
|
+ } else {
|
|
+ return com.mojang.datafixers.util.Either.right(data); // Second codec
|
|
+ }
|
|
+ })
|
|
+ // Paper end - Item serialization as json
|
|
.xmap(CustomData::new, component -> component.tag);
|
|
public static final Codec<CustomData> CODEC_WITH_ID = CODEC.validate(
|
|
component -> component.getUnsafe().contains("id", 8) ? DataResult.success(component) : DataResult.error(() -> "Missing id for entity in: " + component)
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
index f4ccdd848dd64e97796ef952d2aeacb3219da1bd..29d5fa49730d2161bb1b024995a533a08c57939b 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
|
@@ -527,6 +527,39 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
|
return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(MinecraftServer.getServer().registryAccess(), compound).orElseThrow());
|
|
}
|
|
|
|
+ @Override
|
|
+ public com.google.gson.JsonObject serializeItemAsJson(ItemStack itemStack) {
|
|
+ Preconditions.checkNotNull(itemStack, "Cannot serialize empty ItemStack");
|
|
+ Preconditions.checkArgument(!itemStack.isEmpty(), "Cannot serialize empty ItemStack");
|
|
+
|
|
+ net.minecraft.core.RegistryAccess.Frozen reg = net.minecraft.server.MinecraftServer.getServer().registryAccess();
|
|
+ com.mojang.serialization.DynamicOps<com.google.gson.JsonElement> ops = reg.createSerializationContext(com.mojang.serialization.JsonOps.INSTANCE);
|
|
+ com.google.gson.JsonObject item;
|
|
+ // Serialize as SNBT to preserve exact NBT types; vanilla codecs already can handle such deserialization.
|
|
+ net.minecraft.world.item.component.CustomData.SERIALIZE_CUSTOM_AS_SNBT.set(true);
|
|
+ try {
|
|
+ item = net.minecraft.world.item.ItemStack.CODEC.encodeStart(ops, CraftItemStack.unwrap(itemStack)).getOrThrow().getAsJsonObject();
|
|
+ } finally {
|
|
+ net.minecraft.world.item.component.CustomData.SERIALIZE_CUSTOM_AS_SNBT.set(false);
|
|
+ }
|
|
+ item.addProperty("DataVersion", this.getDataVersion());
|
|
+ return item;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public ItemStack deserializeItemFromJson(com.google.gson.JsonObject data) throws IllegalArgumentException {
|
|
+ Preconditions.checkNotNull(data, "null cannot be deserialized");
|
|
+
|
|
+ final int dataVersion = data.get("DataVersion").getAsInt();
|
|
+ final int currentVersion = org.bukkit.craftbukkit.util.CraftMagicNumbers.INSTANCE.getDataVersion();
|
|
+ data = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertJson(
|
|
+ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK,
|
|
+ data, false, dataVersion, currentVersion
|
|
+ );
|
|
+ com.mojang.serialization.DynamicOps<com.google.gson.JsonElement> ops = MinecraftServer.getServer().registryAccess().createSerializationContext(com.mojang.serialization.JsonOps.INSTANCE);
|
|
+ return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.CODEC.parse(ops, data).getOrThrow(IllegalArgumentException::new));
|
|
+ }
|
|
+
|
|
@Override
|
|
public byte[] serializeEntity(org.bukkit.entity.Entity entity) {
|
|
Preconditions.checkNotNull(entity, "null cannot be serialized");
|