11package dev .xpple .seedmapper .datapack ;
22
33import 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 ;
48import com .mojang .logging .LogUtils ;
59import dev .xpple .seedmapper .SeedMapper ;
610import 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