aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorSpottedleaf <[email protected]>2024-06-14 10:34:45 -0700
committerSpottedleaf <[email protected]>2024-06-14 10:34:45 -0700
commitdf633e5ffad29b1ecb3260ebba03d0459aa4861a (patch)
tree196b87e33868df6918bc8488184c51dab4edc845
parent38b3182a9062e88959b33b486fbd73ac179f80c0 (diff)
downloadPaper-df633e5ffad29b1ecb3260ebba03d0459aa4861a.tar.gz
Paper-df633e5ffad29b1ecb3260ebba03d0459aa4861a.zip
DataConverter 1.21
-rw-r--r--patches/server/0989-Rewrite-dataconverter-system.patch (renamed from patches/unapplied/server/0989-Rewrite-dataconverter-system.patch)489
-rw-r--r--patches/server/0990-disable-forced-empty-world-ticks.patch (renamed from patches/server/0989-disable-forced-empty-world-ticks.patch)0
-rw-r--r--patches/server/0991-stubs.patch (renamed from patches/server/0990-stubs.patch)0
3 files changed, 434 insertions, 55 deletions
diff --git a/patches/unapplied/server/0989-Rewrite-dataconverter-system.patch b/patches/server/0989-Rewrite-dataconverter-system.patch
index 993066ea40..8602229378 100644
--- a/patches/unapplied/server/0989-Rewrite-dataconverter-system.patch
+++ b/patches/server/0989-Rewrite-dataconverter-system.patch
@@ -196,10 +196,10 @@ index 0000000000000000000000000000000000000000..a27d3d41109271834b6c37fa22d4b80d
+}
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersionRegistry.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersionRegistry.java
new file mode 100644
-index 0000000000000000000000000000000000000000..1f9835a20fb12021c0c791ebde2b0ee84d0306b4
+index 0000000000000000000000000000000000000000..69b5f9fe20c09ac0e72205ba8e4475c2dfea8313
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersionRegistry.java
-@@ -0,0 +1,425 @@
+@@ -0,0 +1,431 @@
+package ca.spottedleaf.dataconverter.minecraft;
+
+import ca.spottedleaf.dataconverter.converters.DataConverter;
@@ -438,8 +438,11 @@ index 0000000000000000000000000000000000000000..1f9835a20fb12021c0c791ebde2b0ee8
+ 3820,
+ 3825,
+ 3828,
-+ 3833
-+ // All up to 1.20.6
++ 3833,
++ 3939,
++ 3943,
++ 3945
++ // All up to 1.21
+ };
+ Arrays.sort(converterVersions);
+
@@ -486,6 +489,9 @@ index 0000000000000000000000000000000000000000..1f9835a20fb12021c0c791ebde2b0ee8
+ // Too much changed in this version.
+ registerBreakpoint(MCVersions.V24W07A + 1, 5);
+ registerBreakpointAfter(MCVersions.V24W07A + 1, Integer.MAX_VALUE);
++
++ // final release of major version
++ registerBreakpointAfter(MCVersions.V1_20_6, Integer.MAX_VALUE);
+ }
+
+ static {
@@ -627,10 +633,10 @@ index 0000000000000000000000000000000000000000..1f9835a20fb12021c0c791ebde2b0ee8
+}
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersions.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersions.java
new file mode 100644
-index 0000000000000000000000000000000000000000..93acc54f3acdc7d4f2ef10bf712f2588f7e1416d
+index 0000000000000000000000000000000000000000..fe546060bd27eda27931d9757831f0e4f043e31d
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/MCVersions.java
-@@ -0,0 +1,527 @@
+@@ -0,0 +1,539 @@
+package ca.spottedleaf.dataconverter.minecraft;
+
+@SuppressWarnings("unused")
@@ -1155,6 +1161,18 @@ index 0000000000000000000000000000000000000000..93acc54f3acdc7d4f2ef10bf712f2588
+ public static final int V1_20_5 = 3837;
+ public static final int V1_20_6_RC1 = 3838;
+ public static final int V1_20_6 = 3839;
++ public static final int V2418WA = 3940;
++ public static final int V2419WA = 3941;
++ public static final int V2419WB = 3942;
++ public static final int V2420WA = 3944;
++ public static final int V2421WA = 3946;
++ public static final int V2421WB = 3947;
++ public static final int V_1_21_PRE1 = 3948;
++ public static final int V_1_21_PRE2 = 3949;
++ public static final int V_1_21_PRE3 = 3950;
++ public static final int V_1_21_PRE4 = 3951;
++ public static final int V_1_21_RC1 = 3952;
++ public static final int V_1_21 = 3953;
+
+ private MCVersions() {}
+}
@@ -5989,15 +6007,16 @@ index 0000000000000000000000000000000000000000..94569f0ccff0d3a09eafd4ba73572d9d
+}
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterEnchantmentsRename.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterEnchantmentsRename.java
new file mode 100644
-index 0000000000000000000000000000000000000000..154ba98bfb587fb4b880e39cd573701b1b049cfe
+index 0000000000000000000000000000000000000000..06596b56a1f89900e5f23f7f4a12bd1d5d02b7c8
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterEnchantmentsRename.java
-@@ -0,0 +1,35 @@
+@@ -0,0 +1,38 @@
+package ca.spottedleaf.dataconverter.minecraft.converters.itemstack;
+
+import ca.spottedleaf.dataconverter.converters.DataConverter;
+import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper;
+import ca.spottedleaf.dataconverter.types.MapType;
++import ca.spottedleaf.dataconverter.util.NamespaceUtil;
+import java.util.function.Function;
+
+public final class ConverterEnchantmentsRename extends DataConverter<MapType<String>, MapType<String>> {
@@ -6011,7 +6030,9 @@ index 0000000000000000000000000000000000000000..154ba98bfb587fb4b880e39cd573701b
+ public ConverterEnchantmentsRename(final int toVersion, final int versionStep, final Function<String, String> renamer) {
+ super(toVersion, versionStep);
+
-+ this.renamer = renamer;
++ this.renamer = (final String input) -> {
++ return renamer.apply(NamespaceUtil.correctNamespace(input));
++ };
+ }
+
+ @Override
@@ -6589,10 +6610,10 @@ index 0000000000000000000000000000000000000000..4fa31e40b0a6f571a853299b4e242de9
+}
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java
new file mode 100644
-index 0000000000000000000000000000000000000000..a5a21d1c7579e45b78eae4b42a9f023db74acc0a
+index 0000000000000000000000000000000000000000..2d29d89cc45866822189a62bffbe1a8fe57c477b
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java
-@@ -0,0 +1,1244 @@
+@@ -0,0 +1,1245 @@
+package ca.spottedleaf.dataconverter.minecraft.converters.itemstack;
+
+import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper;
@@ -7121,12 +7142,13 @@ index 0000000000000000000000000000000000000000..a5a21d1c7579e45b78eae4b42a9f023d
+ }
+ }
+
-+ final boolean hideModifiers = (flags & TOOLTIP_FLAG_HIDE_MODIFIERS) != 0;
-+ if (newAttributes.size() > 0 || hideModifiers) {
++ if (newAttributes.size() > 0) {
+ final MapType<String> newModifiers = type.createEmptyMap();
+ item.componentSetMap("minecraft:attribute_modifiers", newModifiers);
+
+ newModifiers.setList("modifiers", newAttributes);
++
++ final boolean hideModifiers = (flags & TOOLTIP_FLAG_HIDE_MODIFIERS) != 0;
+ if (hideModifiers) {
+ newModifiers.setBoolean("show_in_tooltip", false);
+ }
@@ -9223,10 +9245,10 @@ index 0000000000000000000000000000000000000000..075574f33476882ddc6787e3b8bac864
+}
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/datatypes/MCTypeRegistry.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/datatypes/MCTypeRegistry.java
new file mode 100644
-index 0000000000000000000000000000000000000000..37519f2aab94c299f68819d1b2df2caffb75c9cd
+index 0000000000000000000000000000000000000000..f4d7700ab53753dd5ac3222fbfd7bdd11b48197c
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/datatypes/MCTypeRegistry.java
-@@ -0,0 +1,298 @@
+@@ -0,0 +1,303 @@
+package ca.spottedleaf.dataconverter.minecraft.datatypes;
+
+import ca.spottedleaf.dataconverter.minecraft.versions.*;
@@ -9521,6 +9543,11 @@ index 0000000000000000000000000000000000000000..37519f2aab94c299f68819d1b2df2caf
+ V3825.register();
+ V3828.register();
+ V3833.register();
++ // V1.21
++ V3938.register();
++ V3939.register();
++ V3943.register();
++ V3945.register();
+ }
+
+ private MCTypeRegistry() {}
@@ -11015,7 +11042,7 @@ index 0000000000000000000000000000000000000000..bf6f57bc84785622aea35dc70872db6d
+}
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1451.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1451.java
new file mode 100644
-index 0000000000000000000000000000000000000000..fd46b075f3c18c52e31aeee4cb4638d5d7b673c3
+index 0000000000000000000000000000000000000000..2f6a43d858645baeb3c69959479b6835dd7bd7a8
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1451.java
@@ -0,0 +1,513 @@
@@ -11345,8 +11372,8 @@ index 0000000000000000000000000000000000000000..fd46b075f3c18c52e31aeee4cb4638d5
+ id = criteriaName;
+ } else {
+ try {
-+ type = ResourceLocation.of(criteriaName.substring(0, index), '.').toString();
-+ id = ResourceLocation.of(criteriaName.substring(index + 1), '.').toString();
++ type = ResourceLocation.bySeparator(criteriaName.substring(0, index), '.').toString();
++ id = ResourceLocation.bySeparator(criteriaName.substring(index + 1), '.').toString();
+ } catch (final Exception ex) {
+ type = "_special";
+ id = criteriaName;
@@ -11670,10 +11697,10 @@ index 0000000000000000000000000000000000000000..95822caa64d6c8a780bb120bedd27283
+}
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1460.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1460.java
new file mode 100644
-index 0000000000000000000000000000000000000000..9933c54eba686ba851e0d2112c7a22a09544c2c2
+index 0000000000000000000000000000000000000000..bf64be7255b02461d218a821ac9b36ba5bc83b13
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V1460.java
-@@ -0,0 +1,44 @@
+@@ -0,0 +1,45 @@
+package ca.spottedleaf.dataconverter.minecraft.versions;
+
+import ca.spottedleaf.dataconverter.converters.DataConverter;
@@ -11682,6 +11709,7 @@ index 0000000000000000000000000000000000000000..9933c54eba686ba851e0d2112c7a22a0
+import ca.spottedleaf.dataconverter.minecraft.walkers.block_name.DataWalkerBlockNames;
+import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists;
+import ca.spottedleaf.dataconverter.types.MapType;
++import ca.spottedleaf.dataconverter.util.NamespaceUtil;
+import net.minecraft.resources.ResourceLocation;
+import java.util.HashMap;
+import java.util.Locale;
@@ -11706,7 +11734,7 @@ index 0000000000000000000000000000000000000000..9933c54eba686ba851e0d2112c7a22a0
+ String motive = data.getString("Motive");
+ if (motive != null) {
+ motive = motive.toLowerCase(Locale.ROOT);
-+ data.setString("Motive", new ResourceLocation(MOTIVE_REMAP.getOrDefault(motive, motive)).toString());
++ data.setString("Motive", NamespaceUtil.correctNamespace(MOTIVE_REMAP.getOrDefault(motive, motive)));
+ }
+ return null;
+ }
@@ -22456,10 +22484,10 @@ index 0000000000000000000000000000000000000000..f50b81d931a1908d405bb72e0679983a
+}
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3818.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3818.java
new file mode 100644
-index 0000000000000000000000000000000000000000..40f9b8f2a3d0b01dc97472f34c441321a0e33079
+index 0000000000000000000000000000000000000000..a1a4659538c8f678319ddc7d61b400051c8a4953
--- /dev/null
+++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3818.java
-@@ -0,0 +1,339 @@
+@@ -0,0 +1,340 @@
+package ca.spottedleaf.dataconverter.minecraft.versions;
+
+import ca.spottedleaf.dataconverter.converters.DataConverter;
@@ -22713,6 +22741,7 @@ index 0000000000000000000000000000000000000000..40f9b8f2a3d0b01dc97472f34c441321
+ WalkerUtils.convertListPath(MCTypeRegistry.ITEM_STACK, root, "minecraft:container", "item", fromVersion, toVersion);
+ WalkerUtils.convert(MCTypeRegistry.ENTITY, root, "minecraft:entity_data", fromVersion, toVersion);
+ WalkerUtils.convertList(MCTypeRegistry.ITEM_NAME, root, "minecraft:pot_decorations", fromVersion, toVersion);
++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root.getMap("minecraft:food"), "using_converts_to", fromVersion, toVersion);
+
+ return null;
+ }
@@ -23128,6 +23157,356 @@ index 0000000000000000000000000000000000000000..4581b9ce0734e552fd8810239e7b86f8
+
+ private V3833() {}
+}
+diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3938.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3938.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..2a6d144c2f074403bde8a62377ca6986c0c12a84
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3938.java
+@@ -0,0 +1,24 @@
++package ca.spottedleaf.dataconverter.minecraft.versions;
++
++import ca.spottedleaf.dataconverter.minecraft.MCVersions;
++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry;
++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths;
++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems;
++
++public final class V3938 {
++
++ private static final int VERSION = MCVersions.V1_20_6 + 99;
++
++ private static void registerArrow(final String id) {
++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "inBlockState"));
++ // new: weapon
++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerItems("item", "weapon"));
++ }
++
++ public static void register() {
++ registerArrow("minecraft:spectral_arrow");
++ registerArrow("minecraft:arrow");
++ }
++
++ private V3938() {}
++}
+diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3939.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3939.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..632c8008484e844d962405c6ef8fb9f09fc6c977
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3939.java
+@@ -0,0 +1,22 @@
++package ca.spottedleaf.dataconverter.minecraft.versions;
++
++import ca.spottedleaf.dataconverter.minecraft.MCVersions;
++import ca.spottedleaf.dataconverter.minecraft.converters.leveldat.ConverterRemoveFeatureFlag;
++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry;
++import java.util.Arrays;
++import java.util.HashSet;
++
++public final class V3939 {
++
++ private static final int VERSION = MCVersions.V1_20_6 + 100;
++
++ public static void register() {
++ MCTypeRegistry.LEVEL.addStructureConverter(new ConverterRemoveFeatureFlag(VERSION, new HashSet<>(
++ Arrays.asList(
++ "minecraft:update_1_21"
++ )
++ )));
++ }
++
++ private V3939() {}
++}
+diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3943.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3943.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..b769abe8c469b15983b433fb9b7de9f41528a4f9
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3943.java
+@@ -0,0 +1,34 @@
++package ca.spottedleaf.dataconverter.minecraft.versions;
++
++import ca.spottedleaf.dataconverter.converters.DataConverter;
++import ca.spottedleaf.dataconverter.minecraft.MCVersions;
++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry;
++import ca.spottedleaf.dataconverter.types.MapType;
++
++public final class V3943 {
++
++ private static final int VERSION = MCVersions.V2419WB + 1;
++
++ public static void register() {
++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) {
++ @Override
++ public MapType<String> convert(final MapType<String> data, final long sourceVersion, final long toVersion) {
++ final String oldRange = data.getString("menuBackgroundBlurriness", "0.5");
++
++ int newRange;
++ try {
++ newRange = (int)Math.round(Double.parseDouble(oldRange) * 10.0);
++ } catch (final NumberFormatException ex) {
++ newRange = 5;
++ }
++
++ // note: options are always string, so DFU is wrong to use int
++ data.setString("menuBackgroundBlurriness", Integer.toString(newRange));
++
++ return null;
++ }
++ });
++ }
++
++ private V3943() {}
++}
+diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3945.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3945.java
+new file mode 100644
+index 0000000000000000000000000000000000000000..aaeb3b9006b9ae2a8d3a28158bc17d05be0ba2fa
+--- /dev/null
++++ b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V3945.java
+@@ -0,0 +1,246 @@
++package ca.spottedleaf.dataconverter.minecraft.versions;
++
++import ca.spottedleaf.dataconverter.converters.DataConverter;
++import ca.spottedleaf.dataconverter.minecraft.MCVersions;
++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper;
++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry;
++import ca.spottedleaf.dataconverter.types.ListType;
++import ca.spottedleaf.dataconverter.types.MapType;
++import ca.spottedleaf.dataconverter.types.ObjectType;
++import com.google.common.collect.ImmutableMap;
++import java.util.HashMap;
++import java.util.LinkedHashMap;
++import java.util.Locale;
++import java.util.Map;
++import java.util.UUID;
++
++public final class V3945 {
++
++ private static final int VERSION = MCVersions.V2420WA + 1;
++
++ private static final Map<UUID, String> UUID_TO_ID = new HashMap<>(
++ ImmutableMap.<UUID, String>builder()
++ .put(UUID.fromString("736565d2-e1a7-403d-a3f8-1aeb3e302542"), "minecraft:creative_mode_block_range")
++ .put(UUID.fromString("98491ef6-97b1-4584-ae82-71a8cc85cf73"), "minecraft:creative_mode_entity_range")
++ .put(UUID.fromString("91AEAA56-376B-4498-935B-2F7F68070635"), "minecraft:effect.speed")
++ .put(UUID.fromString("7107DE5E-7CE8-4030-940E-514C1F160890"), "minecraft:effect.slowness")
++ .put(UUID.fromString("AF8B6E3F-3328-4C0A-AA36-5BA2BB9DBEF3"), "minecraft:effect.haste")
++ .put(UUID.fromString("55FCED67-E92A-486E-9800-B47F202C4386"), "minecraft:effect.mining_fatigue")
++ .put(UUID.fromString("648D7064-6A60-4F59-8ABE-C2C23A6DD7A9"), "minecraft:effect.strength")
++ .put(UUID.fromString("C0105BF3-AEF8-46B0-9EBC-92943757CCBE"), "minecraft:effect.jump_boost")
++ .put(UUID.fromString("22653B89-116E-49DC-9B6B-9971489B5BE5"), "minecraft:effect.weakness")
++ .put(UUID.fromString("5D6F0BA2-1186-46AC-B896-C61C5CEE99CC"), "minecraft:effect.health_boost")
++ .put(UUID.fromString("EAE29CF0-701E-4ED6-883A-96F798F3DAB5"), "minecraft:effect.absorption")
++ .put(UUID.fromString("03C3C89D-7037-4B42-869F-B146BCB64D2E"), "minecraft:effect.luck")
++ .put(UUID.fromString("CC5AF142-2BD2-4215-B636-2605AED11727"), "minecraft:effect.unluck")
++ .put(UUID.fromString("6555be74-63b3-41f1-a245-77833b3c2562"), "minecraft:evil")
++ .put(UUID.fromString("1eaf83ff-7207-4596-b37a-d7a07b3ec4ce"), "minecraft:powder_snow")
++ .put(UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D"), "minecraft:sprinting")
++ .put(UUID.fromString("020E0DFB-87AE-4653-9556-831010E291A0"), "minecraft:attacking")
++ .put(UUID.fromString("766bfa64-11f3-11ea-8d71-362b9e155667"), "minecraft:baby")
++ .put(UUID.fromString("7E0292F2-9434-48D5-A29F-9583AF7DF27F"), "minecraft:covered")
++ .put(UUID.fromString("9e362924-01de-4ddd-a2b2-d0f7a405a174"), "minecraft:suffocating")
++ .put(UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E"), "minecraft:drinking")
++ .put(UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836"), "minecraft:baby")
++ .put(UUID.fromString("49455A49-7EC5-45BA-B886-3B90B23A1718"), "minecraft:attacking")
++ .put(UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), "minecraft:armor.boots")
++ .put(UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), "minecraft:armor.leggings")
++ .put(UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), "minecraft:armor.chestplate")
++ .put(UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150"), "minecraft:armor.helmet")
++ .put(UUID.fromString("C1C72771-8B8E-BA4A-ACE0-81A93C8928B2"), "minecraft:armor.body")
++ .put(UUID.fromString("b572ecd2-ac0c-4071-abde-9594af072a37"), "minecraft:enchantment.fire_protection")
++ .put(UUID.fromString("40a9968f-5c66-4e2f-b7f4-2ec2f4b3e450"), "minecraft:enchantment.blast_protection")
++ .put(UUID.fromString("07a65791-f64d-4e79-86c7-f83932f007ec"), "minecraft:enchantment.respiration")
++ .put(UUID.fromString("60b1b7db-fffd-4ad0-817c-d6c6a93d8a45"), "minecraft:enchantment.aqua_affinity")
++ .put(UUID.fromString("11dc269a-4476-46c0-aff3-9e17d7eb6801"), "minecraft:enchantment.depth_strider")
++ .put(UUID.fromString("87f46a96-686f-4796-b035-22e16ee9e038"), "minecraft:enchantment.soul_speed")
++ .put(UUID.fromString("b9716dbd-50df-4080-850e-70347d24e687"), "minecraft:enchantment.soul_speed")
++ .put(UUID.fromString("92437d00-c3a7-4f2e-8f6c-1f21585d5dd0"), "minecraft:enchantment.swift_sneak")
++ .put(UUID.fromString("5d3d087b-debe-4037-b53e-d84f3ff51f17"), "minecraft:enchantment.sweeping_edge")
++ .put(UUID.fromString("3ceb37c0-db62-46b5-bd02-785457b01d96"), "minecraft:enchantment.efficiency")
++ .put(UUID.fromString("CB3F55D3-645C-4F38-A497-9C13A33DB5CF"), "minecraft:base_attack_damage")
++ .put(UUID.fromString("FA233E1C-4180-4865-B01B-BCCE9785ACA3"), "minecraft:base_attack_speed")
++ .build()
++ );
++ private static final Map<String, String> NAME_TO_ID = new HashMap<>(
++ Map.of(
++ "Random spawn bonus", "minecraft:random_spawn_bonus",
++ "Random zombie-spawn bonus", "minecraft:zombie_random_spawn_bonus",
++ "Leader zombie bonus", "minecraft:leader_zombie_bonus",
++ "Zombie reinforcement callee charge", "minecraft:reinforcement_callee_charge",
++ "Zombie reinforcement caller charge", "minecraft:reinforcement_caller_charge"
++ )
++ );
++
++ private static UUID makeUUID(final int[] arr) {
++ if (arr == null || arr.length != 4) {
++ return null;
++ }
++
++ final long most = ((long)arr[0] << 32) | ((long)arr[1] & 0xFFFFFFFFL);
++ final long least = ((long)arr[2] << 32) | ((long)arr[3] & 0xFFFFFFFFL);
++
++ return new UUID(most, least);
++ }
++
++ private static ListType remapModifiers(final ListType list) {
++ final Map<String, MapType<String>> ret = new LinkedHashMap<>();
++
++ for (int i = 0, len = list.size(); i < len; ++i) {
++ final MapType<String> modifier = list.<String>getMap(i).copy();
++
++ final UUID uuid = makeUUID(modifier.getInts("uuid"));
++ final String name = modifier.getString("name", "");
++
++ final String remappedUUID = UUID_TO_ID.get(uuid);
++ final String remappedName = NAME_TO_ID.get(name);
++
++ if (remappedUUID != null) {
++ modifier.remove("uuid");
++ modifier.remove("name");
++
++ modifier.setString("id", remappedUUID);
++
++ ret.put(remappedUUID, modifier);
++ } else if (remappedName != null) {
++ final MapType<String> existing = ret.get(remappedName);
++ if (existing != null) {
++ existing.setDouble("amount",
++ existing.getDouble("amount", 0.0) + modifier.getDouble("amount", 0.0)
++ );
++ } else {
++ modifier.remove("uuid");
++ modifier.remove("name");
++
++ modifier.setString("id", remappedName);
++
++ ret.put(remappedName, modifier);
++ }
++ } else {
++ final String id = "minecraft:" + (uuid == null ? "unknown" : uuid.toString().toLowerCase(Locale.ROOT));
++
++ modifier.setString("id", id);
++
++ ret.put(id, modifier);
++ }
++ }
++
++ final ListType retList = list.getTypeUtil().createEmptyList();
++
++ for (final MapType<String> modifier : ret.values()) {
++ retList.addMap(modifier);
++ }
++
++ return retList;
++ }
++
++
++ public static void register() {
++
++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) {
++ @Override
++ public MapType<String> convert(final MapType<String> data, final long sourceVersion, final long toVersion) {
++ final MapType<String> components = data.getMap("components");
++ if (components == null) {
++ return null;
++ }
++
++ final MapType<String> attributeModifiers = components.getMap("minecraft:attribute_modifiers");
++ if (attributeModifiers == null) {
++ return null;
++ }
++
++ final ListType modifiers = attributeModifiers.getList("modifiers", ObjectType.MAP);
++ if (modifiers == null) {
++ return null;
++ }
++
++ attributeModifiers.setList("modifiers", remapModifiers(modifiers));
++
++ return null;
++ }
++ });
++
++ final DataConverter<MapType<String>, MapType<String>> entityConverter = new DataConverter<>(VERSION) {
++ @Override
++ public MapType<String> convert(final MapType<String> data, final long sourceVersion, final long toVersion) {
++ RenameHelper.renameSingle(data, "Attributes", "attributes");
++
++ final ListType attributes = data.getList("attributes", ObjectType.MAP);
++ if (attributes == null) {
++ return null;
++ }
++
++ for (int i = 0, len = attributes.size(); i < len; ++i) {
++ final MapType<String> attribute = attributes.getMap(i);
++
++ RenameHelper.renameSingle(attribute, "Name", "id");
++ RenameHelper.renameSingle(attribute, "Base", "base");
++ RenameHelper.renameSingle(attribute, "Modifiers", "modifiers");
++
++ final ListType modifiers = attribute.getList("modifiers", ObjectType.MAP);
++
++ if (modifiers == null) {
++ continue;
++ }
++
++ for (int j = 0, len2 = modifiers.size(); j < len2; ++j) {
++ final MapType<String> modifier = modifiers.getMap(j);
++
++ RenameHelper.renameSingle(modifier, "UUID", "uuid");
++ RenameHelper.renameSingle(modifier, "Name", "name");
++ RenameHelper.renameSingle(modifier, "Amount", "amount");
++ final String newOp;
++ switch (modifier.getInt("Operation", 0)) {
++ case 0: {
++ newOp = "add_value";
++ break;
++ }
++ case 1: {
++ newOp = "add_multiplied_base";
++ break;
++ }
++ case 2: {
++ newOp = "add_multiplied_total";
++ break;
++ }
++ default: {
++ newOp = "invalid";
++ break;
++ }
++ }
++ modifier.remove("Operation");
++ modifier.setString("operation", newOp);
++ }
++
++ attribute.setList("modifiers", remapModifiers(modifiers));
++ }
++
++ return null;
++ }
++ };
++
++ MCTypeRegistry.ENTITY.addStructureConverter(entityConverter);
++ MCTypeRegistry.PLAYER.addStructureConverter(entityConverter);
++
++
++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:jukebox", new DataConverter<>(VERSION) {
++ @Override
++ public MapType<String> convert(final MapType<String> data, final long sourceVersion, final long toVersion) {
++ final long playingFor = data.getLong("TickCount") - data.getLong("RecordStartTick");
++
++ data.remove("IsPlaying");
++ data.remove("TickCount");
++ data.remove("RecordStartTick");
++
++ if (playingFor > 0L) {
++ data.setLong("ticks_since_song_started", playingFor);
++ }
++
++ return null;
++ }
++ });
++ }
++
++ private V3945() {}
++}
diff --git a/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java b/src/main/java/ca/spottedleaf/dataconverter/minecraft/versions/V501.java
new file mode 100644
index 0000000000000000000000000000000000000000..a7a4d6446b7765ac485af82df660aafab05955bf
@@ -28832,11 +29211,11 @@ index 0000000000000000000000000000000000000000..5a6536377c9c1e1753e930ff2a6bb98e
+ }
+}
diff --git a/src/main/java/net/minecraft/data/structures/StructureUpdater.java b/src/main/java/net/minecraft/data/structures/StructureUpdater.java
-index c0296e62fe46302e887b0c4528471e3bccde1c67..1327a33c594b56a2142d35fff8e6ef07f688797d 100644
+index 6082d2a4dda21e1b1a9154629aaf0b282b154a42..d8fe611bb4e121dfe96ccd5b8e7949f91eeba023 100644
--- a/src/main/java/net/minecraft/data/structures/StructureUpdater.java
+++ b/src/main/java/net/minecraft/data/structures/StructureUpdater.java
-@@ -25,7 +25,7 @@ public class StructureUpdater implements SnbtToNbt.Filter {
- LOGGER.warn("SNBT Too old, do not forget to update: {} < {}: {}", i, 3798, name);
+@@ -27,7 +27,7 @@ public class StructureUpdater implements SnbtToNbt.Filter {
+ LOGGER.warn("SNBT Too old, do not forget to update: {} < {}: {}", i, 3937, name);
}
- CompoundTag compoundTag = DataFixTypes.STRUCTURE.updateToCurrentVersion(DataFixers.getDataFixer(), nbt, i);
@@ -28845,38 +29224,38 @@ index c0296e62fe46302e887b0c4528471e3bccde1c67..1327a33c594b56a2142d35fff8e6ef07
return structureTemplate.save(new CompoundTag());
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
-index e605dbdb821b2d13217ac88426e50480a4e4741d..a62c90e10c0dfa4c6211a05c4071932756d7b218 100644
+index f0f5e9bb5ac65250f0a151f9f90b58468335a8c2..278019416ce3be0ccec703c6a70c2a29f11e21b1 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/ChunkStorage.java
-@@ -83,7 +83,7 @@ public class ChunkStorage implements AutoCloseable {
-
- try {
- // CraftBukkit start
-- if (i < 1466) {
-+ if (false && i < 1466) { // Paper - no longer needed, data converter system / DFU handles it now
- CompoundTag level = nbttagcompound.getCompound("Level");
- if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) {
- ServerChunkCache cps = (generatoraccess == null) ? null : ((ServerLevel) generatoraccess).getChunkSource();
-@@ -95,7 +95,7 @@ public class ChunkStorage implements AutoCloseable {
- // CraftBukkit end
+@@ -86,7 +86,7 @@ public class ChunkStorage implements AutoCloseable {
+ } else {
+ try {
+ // CraftBukkit start
+- if (i < 1466) {
++ if (false && i < 1466) { // Paper - no longer needed, data converter system / DFU handles it now
+ CompoundTag level = nbttagcompound.getCompound("Level");
+ if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) {
+ ServerChunkCache cps = (generatoraccess == null) ? null : ((ServerLevel) generatoraccess).getChunkSource();
+@@ -98,7 +98,7 @@ public class ChunkStorage implements AutoCloseable {
+ // CraftBukkit end
- if (i < 1493) {
-- nbttagcompound = DataFixTypes.CHUNK.update(this.fixerUpper, nbttagcompound, i, 1493);
-+ ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, nbttagcompound, i, 1493); // Paper - replace chunk converter
- if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
- LegacyStructureDataHandler persistentstructurelegacy = this.getLegacyStructureHandler(resourcekey, supplier);
+ if (i < 1493) {
+- nbttagcompound = DataFixTypes.CHUNK.update(this.fixerUpper, nbttagcompound, i, 1493);
++ nbttagcompound = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, nbttagcompound, i, 1493); // Paper - replace chunk converter
+ if (nbttagcompound.getCompound("Level").getBoolean("hasLegacyStructureData")) {
+ LegacyStructureDataHandler persistentstructurelegacy = this.getLegacyStructureHandler(resourcekey, supplier);
-@@ -113,7 +113,7 @@ public class ChunkStorage implements AutoCloseable {
- // Spigot end
+@@ -116,7 +116,7 @@ public class ChunkStorage implements AutoCloseable {
+ // Spigot end
- ChunkStorage.injectDatafixingContext(nbttagcompound, resourcekey, optional);
-- nbttagcompound = DataFixTypes.CHUNK.updateToCurrentVersion(this.fixerUpper, nbttagcompound, Math.max(1493, i));
-+ nbttagcompound = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, nbttagcompound, Math.max(1493, i), SharedConstants.getCurrentVersion().getDataVersion().getVersion()); // Paper - replace chunk converter
- if (i < SharedConstants.getCurrentVersion().getDataVersion().getVersion()) {
- NbtUtils.addCurrentDataVersion(nbttagcompound);
- }
+ ChunkStorage.injectDatafixingContext(nbttagcompound, resourcekey, optional);
+- nbttagcompound = DataFixTypes.CHUNK.updateToCurrentVersion(this.fixerUpper, nbttagcompound, Math.max(1493, i));
++ nbttagcompound = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, nbttagcompound, Math.max(1493, i), SharedConstants.getCurrentVersion().getDataVersion().getVersion()); // Paper - replace chunk converter
+ // Spigot start
+ if (stopBelowZero) {
+ nbttagcompound.putString("Status", net.minecraft.core.registries.BuiltInRegistries.CHUNK_STATUS.getKey(ChunkStatus.SPAWN).toString());
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
-index cf44d7b48c774d4c2431d42e352b42d200ee1b71..fa4f9afb421c7924557372cbb2f20caf9e13c81c 100644
+index e0e843f4f69013379ed70cb63d9b4f72163b828b..578d270d5b7efb9ac8f5dde539170f6021e2b786 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java
@@ -32,13 +32,30 @@ public class SimpleRegionStorage implements AutoCloseable {
@@ -28927,10 +29306,10 @@ index c6181e14d85d454506534f9bbe856156c0d4a062..609100ed7aa0b23aa5a9c6fbf6878ea3
LOGGER.warn("Failed to partially datafix chunk {}", pos, var12);
return StructureCheckResult.CHUNK_LOAD_NEEDED;
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager.java
-index 39b4f29fb97464c2021b857bccb2fa933d4003d7..4d9dbf27c7c7d57a06e5f12b7fe30723d2cb69ef 100644
+index 05a76f9d18638f10218161450470f07524b723ac..3ab22c384bb8a7772d389977a61d0e28975fdb79 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager.java
-@@ -233,7 +233,7 @@ public class StructureTemplateManager {
+@@ -245,7 +245,7 @@ public class StructureTemplateManager {
public StructureTemplate readStructure(CompoundTag nbt) {
StructureTemplate structureTemplate = new StructureTemplate();
int i = NbtUtils.getDataVersion(nbt, 500);
@@ -28981,7 +29360,7 @@ index 1d287dd7379e56f7fd4b425880b850cd843f5789..8ab7ca373a885fbe658013c9c6a2e38d
return nbttagcompound;
});
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
-index f6c33a9e2900890e4f6cb19784e01ff438cce83d..f99353a60e3f236735ef6e2e6f13381b50ae9b7b 100644
+index be56e7a7607d3119e560f38e800ad4bbfe1e7714..5a04134973dd1db7f778a57ec5f185feec370990 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -522,7 +522,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
diff --git a/patches/server/0989-disable-forced-empty-world-ticks.patch b/patches/server/0990-disable-forced-empty-world-ticks.patch
index 7415c872ae..7415c872ae 100644
--- a/patches/server/0989-disable-forced-empty-world-ticks.patch
+++ b/patches/server/0990-disable-forced-empty-world-ticks.patch
diff --git a/patches/server/0990-stubs.patch b/patches/server/0991-stubs.patch
index 7f57021011..7f57021011 100644
--- a/patches/server/0990-stubs.patch
+++ b/patches/server/0991-stubs.patch