mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-20 15:26:51 +00:00
Derived retained borrowed pack names
- Retained borrowed-type packs take their pack name from the scoped biome aliases recorded in their generation history instead of the dimension key - Scoped legacy biome aliases of retained borrowed packs now match the definitions their worlds reference - A retained pack whose recorded aliases name several packs is refused instead of staged with a guessed name
This commit is contained in:
1 parent
4244aa4ea7
commit
a0c9d48601
3 files changed
+155
-1
No files matched your search
+11
-1
@@ -830,7 +830,7 @@ public final class ModdedForcedDatapack {
|
||||
GenerationEpoch.DimensionContract contract = retained.epoch().dimensionContract();
|
||||
Optional<ModdedWorldgenIds.ScopedDimension> scoped = ModdedWorldgenIds.scopedDimensionType(contract.dimensionTypeKey());
|
||||
if (scoped.isEmpty()) {
|
||||
return PackStageContext.retained(normalizedRoot, contract.dimensionKey(), retained.epoch());
|
||||
return PackStageContext.retained(normalizedRoot, retainedPackName(retained.epoch(), normalizedRoot), retained.epoch());
|
||||
}
|
||||
ModdedWorldgenIds.ScopedDimension identity = scoped.get();
|
||||
if (!identity.dimension().equals(contract.dimensionKey())) {
|
||||
@@ -849,6 +849,16 @@ public final class ModdedForcedDatapack {
|
||||
return PackStageContext.installed(normalizedRoot, packName, legacyDimensions);
|
||||
}
|
||||
|
||||
static String retainedPackName(GenerationEpoch epoch, Path packRoot) throws IOException {
|
||||
String dimensionKey = epoch.dimensionContract().dimensionKey();
|
||||
Set<String> packs = ModdedWorldgenIds.aliasPacks(epoch.registryContract(), dimensionKey);
|
||||
if (packs.size() > 1) {
|
||||
throw new IOException("Retained Iris generation pack at " + packRoot
|
||||
+ " records scoped biome aliases from several packs " + packs + ".");
|
||||
}
|
||||
return packs.isEmpty() ? dimensionKey : packs.iterator().next();
|
||||
}
|
||||
|
||||
private static RetainedPack retainedPack(Path packRoot) throws IOException {
|
||||
Path epochRoot = packRoot.getParent();
|
||||
Path epochsRoot = epochRoot == null ? null : epochRoot.getParent();
|
||||
|
||||
@@ -2,12 +2,17 @@ package art.arcane.iris.modded;
|
||||
|
||||
import art.arcane.iris.generation.runtime.Engine;
|
||||
import art.arcane.iris.generation.terrain.IrisDimension;
|
||||
import art.arcane.iris.world.history.GenerationRegistryContract;
|
||||
import art.arcane.iris.world.history.GenerationRegistryContract.PhysicalResourceKey;
|
||||
import art.arcane.iris.world.history.GenerationRegistryContractFactory;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public final class ModdedWorldgenIds {
|
||||
private static final String NAMESPACE = "irisworldgen";
|
||||
@@ -68,6 +73,41 @@ public final class ModdedWorldgenIds {
|
||||
return Optional.of(new ScopedDimension(pack, dimension));
|
||||
}
|
||||
|
||||
static Set<String> aliasPacks(GenerationRegistryContract contract, String dimension) {
|
||||
Set<String> packs = new TreeSet<>();
|
||||
for (PhysicalResourceKey key : contract.definitions().keySet()) {
|
||||
if (!GenerationRegistryContractFactory.BIOME_REGISTRY.equals(key.registryKey())) {
|
||||
continue;
|
||||
}
|
||||
Optional<ScopedDimension> scoped = scopedBiome(key.resourceKey());
|
||||
if (scoped.isPresent() && scoped.get().dimension().equals(dimension)) {
|
||||
packs.add(scoped.get().pack());
|
||||
}
|
||||
}
|
||||
return packs;
|
||||
}
|
||||
|
||||
static Optional<ScopedDimension> scopedBiome(String biomeRef) {
|
||||
String prefix = NAMESPACE + ":";
|
||||
if (biomeRef == null || !biomeRef.startsWith(prefix)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
String[] parts = biomeRef.substring(prefix.length()).split("/", 6);
|
||||
if (parts.length != 6
|
||||
|| !"packs".equals(parts[0])
|
||||
|| !"dimensions".equals(parts[2])
|
||||
|| !"biomes".equals(parts[4])
|
||||
|| parts[5].isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
String pack = decode(parts[1]);
|
||||
String dimension = decode(parts[3]);
|
||||
if (pack == null || dimension == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(new ScopedDimension(pack, dimension));
|
||||
}
|
||||
|
||||
public static String displayName(String presetPath) {
|
||||
String[] parts = presetPath.split("/");
|
||||
if (parts.length != 5 || !"packs".equals(parts[0])
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Servers
|
||||
* Copyright (c) 2026 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package art.arcane.iris.modded;
|
||||
|
||||
import art.arcane.iris.world.history.GenerationEpoch;
|
||||
import art.arcane.iris.world.history.GenerationEpochContractFactory;
|
||||
import art.arcane.iris.world.history.GenerationRegistryContract;
|
||||
import art.arcane.iris.world.history.GenerationRegistryContract.PhysicalResourceKey;
|
||||
import art.arcane.iris.world.history.GenerationRegistryContractFactory;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
public class ModdedRetainedPackNameTest {
|
||||
private static final String FINGERPRINT = "11".repeat(32);
|
||||
private static final Path PACK_ROOT = Path.of("/srv/world/dimensions/aether/the_aether/iris/generation/epochs/e/pack");
|
||||
|
||||
@Test
|
||||
public void borrowedRetainedPackTakesItsNameFromTheRecordedScopedBiomeAliases() throws IOException {
|
||||
GenerationEpoch epoch = epoch("aether:the_aether", "sky", List.of(
|
||||
ModdedWorldgenIds.biomeRef("skypack", "sky", "meadow"),
|
||||
"sky:meadow",
|
||||
"iris:biomes/" + "ab".repeat(32)));
|
||||
|
||||
assertEquals("skypack", ModdedForcedDatapack.retainedPackName(epoch, PACK_ROOT));
|
||||
assertEquals(List.of(ModdedWorldgenIds.biomeRef("skypack", "sky", "meadow"), "sky:meadow"),
|
||||
ModdedWorldgenIds.legacyBiomeRefs(ModdedForcedDatapack.retainedPackName(epoch, PACK_ROOT), "sky", "meadow"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scopedAliasesOfOtherDimensionsAreIgnored() throws IOException {
|
||||
GenerationEpoch epoch = epoch("aether:the_aether", "sky", List.of(
|
||||
ModdedWorldgenIds.biomeRef("otherpack", "ground", "meadow"),
|
||||
ModdedWorldgenIds.biomeRef("skypack", "sky", "meadow")));
|
||||
|
||||
assertEquals("skypack", ModdedForcedDatapack.retainedPackName(epoch, PACK_ROOT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void borrowedRetainedPackWithoutScopedAliasesKeepsTheDimensionKey() throws IOException {
|
||||
GenerationEpoch epoch = epoch("aether:the_aether", "sky", List.of("iris:biomes/" + "ab".repeat(32)));
|
||||
|
||||
assertEquals("sky", ModdedForcedDatapack.retainedPackName(epoch, PACK_ROOT));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aliasesFromSeveralPacksAreRefused() {
|
||||
GenerationEpoch epoch = epoch("aether:the_aether", "sky", List.of(
|
||||
ModdedWorldgenIds.biomeRef("skypack", "sky", "meadow"),
|
||||
ModdedWorldgenIds.biomeRef("otherpack", "sky", "meadow")));
|
||||
|
||||
IOException refused = assertThrows(IOException.class, () -> ModdedForcedDatapack.retainedPackName(epoch, PACK_ROOT));
|
||||
assertEquals(true, refused.getMessage().contains(PACK_ROOT.toString()));
|
||||
}
|
||||
|
||||
static GenerationEpoch epoch(String dimensionTypeKey, String dimensionKey, List<String> biomeKeys) {
|
||||
Map<PhysicalResourceKey, String> definitions = new TreeMap<>();
|
||||
for (String biome : biomeKeys) {
|
||||
definitions.put(new PhysicalResourceKey(GenerationRegistryContractFactory.BIOME_REGISTRY, biome), FINGERPRINT);
|
||||
}
|
||||
GenerationEpoch.DimensionContract dimension = new GenerationEpoch.DimensionContract(
|
||||
dimensionKey,
|
||||
dimensionTypeKey,
|
||||
"NORMAL",
|
||||
"OVERWORLD",
|
||||
127,
|
||||
0,
|
||||
256,
|
||||
256,
|
||||
1D,
|
||||
false,
|
||||
"none",
|
||||
0,
|
||||
"0".repeat(64),
|
||||
GenerationEpochContractFactory.CURRENT_DIMENSION_TYPE_FINGERPRINT_SCHEMA,
|
||||
FINGERPRINT
|
||||
);
|
||||
return GenerationEpoch.create(new GenerationEpoch.Spec(FINGERPRINT, 1, 5L, 1, 1, 1, FINGERPRINT, dimension,
|
||||
GenerationRegistryContract.fromDefinitions(definitions)));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user