mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-26 22:10:18 +00:00
Test- 26.3
This commit is contained in:
1 parent
edadd14f4b
commit
f0e7fea13b
107 files changed
+25110
-86
No files matched your search
@@ -62,15 +62,10 @@ public final class DefaultPackBootstrapProvisioner {
|
||||
return DEFAULT_PACKS;
|
||||
}
|
||||
|
||||
public static ProvisionResult provision(Path dataDirectory, Consumer<String> feedback) throws IOException {
|
||||
return provision(dataDirectory, feedback, BukkitStartupPaths.resolveCurrent());
|
||||
}
|
||||
|
||||
public static ProvisionResult provision(
|
||||
Path dataDirectory,
|
||||
Consumer<String> feedback,
|
||||
BukkitStartupPaths startupPaths
|
||||
) throws IOException {
|
||||
public static ProvisionResult provision(BootstrapRequest request) throws IOException {
|
||||
Path dataDirectory = request.dataDirectory();
|
||||
Consumer<String> feedback = request.feedback();
|
||||
BukkitStartupPaths startupPaths = request.startupPaths();
|
||||
Objects.requireNonNull(dataDirectory, "dataDirectory");
|
||||
Objects.requireNonNull(feedback, "feedback");
|
||||
BukkitStartupPaths requiredStartupPaths = Objects.requireNonNull(startupPaths, "startupPaths");
|
||||
@@ -94,7 +89,8 @@ public final class DefaultPackBootstrapProvisioner {
|
||||
3,
|
||||
Duration.ofMillis(250),
|
||||
MAX_ARCHIVE_BYTES,
|
||||
levelRoot
|
||||
levelRoot,
|
||||
request.dataVersion()
|
||||
);
|
||||
return provision(dataDirectory, feedback, options);
|
||||
}
|
||||
@@ -135,7 +131,7 @@ public final class DefaultPackBootstrapProvisioner {
|
||||
if (!Integer.toString(MARKER_SCHEMA).equals(marker.getProperty("schema"))) {
|
||||
return false;
|
||||
}
|
||||
IDataFixer fixer = DataVersion.getLatest().get();
|
||||
IDataFixer fixer = DataVersion.getRuntime().get();
|
||||
if (fixer == null
|
||||
|| !IrisDatapackCompiler.compilerIdentity(fixer)
|
||||
.equals(marker.getProperty("compilerIdentity"))) {
|
||||
@@ -248,9 +244,9 @@ public final class DefaultPackBootstrapProvisioner {
|
||||
}
|
||||
|
||||
List<File> packRoots = IrisDatapackCompiler.collectPackRoots(normalizedData, options.levelRoot());
|
||||
IDataFixer fixer = DataVersion.getLatest().get();
|
||||
IDataFixer fixer = options.dataVersion().get();
|
||||
if (fixer == null) {
|
||||
throw new IOException("Latest Iris datapack fixer is unavailable during bootstrap");
|
||||
throw new IOException("Selected Iris datapack fixer is unavailable during bootstrap");
|
||||
}
|
||||
String compilerIdentity = IrisDatapackCompiler.compilerIdentity(fixer);
|
||||
String aggregateFingerprint = packRootsFingerprint(packRoots);
|
||||
@@ -915,6 +911,16 @@ public final class DefaultPackBootstrapProvisioner {
|
||||
}
|
||||
}
|
||||
|
||||
public record BootstrapRequest(Path dataDirectory, Consumer<String> feedback,
|
||||
BukkitStartupPaths startupPaths, DataVersion dataVersion) {
|
||||
public BootstrapRequest {
|
||||
Objects.requireNonNull(dataDirectory);
|
||||
Objects.requireNonNull(feedback);
|
||||
Objects.requireNonNull(startupPaths);
|
||||
Objects.requireNonNull(dataVersion);
|
||||
}
|
||||
}
|
||||
|
||||
record ProvisionOptions(
|
||||
List<PackSpec> packs,
|
||||
List<IrisGeneratorBinding> bindings,
|
||||
@@ -925,7 +931,8 @@ public final class DefaultPackBootstrapProvisioner {
|
||||
int attempts,
|
||||
Duration retryDelay,
|
||||
long maxArchiveBytes,
|
||||
Path levelRoot
|
||||
Path levelRoot,
|
||||
DataVersion dataVersion
|
||||
) {
|
||||
ProvisionOptions {
|
||||
packs = List.copyOf(Objects.requireNonNull(packs, "packs"));
|
||||
@@ -936,6 +943,10 @@ public final class DefaultPackBootstrapProvisioner {
|
||||
Objects.requireNonNull(requestTimeout, "requestTimeout");
|
||||
Objects.requireNonNull(retryDelay, "retryDelay");
|
||||
Objects.requireNonNull(levelRoot, "levelRoot");
|
||||
Objects.requireNonNull(dataVersion, "dataVersion");
|
||||
if (dataVersion == DataVersion.UNSUPPORTED) {
|
||||
throw new IllegalArgumentException("Unsupported bootstrap datapack version");
|
||||
}
|
||||
if (attempts < 1 || maxArchiveBytes < 1L) {
|
||||
throw new IllegalArgumentException("Invalid bootstrap provisioning options");
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ public interface INMSBinding {
|
||||
if (!supportsIrisWorldGeneration()) {
|
||||
throw new IllegalStateException("Iris world '" + c.name() + "' cannot be created with limited NMS binding "
|
||||
+ getClass().getSimpleName()
|
||||
+ "; set general.disableNMS=false and use a supported Minecraft server runtime (26.1.2 or 26.2)");
|
||||
+ "; set general.disableNMS=false and use a supported Minecraft server runtime (26.1.2, 26.2 or 26.3)");
|
||||
}
|
||||
if (missingDimensionTypes(generator.getTarget().getDimension().getDimensionTypeKey())) {
|
||||
throw new IllegalStateException("Missing dimension types to create world");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package art.arcane.iris.platform.bukkit.nms;
|
||||
|
||||
final class NmsBindingSelector {
|
||||
private static final String SUPPORTED_VERSIONS = "26.1.2 or 26.2";
|
||||
private static final String SUPPORTED_VERSIONS = "26.1.2, 26.2 or 26.3";
|
||||
private static final String SUPPORTED_TAG = "v26_2_R1";
|
||||
|
||||
private NmsBindingSelector() {
|
||||
@@ -11,6 +11,9 @@ final class NmsBindingSelector {
|
||||
if (version == null) {
|
||||
throw new IllegalStateException("Iris requires an exact Minecraft version before selecting NMS");
|
||||
}
|
||||
if (version.isSameRelease(26, 3, 0)) {
|
||||
return "v26_3_R1";
|
||||
}
|
||||
if (!version.isSameRelease(26, 2, 0) && !version.isSameRelease(26, 1, 2)) {
|
||||
throw new IllegalStateException("Iris requires Minecraft " + SUPPORTED_VERSIONS
|
||||
+ ". Detected server version: " + version.value());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package art.arcane.iris.platform.bukkit.nms.datapack;
|
||||
|
||||
import art.arcane.iris.spi.IrisLogging;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import art.arcane.iris.platform.bukkit.nms.INMS;
|
||||
import art.arcane.iris.platform.bukkit.nms.datapack.v1217.DataFixerV1217;
|
||||
import art.arcane.volmlib.util.collection.KMap;
|
||||
@@ -8,13 +9,15 @@ import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
import art.arcane.iris.platform.bukkit.nms.datapack.v263.DataFixerV263;
|
||||
|
||||
//https://minecraft.wiki/w/Pack_format
|
||||
@Getter
|
||||
public enum DataVersion {
|
||||
UNSUPPORTED("0.0.0", 0, () -> null),
|
||||
V26_1_2("26.1.2", 101, DataFixerV1217::new),
|
||||
V26_2("26.2", 107, DataFixerV1217::new);
|
||||
V26_2("26.2", 107, DataFixerV1217::new),
|
||||
V26_3("26.3", 121, DataFixerV263::new);
|
||||
private static final KMap<DataVersion, IDataFixer> cache = new KMap<>();
|
||||
@Getter(AccessLevel.NONE)
|
||||
private final Supplier<IDataFixer> constructor;
|
||||
@@ -49,6 +52,29 @@ public enum DataVersion {
|
||||
return fixer;
|
||||
}
|
||||
|
||||
public static DataVersion forMinecraftVersion(String version) {
|
||||
if (version == null) {
|
||||
return UNSUPPORTED;
|
||||
}
|
||||
return switch (version) {
|
||||
case "26.1.2" -> V26_1_2;
|
||||
case "26.2", "26.2.0" -> V26_2;
|
||||
case "26.3", "26.3.0" -> V26_3;
|
||||
default -> UNSUPPORTED;
|
||||
};
|
||||
}
|
||||
|
||||
public static DataVersion getRuntime() {
|
||||
if (!IrisPlatforms.isBound() || IrisPlatforms.get().minecraftVersion() == null) {
|
||||
return getLatest();
|
||||
}
|
||||
DataVersion version = forMinecraftVersion(IrisPlatforms.get().minecraftVersion());
|
||||
if (version == UNSUPPORTED) {
|
||||
throw new IllegalStateException("Unsupported Minecraft datapack version: " + IrisPlatforms.get().minecraftVersion());
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
public static DataVersion getLatest() {
|
||||
return values()[values().length - 1];
|
||||
}
|
||||
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
package art.arcane.iris.platform.bukkit.nms.datapack.v263;
|
||||
|
||||
import art.arcane.iris.generation.biome.IrisBiomeCustom;
|
||||
import art.arcane.iris.platform.bukkit.nms.datapack.v1217.DataFixerV1217;
|
||||
import art.arcane.volmlib.util.json.JSONArray;
|
||||
import art.arcane.volmlib.util.json.JSONObject;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public final class DataFixerV263 extends DataFixerV1217 {
|
||||
@Override
|
||||
public JSONObject fixCustomBiome(IrisBiomeCustom biome, JSONObject json) {
|
||||
JSONObject fixed = super.fixCustomBiome(biome, json);
|
||||
JSONObject attributes = fixed.getJSONObject("attributes");
|
||||
JSONObject effects = fixed.getJSONObject("effects");
|
||||
for (String key : new String[]{"water_color", "foliage_color", "dry_foliage_color", "grass_color"}) {
|
||||
color(effects, key);
|
||||
}
|
||||
for (String key : new String[]{"minecraft:visual/sky_color", "minecraft:visual/fog_color", "minecraft:visual/water_fog_color"}) {
|
||||
color(attributes, key);
|
||||
}
|
||||
JSONObject spawners = fixed.getJSONObject("spawners");
|
||||
for (String category : spawners.keySet()) {
|
||||
JSONArray entries = spawners.getJSONArray(category);
|
||||
for (int index = 0; index < entries.length(); index++) {
|
||||
JSONObject spawn = entries.getJSONObject(index);
|
||||
int minimum = spawn.getInt("minCount");
|
||||
int maximum = spawn.getInt("maxCount");
|
||||
spawn.remove("minCount");
|
||||
spawn.remove("maxCount");
|
||||
spawn.put("count", minimum == maximum ? minimum : new JSONObject()
|
||||
.put("type", "minecraft:uniform")
|
||||
.put("min_inclusive", minimum)
|
||||
.put("max_inclusive", maximum));
|
||||
}
|
||||
}
|
||||
attributes.put("minecraft:gameplay/natural_mob_spawns", new JSONObject()
|
||||
.put("spawns_by_category", spawners)
|
||||
.put("spawn_costs", fixed.getJSONObject("spawn_costs")));
|
||||
Object probability = fixed.remove("creature_spawn_probability");
|
||||
if (probability != null) {
|
||||
attributes.put("minecraft:gameplay/creature_world_gen_spawn_probability", probability);
|
||||
}
|
||||
fixed.remove("spawners");
|
||||
fixed.remove("spawn_costs");
|
||||
return fixed;
|
||||
}
|
||||
|
||||
private static void color(JSONObject object, String key) {
|
||||
if (object.opt(key) instanceof Number value) {
|
||||
object.put(key, String.format(Locale.ROOT, "#%06x", value.intValue() & 0xFFFFFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -317,6 +317,6 @@ public class NMSBinding1X implements INMSBinding {
|
||||
private IllegalStateException unsupportedStructureHook(String operation) {
|
||||
return new IllegalStateException("Iris cannot " + operation + " with limited NMS binding "
|
||||
+ getClass().getSimpleName()
|
||||
+ "; set general.disableNMS=false and use a supported Minecraft server runtime (26.1.2 or 26.2)");
|
||||
+ "; set general.disableNMS=false and use a supported Minecraft server runtime (26.1.2, 26.2 or 26.3)");
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package art.arcane.iris.structure.export;
|
||||
|
||||
import art.arcane.volmlib.util.nbt.tag.CompoundTag;
|
||||
import art.arcane.volmlib.util.nbt.mca.MCABlockStateCodecSupport;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -73,15 +74,15 @@ record VanillaBlockState(String name, Map<String, String> properties) {
|
||||
return builder.append(']').toString();
|
||||
}
|
||||
|
||||
CompoundTag toNbt() {
|
||||
CompoundTag toNbt(MCABlockStateCodecSupport.Format format) {
|
||||
CompoundTag state = new CompoundTag();
|
||||
state.putString("Name", name);
|
||||
state.putString(format.nameKey(), name);
|
||||
if (!properties.isEmpty()) {
|
||||
CompoundTag propertyTag = new CompoundTag();
|
||||
for (Map.Entry<String, String> property : properties.entrySet()) {
|
||||
propertyTag.putString(property.getKey(), property.getValue());
|
||||
}
|
||||
state.put("Properties", propertyTag);
|
||||
state.put(format.propertiesKey(), propertyTag);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
+8
-6
@@ -211,7 +211,7 @@ final class VanillaJigsawExportCompiler {
|
||||
addError(diagnostics,
|
||||
VanillaJigsawExportDiagnostic.Code.INVALID_MAX_DEPTH,
|
||||
structureKey(structure),
|
||||
"Minecraft 26.2 jigsaw size must be within 0..20; Iris export requires 1..20.");
|
||||
"Minecraft jigsaw size must be within 0..20; Iris export requires 1..20.");
|
||||
}
|
||||
long horizontalDistance = (long) structure.getMaxSizeChunks() * 16L;
|
||||
if (horizontalDistance < 1L || horizontalDistance > MAX_HORIZONTAL_DISTANCE) {
|
||||
@@ -219,7 +219,7 @@ final class VanillaJigsawExportCompiler {
|
||||
VanillaJigsawExportDiagnostic.Code.INVALID_MAX_DISTANCE,
|
||||
structureKey(structure),
|
||||
"Iris maxSizeChunks maps to " + horizontalDistance
|
||||
+ " blocks, outside Minecraft 26.2's 1..128 horizontal limit.");
|
||||
+ " blocks, outside Minecraft's 1..128 horizontal limit.");
|
||||
}
|
||||
int terrainPadding = settings.terrainAdaptation() == VanillaJigsawExportSettings.TerrainAdaptation.NONE
|
||||
? 0 : 12;
|
||||
@@ -315,7 +315,7 @@ final class VanillaJigsawExportCompiler {
|
||||
addError(diagnostics,
|
||||
VanillaJigsawExportDiagnostic.Code.INVALID_POOL_WEIGHT,
|
||||
poolKey + "/pieces[" + index + "]",
|
||||
"Minecraft 26.2 template-pool weights must be within 1..150.");
|
||||
"Minecraft template-pool weights must be within 1..150.");
|
||||
}
|
||||
if (entry.getChance() != 1D) {
|
||||
addError(diagnostics,
|
||||
@@ -577,10 +577,12 @@ final class VanillaJigsawExportCompiler {
|
||||
JsonObject pack = new JsonObject();
|
||||
pack.addProperty("description", request.description());
|
||||
JsonArray minimum = new JsonArray();
|
||||
minimum.add(107);
|
||||
minimum.add(1);
|
||||
boolean current = VanillaStructureTemplateEncoder.targets263();
|
||||
int packFormat = current ? 121 : 107;
|
||||
minimum.add(packFormat);
|
||||
minimum.add(current ? 0 : 1);
|
||||
pack.add("min_format", minimum);
|
||||
pack.addProperty("max_format", 107);
|
||||
pack.addProperty("max_format", packFormat);
|
||||
JsonObject root = new JsonObject();
|
||||
root.add("pack", pack);
|
||||
return root;
|
||||
|
||||
@@ -65,7 +65,7 @@ public final class VanillaJigsawExportRequest {
|
||||
private final Path output;
|
||||
private String namespace = "iris";
|
||||
private String resourcePath;
|
||||
private String description = "Iris vanilla jigsaw export for Minecraft 26.2";
|
||||
private String description = "Iris vanilla jigsaw export";
|
||||
private VanillaJigsawExportFormat format = VanillaJigsawExportFormat.DIRECTORY;
|
||||
private VanillaJigsawExportSettings settings = VanillaJigsawExportSettings.defaults();
|
||||
private boolean replaceExisting;
|
||||
|
||||
+14
-4
@@ -1,6 +1,8 @@
|
||||
package art.arcane.iris.structure.export;
|
||||
|
||||
import art.arcane.iris.pack.value.IrisDirection;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import art.arcane.volmlib.util.nbt.mca.MCABlockStateCodecSupport;
|
||||
import art.arcane.iris.structure.jigsaw.IrisJigsawConnector;
|
||||
import art.arcane.iris.structure.jigsaw.IrisJigsawPiece;
|
||||
import art.arcane.iris.structure.object.IrisObject;
|
||||
@@ -51,18 +53,26 @@ final class VanillaStructureTemplateEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
boolean lowercase = targets263();
|
||||
MCABlockStateCodecSupport.Format format = lowercase
|
||||
? MCABlockStateCodecSupport.Format.LOWERCASE : MCABlockStateCodecSupport.Format.CAPITALIZED;
|
||||
CompoundTag root = new CompoundTag();
|
||||
root.put("size", intList(object.getW(), object.getH(), object.getD()));
|
||||
root.put("palette", palette(paletteStates));
|
||||
root.put("palette", palette(paletteStates, format));
|
||||
root.put("blocks", blocks(orderedBlocks, paletteIndexes));
|
||||
root.put("entities", new ListTag<>(CompoundTag.class));
|
||||
root.putInt("DataVersion", DATA_VERSION_26_2);
|
||||
root.putInt("DataVersion", lowercase ? 5023 : DATA_VERSION_26_2);
|
||||
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
NBTUtil.write(new NamedTag("", root), output, true);
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
static boolean targets263() {
|
||||
String minecraftVersion = IrisPlatforms.get().minecraftVersion();
|
||||
return "26.3".equals(minecraftVersion) || "26.3.0".equals(minecraftVersion);
|
||||
}
|
||||
|
||||
private Map<BlockPosition, BlockEntry> objectBlocks(IrisObject object) {
|
||||
Map<BlockPosition, BlockEntry> blocks = new LinkedHashMap<>();
|
||||
Vector3i center = object.getCenter();
|
||||
@@ -135,10 +145,10 @@ final class VanillaStructureTemplateEncoder {
|
||||
};
|
||||
}
|
||||
|
||||
private ListTag<CompoundTag> palette(List<VanillaBlockState> states) {
|
||||
private ListTag<CompoundTag> palette(List<VanillaBlockState> states, MCABlockStateCodecSupport.Format format) {
|
||||
ListTag<CompoundTag> palette = new ListTag<>(CompoundTag.class);
|
||||
for (VanillaBlockState state : states) {
|
||||
palette.add(state.toNbt());
|
||||
palette.add(state.toNbt(format));
|
||||
}
|
||||
return palette;
|
||||
}
|
||||
|
||||
+6
-6
@@ -110,7 +110,7 @@ public final class GenerationRegistryContractFactory {
|
||||
data,
|
||||
dimension,
|
||||
packFingerprint,
|
||||
DataVersion.getLatest().get(),
|
||||
DataVersion.getRuntime().get(),
|
||||
registries,
|
||||
registries.generationRegistry(),
|
||||
aliasPolicy
|
||||
@@ -224,7 +224,7 @@ public final class GenerationRegistryContractFactory {
|
||||
data,
|
||||
dimension,
|
||||
customBiome,
|
||||
DataVersion.getLatest().get(),
|
||||
DataVersion.getRuntime().get(),
|
||||
registry
|
||||
);
|
||||
}
|
||||
@@ -508,7 +508,7 @@ public final class GenerationRegistryContractFactory {
|
||||
) throws IOException {
|
||||
return captureRequiredDefinitions(
|
||||
requiredContracts,
|
||||
DataVersion.getLatest().get(),
|
||||
DataVersion.getRuntime().get(),
|
||||
IrisPlatforms.get().registries().generationRegistry()
|
||||
);
|
||||
}
|
||||
@@ -519,7 +519,7 @@ public final class GenerationRegistryContractFactory {
|
||||
) throws IOException {
|
||||
return captureRequiredDefinitions(
|
||||
requiredContracts,
|
||||
DataVersion.getLatest().get(),
|
||||
DataVersion.getRuntime().get(),
|
||||
generationRegistry
|
||||
);
|
||||
}
|
||||
@@ -603,7 +603,7 @@ public final class GenerationRegistryContractFactory {
|
||||
return requireGeneratedSource(
|
||||
contract,
|
||||
key,
|
||||
DataVersion.getLatest().get(),
|
||||
DataVersion.getRuntime().get(),
|
||||
IrisPlatforms.get().registries().generationRegistry()
|
||||
);
|
||||
}
|
||||
@@ -652,7 +652,7 @@ public final class GenerationRegistryContractFactory {
|
||||
return requireGeneratedSource(
|
||||
contract,
|
||||
key,
|
||||
DataVersion.getLatest().get(),
|
||||
DataVersion.getRuntime().get(),
|
||||
generationRegistry
|
||||
);
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ public final class SavedTerrainChunk {
|
||||
case "biomes" -> 3;
|
||||
case "noise" -> 4;
|
||||
case "surface" -> 5;
|
||||
case "carvers" -> 6;
|
||||
case "carvers", "terrain" -> 6;
|
||||
case "features" -> 7;
|
||||
case "initialize_light" -> 8;
|
||||
case "light" -> 9;
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package art.arcane.iris.world.history;
|
||||
|
||||
import art.arcane.volmlib.util.nbt.io.NBTUtil;
|
||||
import art.arcane.iris.spi.IrisPlatforms;
|
||||
import art.arcane.iris.spi.PlatformBlockState;
|
||||
import art.arcane.volmlib.util.nbt.mca.MCABlockStateCodecSupport;
|
||||
import art.arcane.volmlib.util.nbt.tag.CompoundTag;
|
||||
import art.arcane.volmlib.util.nbt.tag.ByteArrayTag;
|
||||
import art.arcane.volmlib.util.nbt.tag.ListTag;
|
||||
@@ -81,7 +84,8 @@ final class SavedTerrainChunkReader {
|
||||
if (sectionY * 16 < minimumY || sectionY * 16 >= (long) minimumY + height) {
|
||||
continue;
|
||||
}
|
||||
if (sections.put(sectionY, decodeSection(section)) != null) {
|
||||
if (sections.put(sectionY, decodeSection(section, root.getInt("DataVersion") >= 5023
|
||||
? MCABlockStateCodecSupport.Format.LOWERCASE : MCABlockStateCodecSupport.Format.CAPITALIZED)) != null) {
|
||||
throw new IOException("Saved chunk contains duplicate section " + sectionY);
|
||||
}
|
||||
}
|
||||
@@ -158,16 +162,29 @@ final class SavedTerrainChunkReader {
|
||||
return section;
|
||||
}
|
||||
|
||||
private static Section decodeSection(CompoundTag section) throws IOException {
|
||||
private static Section decodeSection(CompoundTag section, MCABlockStateCodecSupport.Format format) throws IOException {
|
||||
CompoundTag blocks = compound(section, "block_states");
|
||||
CompoundTag biomes = compound(section, "biomes");
|
||||
ListTag<?> blockPalette = list(blocks, "palette");
|
||||
List<BoundaryColumnGeometry.Voxel> decodedBlocks = new ArrayList<>(blockPalette.size());
|
||||
for (Tag<?> entry : blockPalette) {
|
||||
if (!(entry instanceof CompoundTag state)) {
|
||||
throw new IOException("Saved block palette entry is not a compound");
|
||||
Tag<?> state = entry;
|
||||
if (format == MCABlockStateCodecSupport.Format.LOWERCASE
|
||||
&& state instanceof CompoundTag wrapped && wrapped.size() == 1 && wrapped.containsKey("")) {
|
||||
state = wrapped.get("");
|
||||
}
|
||||
if (format == MCABlockStateCodecSupport.Format.LOWERCASE && state instanceof StringTag name) {
|
||||
PlatformBlockState resolved = IrisPlatforms.get().registries().blockOrNull(name.getValue());
|
||||
if (resolved == null) {
|
||||
throw new IOException("Saved block state cannot be resolved: " + name.getValue());
|
||||
}
|
||||
decodedBlocks.add(decodeBlock(MCABlockStateCodecSupport.encodeBlockState(
|
||||
resolved.key(), name.getValue(), format), format));
|
||||
} else if (state instanceof CompoundTag compound) {
|
||||
decodedBlocks.add(decodeBlock(compound, format));
|
||||
} else {
|
||||
throw new IOException("Saved block palette entry is not a block state");
|
||||
}
|
||||
decodedBlocks.add(decodeBlock(state));
|
||||
}
|
||||
ListTag<?> biomePalette = list(biomes, "palette");
|
||||
List<String> decodedBiomes = new ArrayList<>(biomePalette.size());
|
||||
@@ -181,10 +198,10 @@ final class SavedTerrainChunkReader {
|
||||
new Palette<>(decodedBiomes, packedData(biomes), 1, 64));
|
||||
}
|
||||
|
||||
private static BoundaryColumnGeometry.Voxel decodeBlock(CompoundTag state) throws IOException {
|
||||
String name = string(state, "Name");
|
||||
private static BoundaryColumnGeometry.Voxel decodeBlock(CompoundTag state, MCABlockStateCodecSupport.Format format) throws IOException {
|
||||
String name = string(state, format.nameKey());
|
||||
TreeMap<String, String> properties = new TreeMap<>();
|
||||
if (state.get("Properties") instanceof CompoundTag values) {
|
||||
if (state.get(format.propertiesKey()) instanceof CompoundTag values) {
|
||||
for (Map.Entry<String, Tag<?>> property : values) {
|
||||
if (!(property.getValue() instanceof StringTag value)) {
|
||||
throw new IOException("Saved block property is not a string");
|
||||
@@ -192,6 +209,13 @@ final class SavedTerrainChunkReader {
|
||||
properties.put(property.getKey(), value.getValue());
|
||||
}
|
||||
}
|
||||
return decodeBlock(name, properties);
|
||||
}
|
||||
|
||||
private static BoundaryColumnGeometry.Voxel decodeBlock(String name, Map<String, String> properties) throws IOException {
|
||||
if (name.isBlank()) {
|
||||
throw new IOException("Saved block state has no resource key");
|
||||
}
|
||||
String stateKey = stateKey(name, properties);
|
||||
if (name.equals("minecraft:air") || name.equals("minecraft:cave_air") || name.equals("minecraft:void_air")) {
|
||||
return name.equals("minecraft:air") ? AIR
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
package art.arcane.iris.world.storage.region;
|
||||
|
||||
import art.arcane.iris.platform.bukkit.BukkitBlockResolution;
|
||||
import art.arcane.volmlib.util.nbt.mca.MCABlockStateCodecSupport;
|
||||
import art.arcane.iris.platform.bukkit.nms.datapack.DataVersion;
|
||||
|
||||
import art.arcane.iris.spi.IrisLogging;
|
||||
import art.arcane.iris.platform.bukkit.nms.INMS;
|
||||
@@ -30,6 +32,7 @@ import art.arcane.volmlib.util.nbt.mca.NBTWorldSupport;
|
||||
import art.arcane.iris.platform.reflect.KeyedType;
|
||||
import art.arcane.volmlib.util.math.M;
|
||||
import art.arcane.volmlib.util.nbt.tag.CompoundTag;
|
||||
import art.arcane.volmlib.util.nbt.tag.Tag;
|
||||
import art.arcane.iris.generation.concurrent.HyperLock;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Registry;
|
||||
@@ -43,7 +46,7 @@ import java.util.Locale;
|
||||
public class NBTWorld {
|
||||
private static final class Holder {
|
||||
private static final BlockData AIR = BukkitBlockResolution.get("AIR");
|
||||
private static final NBTWorldSupport.BlockStateCodec<BlockData> BLOCK_STATE_CODEC = NBTWorldSupport.blockStateCodec(
|
||||
private static final NBTWorldSupport.BlockStateCodec<BlockData> BLOCK_STATE_CODEC = NBTWorldSupport.blockStateCodec(new NBTWorldSupport.BlockStateCodecOptions<>(
|
||||
blockStateString -> BukkitBlockResolution.getOrNull(blockStateString, true),
|
||||
BukkitBlockResolution::getAir,
|
||||
blockData -> blockData.getAsString(true),
|
||||
@@ -53,8 +56,11 @@ public class NBTWorld {
|
||||
return "minecraft:" + blockData.getMaterial().name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
return key.getNamespace() + ":" + key.getKey();
|
||||
}
|
||||
);
|
||||
},
|
||||
INMS.get().getDataVersion() == DataVersion.V26_3
|
||||
? MCABlockStateCodecSupport.Format.LOWERCASE
|
||||
: MCABlockStateCodecSupport.Format.CAPITALIZED
|
||||
));
|
||||
private static final Map<Biome, Integer> BIOME_IDS = computeBiomeIDs();
|
||||
}
|
||||
|
||||
@@ -127,7 +133,7 @@ public class NBTWorld {
|
||||
);
|
||||
}
|
||||
|
||||
public static BlockData getBlockData(CompoundTag tag) {
|
||||
public static BlockData getBlockData(Tag<?> tag) {
|
||||
return Holder.BLOCK_STATE_CODEC.decode(tag);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user