Skip to content

Commit 040a8ce

Browse files
committed
Fix Datapack Import
1 parent 14a75fb commit 040a8ce

4 files changed

Lines changed: 290 additions & 61 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ org.gradle.parallel=true
44

55
# Mod Properties
66
mod_version=2.22.2-CevAPI
7-
fork_release_version=v0.17
7+
fork_release_version=v0.18
88
maven_group=dev.xpple
99
archives_base_name=SeedMapper
1010

src/main/java/dev/xpple/seedmapper/config/Configs.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ private static Component getDatapackSavedCachePathsComment() {
104104
return Component.literal("Per-server cached datapack file locations.");
105105
}
106106

107+
@Config(comment = "getDatapackLastUrlsComment")
108+
public static Map<String, String> DatapackLastUrls = new HashMap<>();
109+
private static Component getDatapackLastUrlsComment() {
110+
return Component.literal("Per-server last datapack URL entered in the UI.");
111+
}
112+
107113
@Config(comment = "getWorldBorderSavedComment")
108114
public static Map<String, Integer> WorldBorderSaved = new HashMap<>();
109115
private static Component getWorldBorderSavedComment() {
@@ -184,6 +190,15 @@ public static java.nio.file.Path getSavedDatapackCachePathForCurrentServer() {
184190
return java.nio.file.Path.of(raw);
185191
}
186192

193+
public static String getLastDatapackUrlForCurrentServer() {
194+
String key = getCurrentServerKey();
195+
if (key == null) {
196+
return null;
197+
}
198+
String url = DatapackLastUrls.get(key);
199+
return (url == null || url.isBlank()) ? null : url;
200+
}
201+
187202
public static boolean saveDatapackUrlForCurrentServer(String url) {
188203
String key = getCurrentServerKey();
189204
if (key == null || url == null || url.isBlank()) {
@@ -209,6 +224,16 @@ public static boolean saveDatapackForCurrentServer(String url, java.nio.file.Pat
209224
return true;
210225
}
211226

227+
public static boolean saveLastDatapackUrlForCurrentServer(String url) {
228+
String key = getCurrentServerKey();
229+
if (key == null || url == null || url.isBlank()) {
230+
return false;
231+
}
232+
DatapackLastUrls.put(key, url.trim());
233+
save();
234+
return true;
235+
}
236+
212237
public static void removeDatapackUrlForCurrentServer() {
213238
String key = getCurrentServerKey();
214239
if (key == null) {

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

Lines changed: 118 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package dev.xpple.seedmapper.datapack;
22

33
import com.github.cubiomes.Cubiomes;
4+
import com.google.gson.JsonElement;
5+
import com.google.gson.JsonArray;
6+
import com.google.gson.JsonObject;
7+
import com.google.gson.JsonParser;
48
import com.mojang.logging.LogUtils;
59
import dev.xpple.seedmapper.SeedMapper;
610
import dev.xpple.seedmapper.config.Configs;
@@ -673,7 +677,11 @@ private static Path sanitizeDatapack(Path baseDir) throws IOException {
673677
Files.createDirectories(target);
674678
} else {
675679
Files.createDirectories(target.getParent());
676-
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
680+
if (shouldSanitizeBiomePath(relStr)) {
681+
Files.writeString(target, sanitizeBiomeJson(Files.readString(source)));
682+
} else {
683+
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
684+
}
677685
}
678686
} catch (IOException e) {
679687
throw new RuntimeException(e);
@@ -1000,35 +1008,43 @@ private static PackResources createVanillaPack() {
10001008
}
10011009

10021010
private static RegistryAccess.Frozen loadRegistryAccess(ResourceManager resourceManager) {
1011+
ResourceManager structureSafeResourceManager = new FilteringResourceManager(resourceManager, DatapackStructureManager::isUnsafeForStructureImportResource);
10031012
List<RegistryLoadAttempt> attempts = List.of(
10041013
new RegistryLoadAttempt(
1005-
"filtered_enchantment_and_provider",
1006-
new FilteringResourceManager(resourceManager, DatapackStructureManager::isEnchantmentRelatedResource),
1007-
DatapackStructureManager::isEnchantmentRelatedRegistry
1014+
"structure_safe_full_worldgen",
1015+
structureSafeResourceManager,
1016+
key -> !isUnsafeForStructureImportRegistry(key)
10081017
),
10091018
new RegistryLoadAttempt(
1010-
"skip_worldgen_noise_and_density",
1011-
resourceManager,
1019+
"structure_safe_skip_presets",
1020+
structureSafeResourceManager,
10121021
key -> {
10131022
if (key == null) return false;
1014-
// Avoid loading worldgen noise settings and density functions from the datapack
1015-
if (Registries.NOISE_SETTINGS.equals(key) || Registries.DENSITY_FUNCTION.equals(key)) return false;
1023+
if (isUnsafeForStructureImportRegistry(key)) return false;
1024+
if (Registries.WORLD_PRESET.equals(key)) return false;
10161025
return true;
10171026
}
10181027
),
10191028
new RegistryLoadAttempt(
10201029
"structures_only",
1021-
new FilteringResourceManager(resourceManager, DatapackStructureManager::isIrrelevantToStructureImportResource),
1030+
new FilteringResourceManager(structureSafeResourceManager, DatapackStructureManager::isIrrelevantToStructureImportResource),
10221031
key -> {
10231032
if (key == null) return false;
1033+
if (isUnsafeForStructureImportRegistry(key)) return false;
10241034
return Registries.STRUCTURE.equals(key)
10251035
|| Registries.STRUCTURE_SET.equals(key)
10261036
|| Registries.BIOME.equals(key)
10271037
|| Registries.LEVEL_STEM.equals(key)
10281038
|| Registries.DIMENSION_TYPE.equals(key)
10291039
|| Registries.CONFIGURED_CARVER.equals(key)
10301040
|| Registries.PLACED_FEATURE.equals(key)
1031-
|| Registries.CONFIGURED_FEATURE.equals(key);
1041+
|| Registries.CONFIGURED_FEATURE.equals(key)
1042+
|| Registries.PROCESSOR_LIST.equals(key)
1043+
|| Registries.TEMPLATE_POOL.equals(key)
1044+
|| Registries.NOISE_SETTINGS.equals(key)
1045+
|| Registries.NOISE.equals(key)
1046+
|| Registries.DENSITY_FUNCTION.equals(key)
1047+
|| Registries.MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST.equals(key);
10321048
}
10331049
)
10341050
);
@@ -1053,9 +1069,11 @@ private static RegistryAccess.Frozen loadRegistryAccessInternal(ResourceManager
10531069
RegistryAccess.Frozen staticAccess = layered.getLayer(RegistryLayer.STATIC);
10541070
List<HolderLookup.RegistryLookup<?>> staticLookups = staticAccess.listRegistries().collect(Collectors.toList());
10551071
List<RegistryDataLoader.RegistryData<?>> worldgenRegistries = filterRegistryData(RegistryDataLoader.WORLDGEN_REGISTRIES, registryFilter);
1072+
logRegistryLoadPlan("worldgen", worldgenRegistries);
10561073
RegistryAccess.Frozen worldgen = RegistryDataLoader.load(resourceManager, staticLookups, worldgenRegistries, Runnable::run).join();
10571074
List<HolderLookup.RegistryLookup<?>> dimensionLookups = Stream.concat(staticLookups.stream(), worldgen.listRegistries()).collect(Collectors.toList());
10581075
List<RegistryDataLoader.RegistryData<?>> dimensionRegistries = filterRegistryData(RegistryDataLoader.DIMENSION_REGISTRIES, registryFilter);
1076+
logRegistryLoadPlan("dimension", dimensionRegistries);
10591077
RegistryAccess.Frozen dimensions = RegistryDataLoader.load(resourceManager, dimensionLookups, dimensionRegistries, Runnable::run).join();
10601078
Optional<Registry<LevelStem>> loadedStems = dimensions.lookup(Registries.LEVEL_STEM);
10611079
if (loadedStems.isEmpty() || loadedStems.get().keySet().isEmpty()) {
@@ -1085,6 +1103,19 @@ private static List<RegistryDataLoader.RegistryData<?>> filterRegistryData(
10851103
.toList();
10861104
}
10871105

1106+
private static void logRegistryLoadPlan(String phase, List<RegistryDataLoader.RegistryData<?>> registries) {
1107+
if (!Configs.DevMode) {
1108+
return;
1109+
}
1110+
List<Identifier> keys = registries == null
1111+
? List.of()
1112+
: registries.stream()
1113+
.map(RegistryDataLoader.RegistryData::key)
1114+
.map(ResourceKey::identifier)
1115+
.toList();
1116+
LOGGER.info("Datapack registry load plan {}: {}", phase, keys);
1117+
}
1118+
10881119
private static boolean isIrrelevantToStructureImportResource(Identifier id) {
10891120
if (id == null) return false;
10901121
String path = id.getPath();
@@ -1097,13 +1128,17 @@ private static boolean isIrrelevantToStructureImportResource(Identifier id) {
10971128
|| path.startsWith("worldgen/configured_carver")
10981129
|| path.startsWith("worldgen/placed_feature")
10991130
|| path.startsWith("worldgen/configured_feature")
1131+
|| path.startsWith("worldgen/processor_list")
1132+
|| path.startsWith("worldgen/template_pool")
11001133
|| path.startsWith("tags/worldgen/biome")
11011134
|| path.startsWith("tags/biome")
11021135
|| path.startsWith("tags/worldgen/structure")
11031136
|| path.startsWith("tags/worldgen/structure_set")
11041137
|| path.startsWith("tags/worldgen/configured_carver")
11051138
|| path.startsWith("tags/worldgen/placed_feature")
11061139
|| path.startsWith("tags/worldgen/configured_feature")
1140+
|| path.startsWith("tags/worldgen/processor_list")
1141+
|| path.startsWith("tags/worldgen/template_pool")
11071142
|| path.startsWith("structures/")) {
11081143
return false;
11091144
}
@@ -1128,14 +1163,86 @@ private static boolean shouldSkipSanitizedDatapackPath(String relativePath) {
11281163
|| dataPath.startsWith("villager_trade/")
11291164
|| dataPath.startsWith("enchantment/")
11301165
|| dataPath.startsWith("enchantment_provider/")
1166+
|| dataPath.startsWith("tags/villager_trade/")
1167+
|| dataPath.startsWith("tags/enchantment/")
11311168
|| dataPath.startsWith("tags/enchantments/")
11321169
|| dataPath.startsWith("tags/items/enchantable/")) {
11331170
return true;
11341171
}
11351172
return dataPath.startsWith("worldgen/noise_settings")
11361173
|| dataPath.startsWith("worldgen/density_function")
11371174
|| dataPath.startsWith("worldgen/world_preset")
1138-
|| dataPath.startsWith("worldgen/template_pool");
1175+
|| dataPath.startsWith("worldgen/placed_feature")
1176+
|| dataPath.startsWith("worldgen/configured_feature")
1177+
|| dataPath.startsWith("tags/worldgen/placed_feature/")
1178+
|| dataPath.startsWith("tags/worldgen/configured_feature/");
1179+
}
1180+
1181+
private static boolean shouldSanitizeBiomePath(String relativePath) {
1182+
if (relativePath == null || relativePath.isBlank()) {
1183+
return false;
1184+
}
1185+
String relStr = relativePath.replace('\\', '/');
1186+
if (!relStr.startsWith("data/")) {
1187+
return false;
1188+
}
1189+
int namespaceSeparator = relStr.indexOf('/', "data/".length());
1190+
if (namespaceSeparator < 0 || namespaceSeparator + 1 >= relStr.length()) {
1191+
return false;
1192+
}
1193+
String dataPath = relStr.substring(namespaceSeparator + 1);
1194+
return dataPath.startsWith("worldgen/biome/") && dataPath.endsWith(".json");
1195+
}
1196+
1197+
private static String sanitizeBiomeJson(String json) {
1198+
JsonElement parsed = JsonParser.parseString(json);
1199+
if (!parsed.isJsonObject()) {
1200+
return json;
1201+
}
1202+
JsonObject root = parsed.getAsJsonObject();
1203+
root.add("features", new JsonArray());
1204+
root.add("carvers", new JsonArray());
1205+
if (root.has("generation_settings") && root.get("generation_settings").isJsonObject()) {
1206+
JsonObject generationSettings = root.getAsJsonObject("generation_settings");
1207+
generationSettings.remove("features");
1208+
generationSettings.remove("carvers");
1209+
}
1210+
return root.toString();
1211+
}
1212+
1213+
private static boolean isUnsafeForStructureImportResource(Identifier id) {
1214+
if (id == null) {
1215+
return false;
1216+
}
1217+
String path = id.getPath();
1218+
if (path == null) {
1219+
return false;
1220+
}
1221+
return path.startsWith("villager_trade/")
1222+
|| path.startsWith("tags/villager_trade/")
1223+
|| path.startsWith("chicken_variant/")
1224+
|| path.startsWith("tags/chicken_variant/")
1225+
|| path.startsWith("wolf_variant/")
1226+
|| path.startsWith("tags/wolf_variant/")
1227+
|| path.startsWith("enchantment/")
1228+
|| path.startsWith("enchantment_provider/")
1229+
|| path.startsWith("tags/enchantment/")
1230+
|| path.startsWith("tags/enchantments/")
1231+
|| path.startsWith("tags/items/enchantable/");
1232+
}
1233+
1234+
private static boolean isUnsafeForStructureImportRegistry(ResourceKey<? extends Registry<?>> key) {
1235+
if (key == null) {
1236+
return true;
1237+
}
1238+
return Registries.VILLAGER_TRADE.equals(key)
1239+
|| Registries.TRADE_SET.equals(key)
1240+
|| Registries.ENCHANTMENT.equals(key)
1241+
|| Registries.ENCHANTMENT_PROVIDER.equals(key)
1242+
|| Registries.CHICKEN_VARIANT.equals(key)
1243+
|| Registries.CHICKEN_SOUND_VARIANT.equals(key)
1244+
|| Registries.WOLF_VARIANT.equals(key)
1245+
|| Registries.WOLF_SOUND_VARIANT.equals(key);
11391246
}
11401247

11411248
private static boolean isEnchantmentResource(Identifier id) {

0 commit comments

Comments
 (0)