mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-08-27 04:37:47 +00:00
First Test MV
This commit is contained in:
@@ -18,9 +18,9 @@ Canonical English is defined in the typed Java catalogs under `core/src/main/jav
|
|||||||
|
|
||||||
| Platform | Artifact | Minecraft | Notes |
|
| Platform | Artifact | Minecraft | Notes |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| Paper / Purpur / Leaf / Canvas | plugin jar | 26.2 | Full feature set |
|
| Paper / Purpur / Leaf / Canvas | plugin jar | 26.1.2 - 26.2 | Full feature set |
|
||||||
| Folia | plugin jar | 26.2 | Region-safe scheduling throughout |
|
| Folia | plugin jar | 26.1.2 - 26.2 | Region-safe scheduling throughout |
|
||||||
| Spigot / CraftBukkit | plugin jar | 26.2 | Full feature set |
|
| Spigot / CraftBukkit | plugin jar | 26.1.2 - 26.2 | Full feature set |
|
||||||
| Fabric | mod jar | 26.2 | Server worldgen + client HUD; requires Fabric Loader 0.19.3+ |
|
| Fabric | mod jar | 26.2 | Server worldgen + client HUD; requires Fabric Loader 0.19.3+ |
|
||||||
| Forge | mod jar | 26.2 | Server worldgen + client HUD; requires Forge 65.0.4+ |
|
| Forge | mod jar | 26.2 | Server worldgen + client HUD; requires Forge 65.0.4+ |
|
||||||
| NeoForge | mod jar | 26.2 | Server worldgen + client HUD; requires NeoForge 26.2.0.12-beta+ |
|
| NeoForge | mod jar | 26.2 | Server worldgen + client HUD; requires NeoForge 26.2.0.12-beta+ |
|
||||||
|
|||||||
+21
-17
@@ -6,6 +6,7 @@ import ca.spottedleaf.moonrise.patches.chunk_system.scheduling.NewChunkHolder;
|
|||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import art.arcane.iris.spi.IrisLogging;
|
import art.arcane.iris.spi.IrisLogging;
|
||||||
import art.arcane.iris.core.nms.INMSBinding;
|
import art.arcane.iris.core.nms.INMSBinding;
|
||||||
|
import art.arcane.iris.core.nms.MinecraftVersion;
|
||||||
import art.arcane.iris.core.nms.container.BiomeColor;
|
import art.arcane.iris.core.nms.container.BiomeColor;
|
||||||
import art.arcane.iris.core.nms.container.Pair;
|
import art.arcane.iris.core.nms.container.Pair;
|
||||||
import art.arcane.iris.core.nms.container.BlockProperty;
|
import art.arcane.iris.core.nms.container.BlockProperty;
|
||||||
@@ -161,6 +162,7 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
public class NMSBinding implements INMSBinding {
|
public class NMSBinding implements INMSBinding {
|
||||||
private final KMap<Biome, Object> baseBiomeCache = new KMap<>();
|
private final KMap<Biome, Object> baseBiomeCache = new KMap<>();
|
||||||
|
private volatile DataVersion dataVersion;
|
||||||
private final BlockData AIR = Material.AIR.createBlockData();
|
private final BlockData AIR = Material.AIR.createBlockData();
|
||||||
private final AtomicCache<MCAIdMap<net.minecraft.world.level.biome.Biome>> biomeMapCache = new AtomicCache<>();
|
private final AtomicCache<MCAIdMap<net.minecraft.world.level.biome.Biome>> biomeMapCache = new AtomicCache<>();
|
||||||
private final AtomicBoolean injected = new AtomicBoolean();
|
private final AtomicBoolean injected = new AtomicBoolean();
|
||||||
@@ -1238,23 +1240,19 @@ public class NMSBinding implements INMSBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String descriptionId = "entity.minecraft." + entity.name().toLowerCase(Locale.ROOT);
|
// Registry lookup instead of an EntityType static-field scan: 26.2 moved the constants
|
||||||
Field[] fields = EntityType.class.getDeclaredFields();
|
// to a separate EntityTypes holder class that 26.1.2 does not have, while the registry
|
||||||
for (Field field : fields) {
|
// resolves identically on both. ENTITY_TYPE is a DefaultedRegistry, so guard containsKey
|
||||||
if (!Modifier.isStatic(field.getModifiers()) || !field.getType().equals(EntityType.class)) {
|
// to avoid silently resolving unknown keys to the default entry.
|
||||||
continue;
|
Identifier key = Identifier.fromNamespaceAndPath(entity.getKey().getNamespace(), entity.getKey().getKey());
|
||||||
}
|
if (!BuiltInRegistries.ENTITY_TYPE.containsKey(key)) {
|
||||||
|
|
||||||
EntityType entityType = (EntityType) field.get(null);
|
|
||||||
if (entityType == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (descriptionId.equals(entityType.getDescriptionId())) {
|
|
||||||
return new Vector3d(entityType.getWidth(), entityType.getHeight(), entityType.getWidth());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
EntityType<?> entityType = BuiltInRegistries.ENTITY_TYPE.getValue(key);
|
||||||
|
if (entityType == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return new Vector3d(entityType.getWidth(), entityType.getHeight(), entityType.getWidth());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
IrisLogging.error("Unable to get entity dimensions for " + entity + "!");
|
IrisLogging.error("Unable to get entity dimensions for " + entity + "!");
|
||||||
IrisLogging.reportError(e);
|
IrisLogging.reportError(e);
|
||||||
@@ -1362,7 +1360,13 @@ public class NMSBinding implements INMSBinding {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataVersion getDataVersion() {
|
public DataVersion getDataVersion() {
|
||||||
return DataVersion.V26_2;
|
DataVersion cached = dataVersion;
|
||||||
|
if (cached == null) {
|
||||||
|
MinecraftVersion detected = MinecraftVersion.detect(Bukkit.getServer());
|
||||||
|
cached = detected != null && detected.isSameRelease(26, 1, 2) ? DataVersion.V26_1_2 : DataVersion.V26_2;
|
||||||
|
dataVersion = cached;
|
||||||
|
}
|
||||||
|
return cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+16
-34
@@ -6,7 +6,6 @@ import art.arcane.iris.engine.object.IrisStructureTerrain;
|
|||||||
import art.arcane.iris.engine.object.IrisStructureTerrainMode;
|
import art.arcane.iris.engine.object.IrisStructureTerrainMode;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.MapCodec;
|
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
@@ -17,7 +16,6 @@ import net.minecraft.nbt.CompoundTag;
|
|||||||
import net.minecraft.server.Bootstrap;
|
import net.minecraft.server.Bootstrap;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
import net.minecraft.world.level.ChunkPos;
|
import net.minecraft.world.level.ChunkPos;
|
||||||
import net.minecraft.world.level.LevelReader;
|
|
||||||
import net.minecraft.world.level.LevelHeightAccessor;
|
import net.minecraft.world.level.LevelHeightAccessor;
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
import net.minecraft.world.level.biome.Biome;
|
import net.minecraft.world.level.biome.Biome;
|
||||||
@@ -46,8 +44,11 @@ import net.minecraft.world.level.levelgen.structure.pools.ListPoolElement;
|
|||||||
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
|
import net.minecraft.world.level.levelgen.structure.pools.SinglePoolElement;
|
||||||
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
|
import net.minecraft.world.level.levelgen.structure.pools.StructurePoolElement;
|
||||||
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
|
import net.minecraft.world.level.levelgen.structure.pools.StructureTemplatePool;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.AlwaysTrueTest;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockStateMatchTest;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.LiquidSettings;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.BlockIgnoreProcessor;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.ProcessorRule;
|
||||||
|
import net.minecraft.world.level.levelgen.structure.templatesystem.RuleProcessor;
|
||||||
import net.minecraft.world.level.levelgen.structure.structures.DesertPyramidPiece;
|
import net.minecraft.world.level.levelgen.structure.structures.DesertPyramidPiece;
|
||||||
import net.minecraft.world.level.levelgen.structure.structures.DesertPyramidStructure;
|
import net.minecraft.world.level.levelgen.structure.structures.DesertPyramidStructure;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings;
|
||||||
@@ -267,7 +268,7 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
|||||||
block(0, 0, 0, Blocks.COBBLESTONE.defaultBlockState()),
|
block(0, 0, 0, Blocks.COBBLESTONE.defaultBlockState()),
|
||||||
block(15, 0, 0, Blocks.STONE.defaultBlockState())));
|
block(15, 0, 0, Blocks.STONE.defaultBlockState())));
|
||||||
InlineSinglePoolElement element = new InlineSinglePoolElement(
|
InlineSinglePoolElement element = new InlineSinglePoolElement(
|
||||||
sparseTemplate, List.of(new ReplaceBlockProcessor(
|
sparseTemplate, List.of(replaceBlockProcessor(
|
||||||
Blocks.STONE.defaultBlockState(), Blocks.AIR.defaultBlockState())));
|
Blocks.STONE.defaultBlockState(), Blocks.AIR.defaultBlockState())));
|
||||||
PoolElementStructurePiece piece = rigidTemplatePiece(
|
PoolElementStructurePiece piece = rigidTemplatePiece(
|
||||||
element, new BoundingBox(0, 64, 0, 15, 70, 3), 1, Rotation.NONE);
|
element, new BoundingBox(0, 64, 0, 15, 70, 3), 1, Rotation.NONE);
|
||||||
@@ -369,7 +370,7 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
|||||||
block(2, 0, 0, Blocks.AIR.defaultBlockState()),
|
block(2, 0, 0, Blocks.AIR.defaultBlockState()),
|
||||||
block(2, 2, 0, Blocks.COBBLESTONE.defaultBlockState())));
|
block(2, 2, 0, Blocks.COBBLESTONE.defaultBlockState())));
|
||||||
InlineSinglePoolElement element = new InlineSinglePoolElement(
|
InlineSinglePoolElement element = new InlineSinglePoolElement(
|
||||||
template, List.of(new ReplaceBlockProcessor(
|
template, List.of(replaceBlockProcessor(
|
||||||
Blocks.STONE.defaultBlockState(), Blocks.AIR.defaultBlockState())));
|
Blocks.STONE.defaultBlockState(), Blocks.AIR.defaultBlockState())));
|
||||||
PoolElementStructurePiece piece = rigidTemplatePiece(
|
PoolElementStructurePiece piece = rigidTemplatePiece(
|
||||||
element, new BoundingBox(0, 65, 0, 2, 72, 0), 1, Rotation.NONE);
|
element, new BoundingBox(0, 65, 0, 2, 72, 0), 1, Rotation.NONE);
|
||||||
@@ -551,7 +552,7 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
|||||||
block(0, 0, 0, Blocks.STONE.defaultBlockState()),
|
block(0, 0, 0, Blocks.STONE.defaultBlockState()),
|
||||||
block(0, 2, 0, Blocks.COBBLESTONE.defaultBlockState())));
|
block(0, 2, 0, Blocks.COBBLESTONE.defaultBlockState())));
|
||||||
PoolElementStructurePiece piece = rigidTemplatePiece(
|
PoolElementStructurePiece piece = rigidTemplatePiece(
|
||||||
new InlineSinglePoolElement(template, List.of(new ReplaceBlockProcessor(
|
new InlineSinglePoolElement(template, List.of(replaceBlockProcessor(
|
||||||
Blocks.STONE.defaultBlockState(), Blocks.AIR.defaultBlockState()))),
|
Blocks.STONE.defaultBlockState(), Blocks.AIR.defaultBlockState()))),
|
||||||
new BoundingBox(0, 66, 0, 7, 72, 7), 1, Rotation.NONE);
|
new BoundingBox(0, 66, 0, 7, 72, 7), 1, Rotation.NONE);
|
||||||
StructureStart start = rigidSurfaceStart(List.of(piece), TerrainAdjustment.NONE);
|
StructureStart start = rigidSurfaceStart(List.of(piece), TerrainAdjustment.NONE);
|
||||||
@@ -1081,10 +1082,10 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
|||||||
block(1, 0, 0, Blocks.STONE.defaultBlockState())));
|
block(1, 0, 0, Blocks.STONE.defaultBlockState())));
|
||||||
InlineSinglePoolElement upperElement = new InlineSinglePoolElement(
|
InlineSinglePoolElement upperElement = new InlineSinglePoolElement(
|
||||||
upperTemplate, List.of(
|
upperTemplate, List.of(
|
||||||
new ReplaceBlockProcessor(
|
replaceBlockProcessor(
|
||||||
Blocks.COBBLESTONE.defaultBlockState(),
|
Blocks.COBBLESTONE.defaultBlockState(),
|
||||||
Blocks.AIR.defaultBlockState()),
|
Blocks.AIR.defaultBlockState()),
|
||||||
new ReplaceBlockProcessor(
|
replaceBlockProcessor(
|
||||||
Blocks.STONE.defaultBlockState(),
|
Blocks.STONE.defaultBlockState(),
|
||||||
Blocks.WATER.defaultBlockState())));
|
Blocks.WATER.defaultBlockState())));
|
||||||
PoolElementStructurePiece lower = rigidTemplatePiece(
|
PoolElementStructurePiece lower = rigidTemplatePiece(
|
||||||
@@ -2131,32 +2132,13 @@ public class NativeStructurePostProcessorSurfaceTerrainTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class ReplaceBlockProcessor implements StructureProcessor {
|
private static StructureProcessor replaceBlockProcessor(BlockState source, BlockState replacement) {
|
||||||
private final BlockState source;
|
// Vanilla RuleProcessor instead of a custom StructureProcessor subtype: StructureProcessor
|
||||||
private final BlockState replacement;
|
// is an abstract class on 26.1.2 and an interface on 26.2, so a direct subtype cannot
|
||||||
|
// compile against both dev bundles. BlockStateMatchTest matches the exact source state,
|
||||||
private ReplaceBlockProcessor(BlockState source, BlockState replacement) {
|
// matching the previous custom processor's identity-equality semantics.
|
||||||
this.source = source;
|
return new RuleProcessor(List.of(new ProcessorRule(
|
||||||
this.replacement = replacement;
|
new BlockStateMatchTest(source), AlwaysTrueTest.INSTANCE, replacement)));
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StructureTemplate.StructureBlockInfo processBlock(
|
|
||||||
LevelReader level, BlockPos targetPosition, BlockPos referencePos,
|
|
||||||
BlockPos templateRelativePos,
|
|
||||||
StructureTemplate.StructureBlockInfo processedBlockInfo,
|
|
||||||
StructurePlaceSettings settings) {
|
|
||||||
if (!processedBlockInfo.state().equals(source)) {
|
|
||||||
return processedBlockInfo;
|
|
||||||
}
|
|
||||||
return new StructureTemplate.StructureBlockInfo(
|
|
||||||
processedBlockInfo.pos(), replacement, processedBlockInfo.nbt());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MapCodec<? extends StructureProcessor> codec() {
|
|
||||||
return BlockIgnoreProcessor.STRUCTURE_BLOCK.codec();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StructureStart desertStart() {
|
private static StructureStart desertStart() {
|
||||||
|
|||||||
+46
-43
@@ -1,15 +1,16 @@
|
|||||||
package art.arcane.iris.nativegen;
|
package art.arcane.iris.nativegen;
|
||||||
|
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
import com.mojang.serialization.MapCodec;
|
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
import net.minecraft.core.HolderSet;
|
import net.minecraft.core.HolderSet;
|
||||||
import net.minecraft.core.registries.BuiltInRegistries;
|
import net.minecraft.core.registries.BuiltInRegistries;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.resources.Identifier;
|
||||||
import net.minecraft.server.Bootstrap;
|
import net.minecraft.server.Bootstrap;
|
||||||
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.util.valueproviders.ConstantInt;
|
import net.minecraft.util.valueproviders.ConstantInt;
|
||||||
import net.minecraft.world.level.LevelReader;
|
|
||||||
import net.minecraft.world.level.WorldGenLevel;
|
import net.minecraft.world.level.WorldGenLevel;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.Rotation;
|
import net.minecraft.world.level.block.Rotation;
|
||||||
@@ -34,11 +35,13 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProc
|
|||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureProcessorList;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
|
||||||
|
import org.junit.Assume;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -62,38 +65,33 @@ public class NativeStructureTemplateOccupancyTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void straddlingGravityPieceReadsHeightsOnlyInsideTheProcessingArea() throws Exception {
|
public void straddlingGravityPieceHeightReadsHonorTheVanillaClipContract() throws Exception {
|
||||||
ColumnRecorder recorder = new ColumnRecorder();
|
ColumnRecorder recorder = new ColumnRecorder();
|
||||||
|
|
||||||
resolve(straddlingPiece(
|
resolve(straddlingPiece(
|
||||||
List.of(new GravityProcessor(Heightmap.Types.WORLD_SURFACE_WG, 0))), recorder);
|
List.of(new GravityProcessor(Heightmap.Types.WORLD_SURFACE_WG, 0))), recorder);
|
||||||
|
|
||||||
assertEquals(columns(0, 15), recorder.heightColumns);
|
// 26.2 vanilla clips processor evaluation to the placement bounding box; 26.1.2 vanilla
|
||||||
}
|
// runs processors across the whole piece. Iris mirrors the pinned version's semantics.
|
||||||
|
assertEquals(expectedClippedColumns(), recorder.heightColumns);
|
||||||
@Test
|
|
||||||
public void straddlingPieceRunsProcessorsOnlyInsideTheProcessingArea() throws Exception {
|
|
||||||
CountingProcessor counter = new CountingProcessor();
|
|
||||||
|
|
||||||
resolve(straddlingPiece(List.of(counter)), new ColumnRecorder());
|
|
||||||
|
|
||||||
assertEquals(columns(0, 15), counter.columns);
|
|
||||||
assertTrue(counter.columns.size() < TEMPLATE_WIDTH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void cappedStraddlingPieceRunsProcessorsAcrossTheWholePiece() throws Exception {
|
public void cappedStraddlingPieceRunsProcessorsAcrossTheWholePiece() throws Exception {
|
||||||
CountingProcessor counter = new CountingProcessor();
|
ColumnRecorder recorder = new ColumnRecorder();
|
||||||
|
|
||||||
resolve(straddlingPiece(List.of(counter,
|
resolve(straddlingPiece(List.of(
|
||||||
new CappedProcessor(NopProcessor.INSTANCE, ConstantInt.of(0)))),
|
new GravityProcessor(Heightmap.Types.WORLD_SURFACE_WG, 0),
|
||||||
new ColumnRecorder());
|
new CappedProcessor(NopProcessor.INSTANCE, ConstantInt.of(0)))), recorder);
|
||||||
|
|
||||||
assertEquals(columns(0, TEMPLATE_WIDTH - 1), counter.columns);
|
assertEquals(columns(0, TEMPLATE_WIDTH - 1), recorder.heightColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void cappedProcessorIsTheOnlyProcessorThatDisablesTheProcessingAreaClip() {
|
public void cappedProcessorIsTheOnlyProcessorThatDisablesTheProcessingAreaClip() throws Exception {
|
||||||
|
Method contract = clipContractMethod();
|
||||||
|
Assume.assumeTrue("evaluatesEntirePieceState only exists on 26.2+", contract != null);
|
||||||
|
|
||||||
for (StructureProcessor processor : List.of(
|
for (StructureProcessor processor : List.of(
|
||||||
BlockIgnoreProcessor.STRUCTURE_BLOCK,
|
BlockIgnoreProcessor.STRUCTURE_BLOCK,
|
||||||
JigsawReplacementProcessor.INSTANCE,
|
JigsawReplacementProcessor.INSTANCE,
|
||||||
@@ -103,12 +101,12 @@ public class NativeStructureTemplateOccupancyTest {
|
|||||||
new GravityProcessor(Heightmap.Types.WORLD_SURFACE_WG, 0),
|
new GravityProcessor(Heightmap.Types.WORLD_SURFACE_WG, 0),
|
||||||
new RuleProcessor(List.of()),
|
new RuleProcessor(List.of()),
|
||||||
new BlockAgeProcessor(0.5F),
|
new BlockAgeProcessor(0.5F),
|
||||||
new ProtectedBlockProcessor(HolderSet.empty()))) {
|
protectedBlockProcessor())) {
|
||||||
assertFalse(processor.getClass().getName(),
|
assertFalse(processor.getClass().getName(),
|
||||||
processor.evaluatesEntirePieceState());
|
(Boolean) contract.invoke(processor));
|
||||||
}
|
}
|
||||||
assertTrue(new CappedProcessor(NopProcessor.INSTANCE, ConstantInt.of(4))
|
assertTrue((Boolean) contract.invoke(
|
||||||
.evaluatesEntirePieceState());
|
new CappedProcessor(NopProcessor.INSTANCE, ConstantInt.of(4))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -146,6 +144,30 @@ public class NativeStructureTemplateOccupancyTest {
|
|||||||
return columns;
|
return columns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Method clipContractMethod() {
|
||||||
|
try {
|
||||||
|
return StructureProcessor.class.getMethod("evaluatesEntirePieceState");
|
||||||
|
} catch (NoSuchMethodException absent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Set<Integer> expectedClippedColumns() {
|
||||||
|
return clipContractMethod() != null
|
||||||
|
? columns(PROCESSING_AREA.minX(), PROCESSING_AREA.maxX())
|
||||||
|
: columns(0, TEMPLATE_WIDTH - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StructureProcessor protectedBlockProcessor() throws Exception {
|
||||||
|
// Constructed reflectively: the constructor takes HolderSet on 26.2 and TagKey on 26.1.2.
|
||||||
|
Constructor<?> constructor = ProtectedBlockProcessor.class.getConstructors()[0];
|
||||||
|
Class<?> parameter = constructor.getParameterTypes()[0];
|
||||||
|
Object argument = parameter == HolderSet.class
|
||||||
|
? HolderSet.empty()
|
||||||
|
: TagKey.create(Registries.BLOCK, Identifier.fromNamespaceAndPath("minecraft", "air"));
|
||||||
|
return (StructureProcessor) constructor.newInstance(argument);
|
||||||
|
}
|
||||||
|
|
||||||
private static StructureTemplateManager forbiddenTemplateManager() {
|
private static StructureTemplateManager forbiddenTemplateManager() {
|
||||||
throw new AssertionError("Inline templates must not resolve a template manager");
|
throw new AssertionError("Inline templates must not resolve a template manager");
|
||||||
}
|
}
|
||||||
@@ -202,25 +224,6 @@ public class NativeStructureTemplateOccupancyTest {
|
|||||||
private final Set<Integer> stateColumns = new TreeSet<>();
|
private final Set<Integer> stateColumns = new TreeSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class CountingProcessor implements StructureProcessor {
|
|
||||||
private final Set<Integer> columns = new TreeSet<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public StructureTemplate.StructureBlockInfo processBlock(
|
|
||||||
LevelReader level, BlockPos targetPosition, BlockPos referencePos,
|
|
||||||
BlockPos templateRelativePos,
|
|
||||||
StructureTemplate.StructureBlockInfo processedBlockInfo,
|
|
||||||
StructurePlaceSettings settings) {
|
|
||||||
columns.add(processedBlockInfo.pos().getX());
|
|
||||||
return processedBlockInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public MapCodec<? extends StructureProcessor> codec() {
|
|
||||||
return BlockIgnoreProcessor.STRUCTURE_BLOCK.codec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class InlineSinglePoolElement extends SinglePoolElement {
|
private static final class InlineSinglePoolElement extends SinglePoolElement {
|
||||||
private InlineSinglePoolElement(
|
private InlineSinglePoolElement(
|
||||||
StructureTemplate template, List<StructureProcessor> processors) {
|
StructureTemplate template, List<StructureProcessor> processors) {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
String apiVersion = providers.gradleProperty('minecraftVersion').get()
|
String apiVersion = providers.gradleProperty('apiVersion').get()
|
||||||
def mainClass = 'art.arcane.iris.Iris'
|
def mainClass = 'art.arcane.iris.Iris'
|
||||||
def bootstrapperClass = 'art.arcane.iris.IrisBootstrap'
|
def bootstrapperClass = 'art.arcane.iris.IrisBootstrap'
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -87,7 +87,7 @@ String forgeConsumerPath = "${consumerLocation}/forge-mod-consumers/dropins/mods
|
|||||||
String neoForgeConsumerPath = "${consumerLocation}/neoforge-mod-consumers/dropins/mods"
|
String neoForgeConsumerPath = "${consumerLocation}/neoforge-mod-consumers/dropins/mods"
|
||||||
|
|
||||||
def nmsBindings = [
|
def nmsBindings = [
|
||||||
v26_2_R1: '26.2.build.60-beta',
|
v26_2_R1: '26.1.2.build.74-stable',
|
||||||
]
|
]
|
||||||
Class nmsTypeClass = Class.forName('NMSBinding$Type')
|
Class nmsTypeClass = Class.forName('NMSBinding$Type')
|
||||||
nmsBindings.each { key, value ->
|
nmsBindings.each { key, value ->
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ public final class IrisDatapackCompiler {
|
|||||||
List<File> packRoots,
|
List<File> packRoots,
|
||||||
KList<File> datapackRoots,
|
KList<File> datapackRoots,
|
||||||
IDataFixer fixer,
|
IDataFixer fixer,
|
||||||
int packFormat,
|
|
||||||
boolean adjustVanillaHeight
|
boolean adjustVanillaHeight
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
Objects.requireNonNull(packRoots, "packRoots");
|
Objects.requireNonNull(packRoots, "packRoots");
|
||||||
@@ -98,7 +97,7 @@ public final class IrisDatapackCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IrisDimension.writeShared(datapackRoots, height, packFormat, adjustVanillaHeight);
|
IrisDimension.writeShared(datapackRoots, height, adjustVanillaHeight);
|
||||||
validateOutputs(datapackRoots, dimensionCount);
|
validateOutputs(datapackRoots, dimensionCount);
|
||||||
return new CompilationResult(packCount, dimensionCount, countBiomes(biomes));
|
return new CompilationResult(packCount, dimensionCount, countBiomes(biomes));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,7 +200,6 @@ public class ServerConfigurator {
|
|||||||
packRoots,
|
packRoots,
|
||||||
stagedRoots,
|
stagedRoots,
|
||||||
fixer,
|
fixer,
|
||||||
BukkitPlatform.dataPackFormat(),
|
|
||||||
IrisSettings.get().getGeneral().adjustVanillaHeight
|
IrisSettings.get().getGeneral().adjustVanillaHeight
|
||||||
);
|
);
|
||||||
for (int i = 0; i < liveRoots.size(); i++) {
|
for (int i = 0; i < liveRoots.size(); i++) {
|
||||||
|
|||||||
@@ -257,7 +257,7 @@ public interface INMSBinding {
|
|||||||
if (!supportsIrisWorldGeneration()) {
|
if (!supportsIrisWorldGeneration()) {
|
||||||
throw new IllegalStateException("Iris world '" + c.name() + "' cannot be created with limited NMS binding "
|
throw new IllegalStateException("Iris world '" + c.name() + "' cannot be created with limited NMS binding "
|
||||||
+ getClass().getSimpleName()
|
+ getClass().getSimpleName()
|
||||||
+ "; set general.disableNMS=false and use the supported Minecraft 26.2 server runtime");
|
+ "; set general.disableNMS=false and use a supported Minecraft server runtime (26.1.2 or 26.2)");
|
||||||
}
|
}
|
||||||
if (missingDimensionTypes(generator.getTarget().getDimension().getDimensionTypeKey())) {
|
if (missingDimensionTypes(generator.getTarget().getDimension().getDimensionTypeKey())) {
|
||||||
throw new IllegalStateException("Missing dimension types to create world");
|
throw new IllegalStateException("Missing dimension types to create world");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package art.arcane.iris.core.nms;
|
package art.arcane.iris.core.nms;
|
||||||
|
|
||||||
final class NmsBindingSelector {
|
final class NmsBindingSelector {
|
||||||
private static final String SUPPORTED_VERSION = "26.2";
|
private static final String SUPPORTED_VERSIONS = "26.1.2 or 26.2";
|
||||||
private static final String SUPPORTED_TAG = "v26_2_R1";
|
private static final String SUPPORTED_TAG = "v26_2_R1";
|
||||||
|
|
||||||
private NmsBindingSelector() {
|
private NmsBindingSelector() {
|
||||||
@@ -11,8 +11,8 @@ final class NmsBindingSelector {
|
|||||||
if (version == null) {
|
if (version == null) {
|
||||||
throw new IllegalStateException("Iris requires an exact Minecraft version before selecting NMS");
|
throw new IllegalStateException("Iris requires an exact Minecraft version before selecting NMS");
|
||||||
}
|
}
|
||||||
if (!version.isSameRelease(26, 2, 0)) {
|
if (!version.isSameRelease(26, 2, 0) && !version.isSameRelease(26, 1, 2)) {
|
||||||
throw new IllegalStateException("Iris requires Minecraft " + SUPPORTED_VERSION
|
throw new IllegalStateException("Iris requires Minecraft " + SUPPORTED_VERSIONS
|
||||||
+ ". Detected server version: " + version.value());
|
+ ". Detected server version: " + version.value());
|
||||||
}
|
}
|
||||||
return SUPPORTED_TAG;
|
return SUPPORTED_TAG;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import java.util.function.Supplier;
|
|||||||
@Getter
|
@Getter
|
||||||
public enum DataVersion {
|
public enum DataVersion {
|
||||||
UNSUPPORTED("0.0.0", 0, () -> null),
|
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);
|
||||||
private static final KMap<DataVersion, IDataFixer> cache = new KMap<>();
|
private static final KMap<DataVersion, IDataFixer> cache = new KMap<>();
|
||||||
@Getter(AccessLevel.NONE)
|
@Getter(AccessLevel.NONE)
|
||||||
@@ -51,4 +52,15 @@ public enum DataVersion {
|
|||||||
public static DataVersion getLatest() {
|
public static DataVersion getLatest() {
|
||||||
return values()[values().length - 1];
|
return values()[values().length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int minSupportedPackFormat() {
|
||||||
|
int minimum = Integer.MAX_VALUE;
|
||||||
|
for (DataVersion version : values()) {
|
||||||
|
if (version == UNSUPPORTED) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
minimum = Math.min(minimum, version.packFormat);
|
||||||
|
}
|
||||||
|
return minimum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -293,6 +293,6 @@ public class NMSBinding1X implements INMSBinding {
|
|||||||
private IllegalStateException unsupportedStructureHook(String operation) {
|
private IllegalStateException unsupportedStructureHook(String operation) {
|
||||||
return new IllegalStateException("Iris cannot " + operation + " with limited NMS binding "
|
return new IllegalStateException("Iris cannot " + operation + " with limited NMS binding "
|
||||||
+ getClass().getSimpleName()
|
+ getClass().getSimpleName()
|
||||||
+ "; set general.disableNMS=false and use the supported Minecraft 26.2 server runtime");
|
+ "; set general.disableNMS=false and use a supported Minecraft server runtime (26.1.2 or 26.2)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import java.util.zip.ZipInputStream;
|
|||||||
public final class DefaultPackBootstrapProvisioner {
|
public final class DefaultPackBootstrapProvisioner {
|
||||||
private static final URI DEFAULT_SOURCE = URI.create("https://github.com/IrisDimensions/overworld/releases/download/beta/overworld.zip");
|
private static final URI DEFAULT_SOURCE = URI.create("https://github.com/IrisDimensions/overworld/releases/download/beta/overworld.zip");
|
||||||
private static final String WORLD_DATAPACK_DIRECTORY = "iris";
|
private static final String WORLD_DATAPACK_DIRECTORY = "iris";
|
||||||
private static final int PACK_FORMAT = 107;
|
|
||||||
private static final int MARKER_SCHEMA = 2;
|
private static final int MARKER_SCHEMA = 2;
|
||||||
private static final int MAX_ARCHIVE_ENTRIES = 100_000;
|
private static final int MAX_ARCHIVE_ENTRIES = 100_000;
|
||||||
private static final long MAX_ARCHIVE_BYTES = 512L * 1024L * 1024L;
|
private static final long MAX_ARCHIVE_BYTES = 512L * 1024L * 1024L;
|
||||||
@@ -189,7 +188,7 @@ public final class DefaultPackBootstrapProvisioner {
|
|||||||
if (fixer == null) {
|
if (fixer == null) {
|
||||||
throw new IOException("Latest Iris datapack fixer is unavailable during bootstrap");
|
throw new IOException("Latest Iris datapack fixer is unavailable during bootstrap");
|
||||||
}
|
}
|
||||||
IrisDatapackCompiler.compile(packRoots, outputFolders, fixer, PACK_FORMAT, false);
|
IrisDatapackCompiler.compile(packRoots, outputFolders, fixer, false);
|
||||||
if (!isDatapackRoot(compileContainer)) {
|
if (!isDatapackRoot(compileContainer)) {
|
||||||
throw new IOException("Canonical Iris datapack compiler produced incomplete output at " + compileContainer);
|
throw new IOException("Canonical Iris datapack compiler produced incomplete output at " + compileContainer);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import art.arcane.iris.core.loader.IrisData;
|
|||||||
import art.arcane.iris.spi.IrisLogging;
|
import art.arcane.iris.spi.IrisLogging;
|
||||||
import art.arcane.iris.spi.PlatformBlockState;
|
import art.arcane.iris.spi.PlatformBlockState;
|
||||||
import art.arcane.iris.core.loader.IrisRegistrant;
|
import art.arcane.iris.core.loader.IrisRegistrant;
|
||||||
|
import art.arcane.iris.core.nms.datapack.DataVersion;
|
||||||
import art.arcane.iris.core.nms.datapack.IDataFixer;
|
import art.arcane.iris.core.nms.datapack.IDataFixer;
|
||||||
import art.arcane.iris.core.nms.datapack.IDataFixer.Dimension;
|
import art.arcane.iris.core.nms.datapack.IDataFixer.Dimension;
|
||||||
import art.arcane.iris.engine.data.cache.AtomicCache;
|
import art.arcane.iris.engine.data.cache.AtomicCache;
|
||||||
@@ -763,7 +764,6 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
public static void writeShared(
|
public static void writeShared(
|
||||||
KList<File> datapackRoots,
|
KList<File> datapackRoots,
|
||||||
DimensionHeight height,
|
DimensionHeight height,
|
||||||
int packFormat,
|
|
||||||
boolean adjustVanillaHeight
|
boolean adjustVanillaHeight
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
IrisLogging.debug(" Installing Data Pack Vanilla Dimension Types");
|
IrisLogging.debug(" Installing Data Pack Vanilla Dimension Types");
|
||||||
@@ -774,16 +774,22 @@ public class IrisDimension extends IrisRegistrant {
|
|||||||
write(datapackRoot, "the_end", jsonStrings[2], adjustVanillaHeight);
|
write(datapackRoot, "the_end", jsonStrings[2], adjustVanillaHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ranged formats spanning every supported runtime (26.1.2 = 101, 26.2 = 107). The bootstrap
|
||||||
|
// provisioner stages this datapack before the server (and INMS) exists, so the runtime
|
||||||
|
// version cannot be resolved there; a range keeps the emitted bytes identical on both
|
||||||
|
// install paths and both Paper versions parse ranged min_format/max_format.
|
||||||
|
int minFormat = DataVersion.minSupportedPackFormat();
|
||||||
|
int maxFormat = DataVersion.getLatest().getPackFormat();
|
||||||
String raw = """
|
String raw = """
|
||||||
{
|
{
|
||||||
"pack": {
|
"pack": {
|
||||||
"description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.",
|
"description": "Iris Data Pack. This pack contains all installed Iris Packs' resources.",
|
||||||
"pack_format": {},
|
"pack_format": %d,
|
||||||
"min_format": {},
|
"min_format": %d,
|
||||||
"max_format": {}
|
"max_format": %d
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""".replace("{}", Integer.toString(packFormat));
|
""".formatted(maxFormat, minFormat, maxFormat);
|
||||||
|
|
||||||
for (File datapackRoot : datapackRoots) {
|
for (File datapackRoot : datapackRoots) {
|
||||||
File mcm = new File(datapackRoot, "pack.mcmeta");
|
File mcm = new File(datapackRoot, "pack.mcmeta");
|
||||||
|
|||||||
@@ -242,10 +242,6 @@ public final class BukkitPlatform implements IrisPlatform {
|
|||||||
return INMS.get().applyCustomNbt(itemStack, customNbt);
|
return INMS.get().applyCustomNbt(itemStack, customNbt);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int dataPackFormat() {
|
|
||||||
return INMS.get().getDataVersion().getPackFormat();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static java.util.concurrent.CompletableFuture<Boolean> teleportAsync(Entity entity, Location destination) {
|
public static java.util.concurrent.CompletableFuture<Boolean> teleportAsync(Entity entity, Location destination) {
|
||||||
return io.papermc.lib.PaperLib.teleportAsync(entity, destination);
|
return io.papermc.lib.PaperLib.teleportAsync(entity, destination);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ public interface DirectorExecutor extends DirectorExecutorBase {
|
|||||||
return sender == null ? null : sender.player();
|
return sender == null ? null : sender.player();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default boolean playerWorldGeneratesStructures() {
|
||||||
|
Player activePlayer = player();
|
||||||
|
return activePlayer != null && activePlayer.getWorld().canGenerateStructures();
|
||||||
|
}
|
||||||
|
|
||||||
default IrisData data() {
|
default IrisData data() {
|
||||||
var access = access();
|
var access = access();
|
||||||
if (access != null) {
|
if (access != null) {
|
||||||
|
|||||||
+1
-3
@@ -29,7 +29,6 @@ import art.arcane.iris.spi.PlatformStructureHooks;
|
|||||||
import art.arcane.iris.util.common.director.DirectorParameterHandler;
|
import art.arcane.iris.util.common.director.DirectorParameterHandler;
|
||||||
import art.arcane.volmlib.util.collection.KList;
|
import art.arcane.volmlib.util.collection.KList;
|
||||||
import art.arcane.volmlib.util.director.exceptions.DirectorParsingException;
|
import art.arcane.volmlib.util.director.exceptions.DirectorParsingException;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -100,8 +99,7 @@ public class StructureHandler implements DirectorParameterHandler<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean nativeStructureGenerationEnabled() {
|
protected boolean nativeStructureGenerationEnabled() {
|
||||||
Player activePlayer = player();
|
return playerWorldGeneratesStructures();
|
||||||
return activePlayer != null && activePlayer.getWorld().canGenerateStructures();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, String> distinctKeys(List<String> keys) {
|
private static Map<String, String> distinctKeys(List<String> keys) {
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package art.arcane.iris.core;
|
package art.arcane.iris.core;
|
||||||
|
|
||||||
|
import art.arcane.iris.core.nms.datapack.DataVersion;
|
||||||
import art.arcane.iris.core.nms.datapack.v1217.DataFixerV1217;
|
import art.arcane.iris.core.nms.datapack.v1217.DataFixerV1217;
|
||||||
import art.arcane.volmlib.util.collection.KList;
|
import art.arcane.volmlib.util.collection.KList;
|
||||||
|
import art.arcane.volmlib.util.json.JSONObject;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
@@ -41,7 +43,6 @@ public class IrisDatapackCompilerTest {
|
|||||||
packRoots,
|
packRoots,
|
||||||
new KList<File>().qadd(datapackRoot.toFile()),
|
new KList<File>().qadd(datapackRoot.toFile()),
|
||||||
new DataFixerV1217(),
|
new DataFixerV1217(),
|
||||||
107,
|
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -72,7 +73,6 @@ public class IrisDatapackCompilerTest {
|
|||||||
List.of(packRoot.toFile()),
|
List.of(packRoot.toFile()),
|
||||||
new KList<File>().qadd(datapackRoot.toFile()),
|
new KList<File>().qadd(datapackRoot.toFile()),
|
||||||
new DataFixerV1217(),
|
new DataFixerV1217(),
|
||||||
107,
|
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -99,6 +99,33 @@ public class IrisDatapackCompilerTest {
|
|||||||
IrisDatapackCompiler.collectPackRoots(dataDirectory, serverRoot));
|
IrisDatapackCompiler.collectPackRoots(dataDirectory, serverRoot));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void packMcmetaSpansEverySupportedRuntimeFormat() throws Exception {
|
||||||
|
Path datapackRoot = temporaryFolder.newFolder("mcmeta-datapack").toPath();
|
||||||
|
|
||||||
|
IrisDatapackCompiler.compile(
|
||||||
|
List.of(),
|
||||||
|
new KList<File>().qadd(datapackRoot.toFile()),
|
||||||
|
new DataFixerV1217(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
JSONObject pack = new JSONObject(Files.readString(datapackRoot.resolve("pack.mcmeta"), StandardCharsets.UTF_8))
|
||||||
|
.getJSONObject("pack");
|
||||||
|
int minFormat = pack.getInt("min_format");
|
||||||
|
int maxFormat = pack.getInt("max_format");
|
||||||
|
|
||||||
|
assertEquals(101, minFormat);
|
||||||
|
assertEquals(107, maxFormat);
|
||||||
|
assertEquals(maxFormat, pack.getInt("pack_format"));
|
||||||
|
|
||||||
|
// One artifact serves both runtimes: each supported DataVersion's format must be in range.
|
||||||
|
assertTrue(minFormat <= DataVersion.V26_1_2.getPackFormat()
|
||||||
|
&& DataVersion.V26_1_2.getPackFormat() <= maxFormat);
|
||||||
|
assertTrue(minFormat <= DataVersion.V26_2.getPackFormat()
|
||||||
|
&& DataVersion.V26_2.getPackFormat() <= maxFormat);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void compilingNoPacksPublishesCleanEmptyDatapack() throws Exception {
|
public void compilingNoPacksPublishesCleanEmptyDatapack() throws Exception {
|
||||||
Path datapackRoot = temporaryFolder.newFolder("empty-datapack").toPath();
|
Path datapackRoot = temporaryFolder.newFolder("empty-datapack").toPath();
|
||||||
@@ -110,7 +137,6 @@ public class IrisDatapackCompilerTest {
|
|||||||
List.of(),
|
List.of(),
|
||||||
new KList<File>().qadd(datapackRoot.toFile()),
|
new KList<File>().qadd(datapackRoot.toFile()),
|
||||||
new DataFixerV1217(),
|
new DataFixerV1217(),
|
||||||
107,
|
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,30 @@ public class MinecraftVersionTest {
|
|||||||
assertEquals(0, version.patch());
|
assertEquals(0, version.patch());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parsesThreePartNewSchemeVersion() {
|
||||||
|
MinecraftVersion version = MinecraftVersion.fromBukkitVersion("26.1.2-R0.1-SNAPSHOT");
|
||||||
|
assertEquals("26.1.2", version.value());
|
||||||
|
assertEquals(26, version.major());
|
||||||
|
assertEquals(1, version.minor());
|
||||||
|
assertEquals(2, version.patch());
|
||||||
|
assertTrue(version.isSameRelease(26, 1, 2));
|
||||||
|
assertFalse(version.isSameRelease(26, 2, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void detectsThreePartVersionFromDecoratedVersion() {
|
||||||
|
Server server = mock(Server.class);
|
||||||
|
doReturn("git-Paper-74 (MC: 26.1.2)").when(server).getVersion();
|
||||||
|
doReturn("26.1.2-R0.1-SNAPSHOT").when(server).getBukkitVersion();
|
||||||
|
|
||||||
|
MinecraftVersion version = MinecraftVersion.detect(server);
|
||||||
|
assertEquals("26.1.2", version.value());
|
||||||
|
assertEquals(26, version.major());
|
||||||
|
assertEquals(1, version.minor());
|
||||||
|
assertEquals(2, version.patch());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void comparesMajorBeforeMinor() {
|
public void comparesMajorBeforeMinor() {
|
||||||
MinecraftVersion version = MinecraftVersion.fromBukkitVersion("26.2-R0.1-SNAPSHOT");
|
MinecraftVersion version = MinecraftVersion.fromBukkitVersion("26.2-R0.1-SNAPSHOT");
|
||||||
|
|||||||
@@ -14,6 +14,13 @@ public class NmsBindingSelectorTest {
|
|||||||
assertEquals("v26_2_R1", NmsBindingSelector.select(version));
|
assertEquals("v26_2_R1", NmsBindingSelector.select(version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void selectsSharedRevisionFor2612() {
|
||||||
|
MinecraftVersion version = MinecraftVersion.fromBukkitVersion("26.1.2-R0.1-SNAPSHOT");
|
||||||
|
|
||||||
|
assertEquals("v26_2_R1", NmsBindingSelector.select(version));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rejectsUnsupportedVersionsWithoutProbingAnotherRevision() {
|
public void rejectsUnsupportedVersionsWithoutProbingAnotherRevision() {
|
||||||
MinecraftVersion version = MinecraftVersion.fromBukkitVersion("26.3-R0.1-SNAPSHOT");
|
MinecraftVersion version = MinecraftVersion.fromBukkitVersion("26.3-R0.1-SNAPSHOT");
|
||||||
@@ -24,6 +31,16 @@ public class NmsBindingSelectorTest {
|
|||||||
assertTrue(failure.getMessage().contains("26.3"));
|
assertTrue(failure.getMessage().contains("26.3"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void rejectsBasePatchOfSupportedMinorLine() {
|
||||||
|
MinecraftVersion version = MinecraftVersion.fromBukkitVersion("26.1-R0.1-SNAPSHOT");
|
||||||
|
|
||||||
|
IllegalStateException failure = assertThrows(IllegalStateException.class,
|
||||||
|
() -> NmsBindingSelector.select(version));
|
||||||
|
|
||||||
|
assertTrue(failure.getMessage().contains("26.1"));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void rejectsMissingVersionDetection() {
|
public void rejectsMissingVersionDetection() {
|
||||||
assertThrows(IllegalStateException.class, () -> NmsBindingSelector.select(null));
|
assertThrows(IllegalStateException.class, () -> NmsBindingSelector.select(null));
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package art.arcane.iris.core.nms.datapack;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
|
||||||
|
public class DataVersionTest {
|
||||||
|
@Test
|
||||||
|
public void latestRemainsNewestSupportedRelease() {
|
||||||
|
assertSame(DataVersion.V26_2, DataVersion.getLatest());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void packFormatsMatchServerVersionJson() {
|
||||||
|
assertEquals(101, DataVersion.V26_1_2.getPackFormat());
|
||||||
|
assertEquals(107, DataVersion.V26_2.getPackFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void minSupportedPackFormatIsTheOldestSupportedRuntime() {
|
||||||
|
assertEquals(101, DataVersion.minSupportedPackFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bothSupportedReleasesShareAFixer() {
|
||||||
|
assertNotNull(DataVersion.V26_1_2.get());
|
||||||
|
assertNotNull(DataVersion.V26_2.get());
|
||||||
|
assertSame(DataVersion.V26_1_2.get().getClass(), DataVersion.V26_2.get().getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,9 +8,13 @@ to a new Minecraft version, in order.
|
|||||||
|
|
||||||
`gradle.properties`:
|
`gradle.properties`:
|
||||||
|
|
||||||
- `minecraftVersion` — target MC version (e.g. `26.2`). Drives the Bukkit plugin `api-version`,
|
- `minecraftVersion` — target MC version (e.g. `26.2`). Drives
|
||||||
`BuildConstants.MINECRAFT_VERSION`, the `com.mojang:minecraft` coordinate, all mod-metadata
|
`BuildConstants.MINECRAFT_VERSION`, the `com.mojang:minecraft` coordinate, all mod-metadata
|
||||||
minecraft ranges, and every dist/jar artifact name.
|
minecraft ranges, and every dist/jar artifact name.
|
||||||
|
- `apiVersion` — Bukkit plugin `api-version` (e.g. `26.1`). Deliberately decoupled from
|
||||||
|
`minecraftVersion`: it is the lowest Minecraft release line the single plugin artifact loads on
|
||||||
|
(currently `26.1` so one jar serves 26.1.2 and 26.2). Bump it only when dropping support for the
|
||||||
|
older line.
|
||||||
- `fabricLoaderVersion` — Fabric Loader version.
|
- `fabricLoaderVersion` — Fabric Loader version.
|
||||||
- `forgeVersion` — Forge version (`<mc>-<forge>`).
|
- `forgeVersion` — Forge version (`<mc>-<forge>`).
|
||||||
- `neoForgeVersion` — NeoForge version.
|
- `neoForgeVersion` — NeoForge version.
|
||||||
@@ -19,7 +23,8 @@ to a new Minecraft version, in order.
|
|||||||
## Ordered steps
|
## Ordered steps
|
||||||
|
|
||||||
1. Edit `gradle.properties`: update `minecraftVersion`, `fabricLoaderVersion`, `forgeVersion`,
|
1. Edit `gradle.properties`: update `minecraftVersion`, `fabricLoaderVersion`, `forgeVersion`,
|
||||||
`neoForgeVersion`, and the `irisVersion` suffix.
|
`neoForgeVersion`, and the `irisVersion` suffix. Revisit `apiVersion` only if the bump drops
|
||||||
|
support for the oldest Minecraft line the plugin artifact still loads on.
|
||||||
|
|
||||||
2. Edit `gradle/libs.versions.toml`:
|
2. Edit `gradle/libs.versions.toml`:
|
||||||
- `spigot` — the Spigot/Paper API pin used to compile against (`<mc>-R0.1-SNAPSHOT`).
|
- `spigot` — the Spigot/Paper API pin used to compile against (`<mc>-R0.1-SNAPSHOT`).
|
||||||
@@ -148,7 +153,7 @@ to a new Minecraft version, in order.
|
|||||||
|
|
||||||
## Derived automatically (do not hand-edit on a version bump)
|
## Derived automatically (do not hand-edit on a version bump)
|
||||||
|
|
||||||
- Bukkit plugin `api-version` — `adapters/bukkit/plugin/build.gradle` reads `minecraftVersion`.
|
- Bukkit plugin `api-version` — `adapters/bukkit/plugin/build.gradle` reads `apiVersion`.
|
||||||
- `BuildConstants.MINECRAFT_VERSION` — stamped by the `generateTemplates` task in
|
- `BuildConstants.MINECRAFT_VERSION` — stamped by the `generateTemplates` task in
|
||||||
`core/build.gradle` from `minecraftVersion`; consumed by `Tasks.supportedVersions`.
|
`core/build.gradle` from `minecraftVersion`; consumed by `Tasks.supportedVersions`.
|
||||||
- Mod-metadata `minecraft` version ranges — templated from `minecraftVersion` at `processResources`.
|
- Mod-metadata `minecraft` version ranges — templated from `minecraftVersion` at `processResources`.
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ nmsTools.repo-url=https://repo.codemc.org/repository/nms/
|
|||||||
nmsTools.specialSourceVersion=1.11.4
|
nmsTools.specialSourceVersion=1.11.4
|
||||||
irisVersion=4.0.0-26.2
|
irisVersion=4.0.0-26.2
|
||||||
minecraftVersion=26.2
|
minecraftVersion=26.2
|
||||||
|
# Bukkit plugin api-version: lowest supported Minecraft release line so one artifact loads on 26.1.2 and 26.2
|
||||||
|
apiVersion=26.1
|
||||||
fabricLoaderVersion=0.19.3
|
fabricLoaderVersion=0.19.3
|
||||||
forgeVersion=26.2-65.0.4
|
forgeVersion=26.2-65.0.4
|
||||||
neoForgeVersion=26.2.0.12-beta
|
neoForgeVersion=26.2.0.12-beta
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ sentryPlugin = "6.14.0" # https://github.com/getsentry/sentry-android-gradle-plu
|
|||||||
# Core Libraries
|
# Core Libraries
|
||||||
lombok = "1.18.46"
|
lombok = "1.18.46"
|
||||||
spigot = "26.2-R0.1-SNAPSHOT" # https://hub.spigotmc.org/nexus/repository/snapshots/org/spigotmc/spigot-api/maven-metadata.xml
|
spigot = "26.2-R0.1-SNAPSHOT" # https://hub.spigotmc.org/nexus/repository/snapshots/org/spigotmc/spigot-api/maven-metadata.xml
|
||||||
paper-api = "26.2.build.60-beta"
|
paper-api = "26.1.2.build.74-stable"
|
||||||
log4j = "2.26.1" # https://central.sonatype.com/artifact/org.apache.logging.log4j/log4j-api
|
log4j = "2.26.1" # https://central.sonatype.com/artifact/org.apache.logging.log4j/log4j-api
|
||||||
adventure-api = "4.26.1" # https://github.com/KyoriPowered/adventure
|
adventure-api = "4.26.1" # https://github.com/KyoriPowered/adventure
|
||||||
adventure-platform = "4.4.1" # https://github.com/KyoriPowered/adventure-platform
|
adventure-platform = "4.4.1" # https://github.com/KyoriPowered/adventure-platform
|
||||||
|
|||||||
Reference in New Issue
Block a user