Skip to content

Commit 610e082

Browse files
committed
Better Handling Of DataPacks
1 parent 511fcfb commit 610e082

3 files changed

Lines changed: 85 additions & 5 deletions

File tree

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ I also added the ability to import waypoints from [Wurst7-CevAPI](https://github
170170
Can now change the default 5 minute render timeout with ```/sm:config ESP Timeout```
171171

172172
### Loot Table Browser
173-
174173
Can now visually search and browse through the loot table for the given map area. Click the 'Loot Table' button on the seed map to open the browser. You can also make ESP highlights or waypoints to the chests or simply copy the coordinates. Enchantments will be highlighted with colors and icons.
175174

176175
![LootTable](https://i.imgur.com/lnT5LsP.png)

src/main/c/cubiomes

src/main/java/dev/xpple/seedmapper/datapack/DatapackStructureManager.java

Lines changed: 84 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -388,9 +388,15 @@ private DatapackWorldgen(CloseableResourceManager resourceManager, RegistryAcces
388388
}
389389

390390
public static DatapackWorldgen load(Path datapackRoot, long seed) throws IOException {
391-
PackResources vanilla = createVanillaPack();
392-
PackResources customPack = createPathPack("seedmapper_datapack", datapackRoot, PackSource.WORLD);
393-
CloseableResourceManager resourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, List.of(vanilla, customPack));
391+
PackResources vanilla = createVanillaPack();
392+
// Create a sanitized copy of the datapack that strips worldgen JSON which
393+
// commonly fails registry loading (noise_settings, density_function, etc.).
394+
Path sanitized = sanitizeDatapack(datapackRoot);
395+
PackResources customPack = createPathPack("seedmapper_datapack", sanitized, PackSource.WORLD);
396+
// Create a small runtime fallback datapack to supply missing density-function keys
397+
Path fallbackDatapack = createTemporaryFallbackDatapack();
398+
PackResources fallbackPack = createPathPack("seedmapper_fallback", fallbackDatapack, PackSource.BUILT_IN);
399+
CloseableResourceManager resourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, List.of(vanilla, fallbackPack, customPack));
394400
RegistryAccess.Frozen registryAccess = loadRegistryAccess(resourceManager);
395401
Set<Identifier> vanillaStructures = loadVanillaStructureIds();
396402
LevelStorageSource.LevelStorageAccess storageAccess = createTempStorageAccess();
@@ -604,6 +610,45 @@ private static List<CustomStructureSet> buildCustomStructureSets(RegistryAccess
604610
}
605611
}
606612

613+
private static Path createTemporaryFallbackDatapack() throws IOException {
614+
Path temp = Files.createTempDirectory("seedmapper_fallback_datapack");
615+
Path dataDir = temp.resolve("data").resolve("minecraft").resolve("worldgen").resolve("density_function");
616+
Files.createDirectories(dataDir);
617+
// Provide a simple constant density function so registry parsing that expects
618+
// `preliminary_surface_level` can resolve during datapack import. This is
619+
// intentionally minimal; it acts as a fallback only.
620+
String json = "{\n \"type\": \"minecraft:constant\",\n \"argument\": 64.0\n}\n";
621+
Files.writeString(dataDir.resolve("preliminary_surface_level.json"), json);
622+
return temp;
623+
}
624+
625+
private static Path sanitizeDatapack(Path baseDir) throws IOException {
626+
if (baseDir == null) return null;
627+
Path sanitized = Files.createTempDirectory("seedmapper_sanitized_");
628+
try (Stream<Path> stream = Files.walk(baseDir)) {
629+
stream.forEach(source -> {
630+
try {
631+
Path rel = baseDir.relativize(source);
632+
String relStr = rel.toString().replace('\\', '/');
633+
// Skip worldgen-related files under data/*/worldgen/**
634+
if (relStr.startsWith("data/") && relStr.contains("/worldgen/")) {
635+
return;
636+
}
637+
Path target = sanitized.resolve(rel);
638+
if (Files.isDirectory(source)) {
639+
Files.createDirectories(target);
640+
} else {
641+
Files.createDirectories(target.getParent());
642+
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
643+
}
644+
} catch (IOException e) {
645+
throw new RuntimeException(e);
646+
}
647+
});
648+
}
649+
return sanitized;
650+
}
651+
607652
public record DimensionContext(int dimensionId, ChunkGenerator chunkGenerator, BiomeSource biomeSource, RandomState randomState,
608653
ChunkGeneratorStructureState structureState, LevelHeightAccessor heightAccessor) {}
609654

@@ -927,6 +972,29 @@ private static RegistryAccess.Frozen loadRegistryAccess(ResourceManager resource
927972
new FilteringResourceManager(resourceManager, DatapackStructureManager::isEnchantmentRelatedResource),
928973
DatapackStructureManager::isEnchantmentRelatedRegistry
929974
),
975+
new RegistryLoadAttempt(
976+
"skip_worldgen_noise_and_density",
977+
resourceManager,
978+
key -> {
979+
if (key == null) return false;
980+
// Avoid loading worldgen noise settings and density functions from the datapack
981+
if (Registries.NOISE_SETTINGS.equals(key) || Registries.DENSITY_FUNCTION.equals(key)) return false;
982+
return true;
983+
}
984+
),
985+
new RegistryLoadAttempt(
986+
"structures_only",
987+
new FilteringResourceManager(resourceManager, DatapackStructureManager::isWorldgenResource),
988+
key -> {
989+
if (key == null) return false;
990+
return Registries.STRUCTURE.equals(key)
991+
|| Registries.STRUCTURE_SET.equals(key)
992+
|| Registries.BIOME.equals(key)
993+
|| Registries.CONFIGURED_CARVER.equals(key)
994+
|| Registries.PLACED_FEATURE.equals(key)
995+
|| Registries.CONFIGURED_FEATURE.equals(key);
996+
}
997+
),
930998
new RegistryLoadAttempt(
931999
"unfiltered",
9321000
resourceManager,
@@ -986,6 +1054,19 @@ private static List<RegistryDataLoader.RegistryData<?>> filterRegistryData(
9861054
.toList();
9871055
}
9881056

1057+
private static boolean isWorldgenResource(Identifier id) {
1058+
if (id == null) return false;
1059+
String path = id.getPath();
1060+
if (path == null) return false;
1061+
return path.startsWith("worldgen/noise_settings")
1062+
|| path.startsWith("worldgen/density_function")
1063+
|| path.startsWith("worldgen/world_preset")
1064+
|| path.startsWith("worldgen/configured_carver")
1065+
|| path.startsWith("worldgen/placed_feature")
1066+
|| path.startsWith("worldgen/configured_feature")
1067+
|| path.startsWith("worldgen/configured_carver");
1068+
}
1069+
9891070
private static boolean isEnchantmentResource(Identifier id) {
9901071
if (id == null) {
9911072
return false;

0 commit comments

Comments
 (0)