Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 040a8ce

Browse filesBrowse files
committed
Fix Datapack Import
1 parent 14a75fb commit 040a8ce
Copy full SHA for 040a8ce

4 files changed

+290-61Lines changed: 290 additions & 61 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎gradle.properties‎

Copy file name to clipboardExpand all lines: gradle.properties
+1-1Lines 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

Collapse file

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

Copy file name to clipboardExpand all lines: src/main/java/dev/xpple/seedmapper/config/Configs.java
+25Lines 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) {
Collapse file

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

Copy file name to clipboardExpand all lines: src/main/java/dev/xpple/seedmapper/datapack/DatapackStructureManager.java
+118-11Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.