diff --git a/.github/primers/config/1.1/README.md b/.github/primers/config/1.1/README.md new file mode 100644 index 00000000..b607c867 --- /dev/null +++ b/.github/primers/config/1.1/README.md @@ -0,0 +1,64 @@ +# Config Format v1.1 + +To make it less confusing for users to configure custom generator, I decided to merge `customGen` with basic generators (`cobbleGen`/`stoneGen`/`basaltGen`). This format is a partial port of [GH-53](https://github.com/null2264/CobbleGen/issues/53). + +> [!NOTE] +> If you still want to use format v1.0, you can set `formatVersion` to `1.0` (do note that it'll be removed completely at some point): +> +> ```json5 +> { +> "formatVersion": "1.0", +> "cobbleGen": [ +> ... +> ], +> "customGen": { +> ... +> } +> } +> ``` + +## v1.0 + +Previously in v1.0, you'd define custom generators inside `customGen`, but most people got confused about the `cobbleGen`/`stoneGen`/`basaltGen` and thought it's a name for the custom generator. + +```json5 +{ + "cobbleGen": [ + { + "id": "minecraft:cobblestone", + "weight": 100.0 + } + ], + "customGen": { + // This is the most confusing part for most people + "cobbleGen": { + "minecraft:bedrock": [ + { + "id": "#minecraft:ores", + "weight": 100.0 + } + ] + } + } +} +``` + +## v1.1 + +Now in v1.1, all you need to do to define a custom generator is by adding `modifier` value inside the "result block", similar to how you set the generation's `weight`. + +```json5 +{ + "cobbleGen": [ + { + "id": "minecraft:cobblestone", + "weight": 100.0 + }, + { + "id": "#minecraft:ores", + "weight": 100.0, + "modifier": "minecraft:bedrock" + } + ] +} +``` diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9b991194..f1cdd981 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -134,56 +134,6 @@ jobs: pauseOnLostFocus:false EOF - cat <> run/test-${{ matrix.mc }}-${{ matrix.loader }}/config/cobblegen.json5 - { - "formatVersion": "1.0", - "cobbleGen": [ - { - "id": "minecraft:bedrock", - "weight": 100.0, - }, - ], - "stoneGen": [ - { - "id": "minecraft:bedrock", - "weight": 100.0, - }, - ], - "basaltGen": [ - { - "id": "minecraft:bedrock", - "weight": 100.0, - }, - ], - "customGen": { - "cobbleGen": { - "minecraft:bedrock": [ - { - "id": "minecraft:bedrock", - "weight": 100.0, - }, - ], - }, - "stoneGen": { - "minecraft:bedrock": [ - { - "id": "minecraft:bedrock", - "weight": 100.0, - }, - ], - }, - "basaltGen": { - "minecraft:bedrock": [ - { - "id": "minecraft:bedrock", - "weight": 100.0, - }, - ], - }, - }, - } - EOF - json="$(cat ./headlessmc.json)" url="$(echo $json | jq -r '.assets[].browser_download_url' | grep .jar | grep launcher | grep -v jfx | grep -v wrapper)" curl -Ls -o "headlessmc-launcher.jar" $url diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/CobbleGen.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/CobbleGen.java index 753f4b0b..f51229aa 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/CobbleGen.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/CobbleGen.java @@ -4,6 +4,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder; import io.github.null2264.cobblegen.compat.LoaderCompat; import io.github.null2264.cobblegen.compat.TextCompat; +import io.github.null2264.cobblegen.data.config.Config; import io.github.null2264.cobblegen.data.config.ConfigData; import io.github.null2264.cobblegen.data.config.ConfigMetaData; import io.github.null2264.cobblegen.data.model.CGRegistry; @@ -14,7 +15,6 @@ import java.io.File; import java.nio.file.Path; -import static io.github.null2264.cobblegen.data.config.ConfigHelper.loadConfig; import static io.github.null2264.cobblegen.util.Constants.OP_LEVEL_GAMEMASTERS; #if FORGE @@ -39,12 +39,13 @@ public class CobbleGen private static final Path configPath = LoaderCompat.getConfigDir(); private static final File configFile = new File(configPath + File.separator + MOD_ID + ".json5"); private static final File metaConfigFile = new File(configPath + File.separator + MOD_ID + "-meta.json5"); + private static final Config.Factory metaConfigFactory = new ConfigMetaData.Factory(); @ApiStatus.Internal - public static ConfigMetaData META_CONFIG = loadConfig(false, metaConfigFile, null, new ConfigMetaData(), ConfigMetaData.class); + public static ConfigMetaData META_CONFIG = metaConfigFactory.load(metaConfigFile); public CobbleGen() { // Force config to be generated when loading up the game instead of having to load a world - loadConfig(false, configFile, null, ConfigData.defaultConfig(), ConfigData.class); + new ConfigData.Factory().load(configFile); #if FORGE && MC>=11801 && MC<12105 // I was gonna do RegisterGameTestsEvent like a normal person, but there's a check that I need to bypass otherwise Forge won't register my test net.minecraft.gametest.framework.GameTestRegistry.register(io.github.null2264.cobblegen.gametest.BlockGenerationTest.class); @@ -59,19 +60,27 @@ public void onInitialize() {} public static void initCommands(CommandDispatcher dispatcher) { CGLog.info("Registering command..."); dispatcher.register( - LiteralArgumentBuilder.literal("cobblegen") - .then(LiteralArgumentBuilder.literal("reload-meta").requires(arg -> arg.hasPermission(OP_LEVEL_GAMEMASTERS)).executes(c -> { - CGLog.info("Reloading meta config..."); - META_CONFIG = loadConfig(true, metaConfigFile, META_CONFIG, new ConfigMetaData(), ConfigMetaData.class); - c.getSource().sendSuccess( - #if MC>=12001 - () -> - #endif - TextCompat.literal("Meta config has been reloaded"), false - ); - CGLog.info("Meta config has been reloaded"); - return 0; - })) + LiteralArgumentBuilder.literal("cobblegen") + .then(LiteralArgumentBuilder.literal("reload-meta").requires(arg -> arg.hasPermission(OP_LEVEL_GAMEMASTERS)).executes(c -> { + META_CONFIG = metaConfigFactory.reload(metaConfigFile); + c.getSource().sendSuccess( + #if MC>=12001 + () -> + #endif + TextCompat.literal("Meta config has been reloaded"), false + ); + return 0; + })) + .then(LiteralArgumentBuilder.literal("reload").requires(arg -> arg.hasPermission(OP_LEVEL_GAMEMASTERS)).executes(c -> { + FLUID_INTERACTION.reload(); + c.getSource().sendSuccess( + #if MC>=12001 + () -> + #endif + TextCompat.literal("Generator config has been reloaded"), false + ); + return 0; + })) ); } diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/FluidInteraction.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/FluidInteraction.java index 0df760f8..99b7a343 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/FluidInteraction.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/FluidInteraction.java @@ -1,6 +1,5 @@ package io.github.null2264.cobblegen; -import io.github.null2264.cobblegen.CobbleGen; import io.github.null2264.cobblegen.data.CGRegistryImpl; import io.github.null2264.cobblegen.data.model.CGRegistry; import io.github.null2264.cobblegen.data.model.Generator; @@ -27,7 +26,7 @@ import static io.github.null2264.cobblegen.compat.CollectionCompat.listOf; import static io.github.null2264.cobblegen.util.Constants.LAVA_FIZZ; -import static io.github.null2264.cobblegen.util.Util.notNullOr; +import static io.github.null2264.cobblegen.util.Util.elvis; /** * Replacement for BlockGenerator. This will act like Vanilla's registry system @@ -60,7 +59,7 @@ public Map> getLocalGenerators() { @NotNull public Map> getGenerators() { - return notNullOr(serverGeneratorMap, generatorMap); + return elvis(serverGeneratorMap, generatorMap); } @ApiStatus.Internal @@ -143,7 +142,6 @@ public boolean interact(LevelAccessor level, BlockPos pos, BlockState state, boo for (Generator generator : generators) { if (!generator.check(level, pos, state, fromTop)) continue; - if (fromTop && generator.getType() != GeneratorType.STONE) continue; final Optional result = generator.tryGenerate(level, pos, state); if (result.isPresent()) { diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/compat/CollectionCompat.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/compat/CollectionCompat.java index 6ba54088..4146942a 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/compat/CollectionCompat.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/compat/CollectionCompat.java @@ -23,4 +23,11 @@ public static Map mapOf(K key, V value) { public static List streamToList(Stream stream) { return (List) Collections.unmodifiableList(new ArrayList<>(Arrays.asList(stream.toArray()))); } -} \ No newline at end of file + + public static List mergeList(List list, List list2) { + List rt = new ArrayList<>(); + rt.addAll(list); + rt.addAll(list2); + return rt; + } +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/CGModifier.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/CGModifier.java index d62cb321..3a0fcd9f 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/CGModifier.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/CGModifier.java @@ -5,8 +5,6 @@ import java.util.List; import java.util.Objects; -import static io.github.null2264.cobblegen.compat.CollectionCompat.streamToList; - /** * Class to holds modifier as Map key */ @@ -15,7 +13,7 @@ public class CGModifier { public CGModifier(List modifiers) { if (modifiers.size() >= 4) throw new IllegalArgumentException("Cannot have more than 4 modifiers"); - this.modifiers = streamToList(modifiers.stream().sorted()); + this.modifiers = modifiers.stream().sorted().toList(); } public void writeToBuf(FriendlyByteBuf buf) { @@ -38,4 +36,4 @@ public boolean equals(Object o) { public int hashCode() { return Objects.hash(modifiers); } -} \ No newline at end of file +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/Config.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/Config.java index 6276fc99..dcbdf169 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/Config.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/Config.java @@ -1,3 +1,10 @@ package io.github.null2264.cobblegen.data.config; -public interface Config {} \ No newline at end of file +import java.io.File; + +public interface Config { + interface Factory { + T load(File file); + T reload(File file); + } +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigData.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigData.java index fa3c6320..3b4b65be 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigData.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigData.java @@ -6,17 +6,52 @@ import io.github.null2264.cobblegen.data.CGIdentifier; import io.github.null2264.cobblegen.data.JanksonSerializable; import io.github.null2264.cobblegen.data.Pair; +import io.github.null2264.cobblegen.gametest.CobbleGenTestConfig; +import io.github.null2264.cobblegen.util.CGLog; +import io.github.null2264.cobblegen.util.Util; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.File; + import static io.github.null2264.cobblegen.compat.CollectionCompat.listOf; @SuppressWarnings("TextBlockMigration") -public class ConfigData implements Config, JanksonSerializable -{ +public class ConfigData implements Config, JanksonSerializable { + + private static String NAME = "generator"; + public static String LATEST_FORMAT_VERSION = "1.1"; + + public static class Factory implements Config.Factory { + @Override + public ConfigData load(File file) { + return ConfigHelper.loadConfig( + NAME, + false, + file, + null, + CobbleGenTestConfig.ENABLED ? ConfigData.testConfig() : ConfigData.defaultConfig(), + ConfigData.class + ); + } + + @Override + public ConfigData reload(File file) { + return ConfigHelper.loadConfig( + NAME, + true, + file, + null, + CobbleGenTestConfig.ENABLED ? ConfigData.testConfig() : ConfigData.defaultConfig(), + ConfigData.class + ); + } + } + + // FIXME: Make this SemVer object @Comment(value = "CobbleGen Format Version, you can leave this alone for now. v2.0 will be released in CobbleGen v6.0") @NotNull - public String formatVersion = "1.0"; + public String formatVersion = LATEST_FORMAT_VERSION; @Nullable @Comment(value = "Default Generators\n" + @@ -32,7 +67,8 @@ public class ConfigData implements Config, JanksonSerializable " \"mod_id:dimension_id\"\n" + " ],\n" + " \"minY\": 0,\n" + - " \"maxY\": 69\n" + + " \"maxY\": 69,\n" + + " \"modifier\": \"mod_id:modifier_block_id\"\n" + "}") public ResultList cobbleGen; @@ -68,59 +104,47 @@ public class ConfigData implements Config, JanksonSerializable @Nullable public FluidInteractionMap advanced; + public static ConfigData testConfig() { + ConfigData config = new ConfigData(); + config.cobbleGen = ResultList.of( + new WeightedBlock.Builder().setId("minecraft:cobbled_deepslate").setWeight(100.0).build(), + new WeightedBlock.Builder().setId("minecraft:deepslate").setWeight(100.0).setModifier("minecraft:bedrock").build() + ); + config.stoneGen = ResultList.of( + new WeightedBlock.Builder().setId("minecraft:deepslate").setWeight(100.0).build(), + new WeightedBlock.Builder().setId("minecraft:cobbled_deepslate").setWeight(100.0).setModifier("minecraft:bedrock").build() + ); + config.basaltGen = ResultList.of( + new WeightedBlock.Builder().setId("minecraft:blackstone").setWeight(100.0).build(), + new WeightedBlock.Builder().setId("minecraft:end_stone").setWeight(100.0).setModifier("minecraft:bedrock").build() + ); + return config; + } + public static ConfigData defaultConfig() { ConfigData config = new ConfigData(); - config.cobbleGen = ResultList.of(new WeightedBlock( - "minecraft:cobblestone", - 100.0, - null, - null, - null, - 0, - null, - null, - null - ), new WeightedBlock("minecraft:cobbled_deepslate", 100.0, null, null, 0, null, null, null, null)); - config.stoneGen = ResultList.of(new WeightedBlock("minecraft:stone", 100.0)); - config.basaltGen = ResultList.of(new WeightedBlock("minecraft:basalt", 100.0)); - config.customGen = new CustomGen( - // Cobble Gen - GeneratorMap.of( - Pair.of( - CGIdentifier.of("minecraft:bedrock"), - ResultList.of( - new WeightedBlock("minecraft:emerald_ore", 2.0), - new WeightedBlock("minecraft:diamond_ore", 5.0), - new WeightedBlock("minecraft:lapis_ore", 8.0), - new WeightedBlock("minecraft:gold_ore", 10.0), - new WeightedBlock("minecraft:iron_ore", 15.0), - new WeightedBlock("minecraft:coal_ore", 20.0), - new WeightedBlock("minecraft:cobblestone", 80.0) - ) - ) - ), - // Stone Gen - GeneratorMap.of( - Pair.of( - CGIdentifier.of("minecraft:bedrock"), - ResultList.of( - new WeightedBlock("minecraft:stone", 40.0), - new WeightedBlock("minecraft:diorite", 20.0), - new WeightedBlock("minecraft:andesite", 20.0), - new WeightedBlock("minecraft:granite", 20.0) - ) - ) - ), - // Basalt Gen - GeneratorMap.of( - Pair.of( - CGIdentifier.of("minecraft:bedrock"), - ResultList.of( - new WeightedBlock("minecraft:end_stone", 100.0, listOf("minecraft:the_end")), - new WeightedBlock("minecraft:blackstone", 100.0, null, listOf("minecraft:overworld")) - ) - ) - ) + config.cobbleGen = ResultList.of( + new WeightedBlock.Builder().setId("minecraft:cobblestone").setWeight(100.0).setMinY(0).build(), + new WeightedBlock.Builder().setId("minecraft:cobbled_deepslate").setWeight(100.0).setMaxY(0).build(), + new WeightedBlock.Builder().setId("minecraft:emerald_ore").setWeight(2.0).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:diamond_ore").setWeight(5.0).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:lapis_ore").setWeight(8.0).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:gold_ore").setWeight(10.0).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:iron_ore").setWeight(15.0).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:coal_ore").setWeight(20.0).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:cobblestone").setWeight(80.0).setModifier("minecraft:bedrock").build() + ); + config.stoneGen = ResultList.of( + new WeightedBlock.Builder().setId("minecraft:stone").setWeight(100.0).build(), + new WeightedBlock.Builder().setId("minecraft:stone").setWeight(40.0).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:diorite").setWeight(20.0).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:andesite").setWeight(20.0).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:granite").setWeight(20.0).setModifier("minecraft:bedrock").build() + ); + config.basaltGen = ResultList.of( + new WeightedBlock.Builder().setId("minecraft:basalt").setWeight(100.0).build(), + new WeightedBlock.Builder().setId("minecraft:end_stone").setWeight(100.0).setDimensions(listOf("minecraft:the_end")).setModifier("minecraft:bedrock").build(), + new WeightedBlock.Builder().setId("minecraft:blackstone").setWeight(100.0).setExcludedDimensions(listOf("minecraft:overworld")).setModifier("minecraft:bedrock").build() ); return config; } @@ -129,11 +153,10 @@ public static ConfigData defaultConfig() { @Serializer public JsonObject toJson() { JsonObject json = new JsonObject(); - json.put("formatVersion", JsonPrimitive.of(formatVersion)); + json.put("formatVersion", JsonPrimitive.of(LATEST_FORMAT_VERSION)); if (cobbleGen != null) json.put("cobbleGen", cobbleGen.toJson()); if (stoneGen != null) json.put("stoneGen", stoneGen.toJson()); if (basaltGen != null) json.put("basaltGen", basaltGen.toJson()); - if (customGen != null) json.put("customGen", customGen.toJson()); if (advanced != null) json.put("advanced", advanced.toJson()); return json; } @@ -142,16 +165,42 @@ public JsonObject toJson() { public static ConfigData fromJson(JsonObject json) { ConfigData config = new ConfigData(); JsonElement formatVersion = json.get("formatVersion"); - config.formatVersion = (formatVersion instanceof JsonPrimitive) ? ((JsonPrimitive) formatVersion).asString() : "1.0"; - /* TODO + config.formatVersion = (formatVersion instanceof JsonPrimitive) ? ((JsonPrimitive) formatVersion).asString() : LATEST_FORMAT_VERSION; + config.cobbleGen = ResultList.fromJson(json.get("cobbleGen"), config.formatVersion); + config.stoneGen = ResultList.fromJson(json.get("stoneGen"), config.formatVersion); + config.basaltGen = ResultList.fromJson(json.get("basaltGen"), config.formatVersion); + // TODO: Delete later + CustomGen customGen = CustomGen.fromJson(json.getObject("customGen")); if (config.formatVersion.equals("1.0")) { - // TODO: Migrate to 2.0 + CGLog.warn(() -> "CobbleGen config format v1.0 is deprecated, please consider migrating to v" + LATEST_FORMAT_VERSION); + if (customGen != null) { + Util.optional(customGen.cobbleGen).ifPresent(gen -> gen.forEach((modifier, value) -> { + if (config.cobbleGen != null) { + config.cobbleGen.addAll(value.stream().peek(result -> result.neighbours = listOf(modifier.toString())).toList()); + } + })); + Util.optional(customGen.stoneGen).ifPresent(gen -> gen.forEach((modifier, value) -> { + if (config.stoneGen != null) { + config.stoneGen.addAll(value.stream().peek(result -> result.neighbours = listOf(modifier.toString())).toList()); + } + })); + Util.optional(customGen.basaltGen).ifPresent(gen -> gen.forEach((modifier, value) -> { + if (config.basaltGen != null) { + config.basaltGen.addAll(value.stream().peek(result -> result.neighbours = listOf(modifier.toString())).toList()); + } + })); + } + } else if (customGen != null) { + // TODO: This probably should be sent to the chat when player joined a world. + CGLog.warn(() -> + "You're using \"customGen\" on config format v" + + config.formatVersion + + "! Please migrate to format v" + + LATEST_FORMAT_VERSION + + " or specify \"formatVersion\" on the config file, otherwise the custom generator(s) won't be used by the mod." + + " Check out https://docs.aap.my.id/cobblegen/config/migration to learn how to migrate to newer format version." + ); } - */ - config.cobbleGen = ResultList.fromJson(json.get("cobbleGen")); - config.stoneGen = ResultList.fromJson(json.get("stoneGen")); - config.basaltGen = ResultList.fromJson(json.get("basaltGen")); - config.customGen = CustomGen.fromJson(json.getObject("customGen")); config.advanced = FluidInteractionMap.fromJson(json.getObject("advanced")); return config; } diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigHelper.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigHelper.java index a770e3ad..fa7f1f4b 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigHelper.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigHelper.java @@ -15,15 +15,21 @@ import static io.github.null2264.cobblegen.util.Constants.JANKSON; public class ConfigHelper { - @ApiStatus.Internal - public static T loadConfig(boolean reload, File configFile, T workingConfig, T defaultConfig, Class clazz) { + static T loadConfig( + String name, + boolean reload, + File configFile, + T workingConfig, + T defaultConfig, + Class clazz + ) { String string = reload ? "reload" : "load"; try { - CGLog.info("Trying to " + string + " config file..."); + CGLog.info(() -> "Trying to " + string + " '" + name + "' config file..."); JsonObject json = JANKSON.load(configFile); return JANKSON.fromJson(json, clazz); } catch (Exception e) { - CGLog.error("There was an error while " + string + "ing the config file!\n" + e); + CGLog.error("There was an error while " + string + "ing '" + name + "' config file!\n" + e); if (reload && workingConfig != null) { CGLog.warn("Falling back to previously working config..."); @@ -76,4 +82,4 @@ private static void saveConfig(Config config, File configFile) { CGLog.error("There was an error while creating the config file!\n" + e); } } -} \ No newline at end of file +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigMetaData.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigMetaData.java index 253f4103..7bd432be 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigMetaData.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ConfigMetaData.java @@ -3,8 +3,38 @@ import blue.endless.jankson.Comment; import org.jetbrains.annotations.NotNull; -public class ConfigMetaData implements Config -{ +import java.io.File; + +public class ConfigMetaData implements Config { + + private static final String NAME = "metadata"; + + public static class Factory implements Config.Factory { + @Override + public ConfigMetaData load(File file) { + return ConfigHelper.loadConfig( + NAME, + false, + file, + null, + new ConfigMetaData(), + ConfigMetaData.class + ); + } + + @Override + public ConfigMetaData reload(File file) { + return ConfigHelper.loadConfig( + NAME, + true, + file, + null, + new ConfigMetaData(), + ConfigMetaData.class + ); + } + } + @Comment(value="Enable Recipe Viewer support (EMI/REI/JEI)") @NotNull public Boolean enableRecipeViewer = true; @@ -44,4 +74,4 @@ public static class CreateData { @Comment(value="Disable Create's pipe support") public Boolean disablePipe = false; } -} \ No newline at end of file +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/CustomGen.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/CustomGen.java index 6e13a55c..c078cf28 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/CustomGen.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/CustomGen.java @@ -12,7 +12,12 @@ import static io.github.null2264.cobblegen.util.Constants.JANKSON; -public class CustomGen implements JanksonSerializable +/** + * @deprecated Has been merged with basic generators + * @see ConfigData + */ +@Deprecated +class CustomGen implements JanksonSerializable { @Nullable public GeneratorMap cobbleGen; @@ -38,7 +43,7 @@ public CustomGen( @Serializer public JsonObject toJson() { JsonObject json = new JsonObject(); - if (cobbleGen != null) json.put("cobbleGen", cobbleGen.toJson()); + if (cobbleGen != null) json.put("cobbleGen", JANKSON.toJson(cobbleGen)); if (stoneGen != null) json.put("stoneGen", JANKSON.toJson(stoneGen)); if (basaltGen != null) json.put("basaltGen", JANKSON.toJson(basaltGen)); return json; @@ -53,4 +58,4 @@ public static CustomGen fromJson(JsonObject json) { GeneratorMap basaltGen = GeneratorMap.fromJson(json.getObject("basaltGen")); return new CustomGen(cobbleGen, stoneGen, basaltGen); } -} \ No newline at end of file +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/GeneratorMap.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/GeneratorMap.java index a4a00644..aec26f8e 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/GeneratorMap.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/GeneratorMap.java @@ -16,6 +16,7 @@ import java.util.HashMap; import java.util.List; +// FIXME: CGIdentifier -> CGModifier public class GeneratorMap extends HashMap implements JanksonSerializable, PacketSerializable { public GeneratorMap() {} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ResultList.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ResultList.java index d9b9e6e5..fe2b117a 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ResultList.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/ResultList.java @@ -32,15 +32,19 @@ public JsonElement toJson() { @Deserializer public static ResultList fromJson(JsonElement json) { + return fromJson(json, ConfigData.LATEST_FORMAT_VERSION); + } + + public static ResultList fromJson(JsonElement json, String formatVersion) { if (json == null) return null; ResultList result = new ResultList(); ((JsonArray) json).stream() - .filter((e) -> e instanceof JsonObject) - .forEach((e) -> { - WeightedBlock block = WeightedBlock.fromJson((JsonObject) e); - if (block != null) result.add(block); - }); + .filter((e) -> e instanceof JsonObject) + .forEach((e) -> { + WeightedBlock block = WeightedBlock.fromJson((JsonObject) e, formatVersion); + if (block != null) result.add(block); + }); return result; } -} \ No newline at end of file +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/WeightedBlock.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/WeightedBlock.java index 6777de91..0b232c5c 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/WeightedBlock.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/config/WeightedBlock.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Optional; +import static io.github.null2264.cobblegen.compat.CollectionCompat.listOf; import static io.github.null2264.cobblegen.util.Constants.JANKSON; public class WeightedBlock implements PacketSerializable, JanksonSerializable @@ -32,6 +33,7 @@ public class WeightedBlock implements PacketSerializable, Jankson public Integer maxY; @Nullable public Integer minY; + // FIXME: Currently only the first element is being used @Nullable public List neighbours; @Nullable @@ -39,18 +41,34 @@ public class WeightedBlock implements PacketSerializable, Jankson @Nullable public List excludedBiomes; + /** + * @deprecated Use {@link WeightedBlock.Builder} instead. + */ + @Deprecated public WeightedBlock(String id, Double weight) { this(id, weight, null, null); } + /** + * @deprecated Use {@link WeightedBlock.Builder} instead. + */ + @Deprecated public WeightedBlock(String id, Double weight, List dimIds) { this(id, weight, dimIds, null); } + /** + * @deprecated Use {@link WeightedBlock.Builder} instead. + */ + @Deprecated public WeightedBlock(String id, Double weight, List dimIds, List excludedDimensions) { this(id, weight, dimIds, excludedDimensions, null, null, null, null, null); } + /** + * @deprecated Use {@link WeightedBlock.Builder} instead. + */ + @Deprecated public WeightedBlock( String id, Double weight, @@ -73,10 +91,18 @@ public WeightedBlock( this.excludedBiomes = excludedBiomes; } + /** + * @deprecated Use {@link WeightedBlock.Builder#of(Block)} instead. + */ + @Deprecated public static WeightedBlock fromBlock(Block block, Double weight) { return fromBlock(block, weight, null, null, null, null); } + /** + * @deprecated Use {@link WeightedBlock.Builder#of(Block)} instead. + */ + @Deprecated public static WeightedBlock fromBlock( Block block, Double weight, @@ -117,19 +143,30 @@ public Optional> getExcludedBiomes() { return Util.optional(excludedBiomes); } + public Optional> getNeighbours() { + return Util.optional(neighbours); + } + + public Optional getModifier() { + if (neighbours == null) return Util.optional(null); + return Util.optional(neighbours[0]); + } + @Override public void toPacket(FriendlyByteBuf buf) { buf.writeUtf(id); buf.writeDouble(weight); - buf.writeOptional(Util.optional(dimensions), (o, value) -> o.writeCollection(value, FriendlyByteBuf::writeUtf)); - buf.writeOptional(Util.optional(excludedDimensions), (o, value) -> o.writeCollection(value, FriendlyByteBuf::writeUtf)); + buf.writeOptional(getDimensions(), (o, value) -> o.writeCollection(value, FriendlyByteBuf::writeUtf)); + buf.writeOptional(getExcludedDimensions(), (o, value) -> o.writeCollection(value, FriendlyByteBuf::writeUtf)); - buf.writeOptional(Util.optional(maxY), FriendlyByteBuf::writeInt); - buf.writeOptional(Util.optional(minY), FriendlyByteBuf::writeInt); + buf.writeOptional(getMaxY(), FriendlyByteBuf::writeInt); + buf.writeOptional(getMinY(), FriendlyByteBuf::writeInt); - buf.writeOptional(Util.optional(biomes), (o, value) -> o.writeCollection(value, FriendlyByteBuf::writeUtf)); - buf.writeOptional(Util.optional(excludedBiomes), (o, value) -> o.writeCollection(value, FriendlyByteBuf::writeUtf)); + buf.writeOptional(getBiomes(), (o, value) -> o.writeCollection(value, FriendlyByteBuf::writeUtf)); + buf.writeOptional(getExcludedBiomes(), (o, value) -> o.writeCollection(value, FriendlyByteBuf::writeUtf)); + + buf.writeOptional(getNeighbours(), (o, value) -> o.writeCollection(value, FriendlyByteBuf::writeUtf)); } public static WeightedBlock fromPacket(FriendlyByteBuf buf) { @@ -145,6 +182,8 @@ public static WeightedBlock fromPacket(FriendlyByteBuf buf) { Optional> biomes = buf.readOptional((o) -> o.readList(FriendlyByteBuf::readUtf)); Optional> excludedBiomes = buf.readOptional((o) -> o.readList(FriendlyByteBuf::readUtf)); + Optional> neighbours = buf.readOptional((o) -> o.readList(FriendlyByteBuf::readUtf)); + return new WeightedBlock( id, weight, @@ -152,7 +191,7 @@ public static WeightedBlock fromPacket(FriendlyByteBuf buf) { excludedDimensions.orElse(null), maxY.orElse(null), minY.orElse(null), - null, + neighbours.orElse(null), biomes.orElse(null), excludedBiomes.orElse(null) ); @@ -170,72 +209,177 @@ public JsonObject toJson() { json.put("minY", JANKSON.toJson(minY)); json.put("biomes", JANKSON.toJson(biomes)); json.put("excludedBiomes", JANKSON.toJson(excludedBiomes)); + if (neighbours != null) { + if (neighbours.size() > 1) + json.put("neighbours", JANKSON.toJson(neighbours)); + else + json.put("modifier", JANKSON.toJson(neighbours[0])); + } return json; } - @SuppressWarnings("PatternVariableCanBeUsed") @Deserializer public static WeightedBlock fromJson(JsonObject json) { + return fromJson(json, "1.1"); + } + + public static WeightedBlock fromJson(JsonObject json, String formatVersion) { + Builder builder = new WeightedBlock.Builder(); + JsonElement _id = json.get("id"); if (!(_id instanceof JsonPrimitive)) return null; - String id = ((JsonPrimitive) _id).asString(); - Double weight = json.getDouble("weight", 0.0); + builder.setId(((JsonPrimitive) _id).asString()); + builder.setWeight(json.getDouble("weight", 0.0)); - @Nullable - List dimensions; JsonElement _dimensions = json.get("dimensions"); if (_dimensions instanceof JsonArray) { - dimensions = new ArrayList<>(); + List dimensions = new ArrayList<>(); ((JsonArray) _dimensions).forEach(value -> dimensions.add(((JsonPrimitive) value).asString())); - } else { - dimensions = null; + builder.setDimensions(dimensions); } @Nullable - List excludedDimensions; JsonElement _excludedDimensions = json.get("excludedDimensions"); if (_excludedDimensions instanceof JsonArray) { - excludedDimensions = new ArrayList<>(); + List excludedDimensions = new ArrayList<>(); ((JsonArray) _excludedDimensions).forEach(value -> excludedDimensions.add(((JsonPrimitive) value).asString())); - } else { - excludedDimensions = null; + builder.setExcludedDimensions(excludedDimensions); } - @Nullable - Integer maxY = null; JsonElement _maxY = json.get("maxY"); if (_maxY instanceof JsonPrimitive) { - maxY = ((JsonPrimitive) _maxY).asInt(0); + builder.setMaxY(((JsonPrimitive) _maxY).asInt(0)); } - @Nullable - Integer minY = null; JsonElement _minY = json.get("minY"); if (_minY instanceof JsonPrimitive) { - minY = ((JsonPrimitive) _minY).asInt(0); + builder.setMinY(((JsonPrimitive) _minY).asInt(0)); } - @Nullable - List biomes; JsonElement _biomes = json.get("biomes"); if (_biomes instanceof JsonArray) { - biomes = new ArrayList<>(); + List biomes = new ArrayList<>(); ((JsonArray) _biomes).forEach(value -> biomes.add(((JsonPrimitive) value).asString())); - } else { - biomes = null; + builder.setBiomes(biomes); } - @Nullable - List excludedBiomes; JsonElement _excludedBiomes = json.get("excludedBiomes"); if (_excludedBiomes instanceof JsonArray) { - excludedBiomes = new ArrayList<>(); + List excludedBiomes = new ArrayList<>(); ((JsonArray) _excludedBiomes).forEach(value -> excludedBiomes.add(((JsonPrimitive) value).asString())); - } else { - excludedBiomes = null; + builder.setExcludedBiomes(excludedBiomes); + } + + if (formatVersion.equals("1.1")) { + JsonElement _neighbours = json.get("neighbours"); + if (_neighbours instanceof JsonArray) { + List neighbours = new ArrayList<>(); + ((JsonArray) _neighbours).forEach(value -> neighbours.add(((JsonPrimitive) value).asString())); + builder.setNeighbours(neighbours); + } + + if (_neighbours == null) { + JsonElement _modifier = json.get("modifier"); + if (_modifier instanceof JsonPrimitive) { + builder.setNeighbours(listOf(((JsonPrimitive) _modifier).asString())); + } + } } - return new WeightedBlock(id, weight, dimensions, excludedDimensions, maxY, minY, null, biomes, excludedBiomes); + return builder.build(); + } + + public static class Builder { + @Nullable + public String id; + @Nullable + public Double weight; + @Nullable + public List dimensions; + @Nullable + public List excludedDimensions; + @Nullable + public Integer maxY; + @Nullable + public Integer minY; + @Nullable + public List neighbours; + @Nullable + public List biomes; + @Nullable + public List excludedBiomes; + + public static Builder of(Block block) { + return new Builder().setId(Util.getBlockId(block).toString()); + } + + public WeightedBlock build() { + if (id == null && weight == null) { + throw new IllegalStateException("Block ID and generation weight can't be unset!"); + } + + return new WeightedBlock( + id, + weight, + dimensions, + excludedDimensions, + maxY, + minY, + neighbours, + biomes, + excludedBiomes + ); + } + + public Builder setId(String value) { + this.id = value; + return this; + } + + public Builder setWeight(Double value) { + this.weight = value; + return this; + } + + public Builder setDimensions(List value) { + this.dimensions = value; + return this; + } + + public Builder setExcludedDimensions(List value) { + this.excludedDimensions = value; + return this; + } + + public Builder setMaxY(Integer value) { + this.maxY = value; + return this; + } + + public Builder setMinY(Integer value) { + this.minY = value; + return this; + } + + public Builder setNeighbours(List value) { + this.neighbours = value; + return this; + } + + public Builder setModifier(String value) { + this.neighbours = listOf(value); + return this; + } + + public Builder setBiomes(List value) { + this.biomes = value; + return this; + } + + public Builder setExcludedBiomes(List value) { + this.excludedBiomes = value; + return this; + } } } diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/BasaltGenerator.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/BasaltGenerator.java index eb1436ee..20f63d81 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/BasaltGenerator.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/BasaltGenerator.java @@ -75,6 +75,11 @@ public boolean isSilent() { return silent; } + @Override + public boolean check(LevelAccessor level, BlockPos pos, BlockState state, boolean fromTop) { + return !fromTop; + } + @Override public Optional tryGenerate(LevelAccessor level, BlockPos pos, BlockState state, Direction direction) { BlockPos blockPos = pos.relative(direction.getOpposite()); @@ -102,4 +107,4 @@ public static Generator fromPacket(FriendlyByteBuf buf) { return new BasaltGenerator(outMap, block, silent); } -} \ No newline at end of file +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/CobbleGenerator.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/CobbleGenerator.java index a314cda3..48c21d99 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/CobbleGenerator.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/CobbleGenerator.java @@ -98,6 +98,11 @@ public boolean isSilent() { return silent; } + @Override + public boolean check(LevelAccessor level, BlockPos pos, BlockState state, boolean fromTop) { + return !fromTop; + } + @Override public Optional tryGenerate(LevelAccessor level, BlockPos pos, BlockState state, Direction direction) { BlockPos blockPos = pos.relative(direction.getOpposite()); @@ -139,4 +144,4 @@ public static Generator fromPacket(FriendlyByteBuf buf) { return new CobbleGenerator(outMap, fluid, silent, obiMap); } -} \ No newline at end of file +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/StoneGenerator.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/StoneGenerator.java index 9ee07be0..ad4f9bc8 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/StoneGenerator.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/generator/StoneGenerator.java @@ -57,7 +57,7 @@ public static StoneGenerator fromString(Map> possibl @Override public GeneratorMap getObsidianOutput() { - return GeneratorMap.of(Pair.of(CGIdentifier.wildcard(), ResultList.of(WeightedBlock.fromBlock(Blocks.STONE, 100D)))); + return GeneratorMap.of(Pair.of(CGIdentifier.wildcard(), ResultList.of(WeightedBlock.Builder.of(Blocks.STONE).setWeight(100D).build()))); } @Override @@ -119,4 +119,4 @@ public static Generator fromPacket(FriendlyByteBuf buf) { return new StoneGenerator(outMap, fluid, silent); } -} \ No newline at end of file +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/model/BuiltInGenerator.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/model/BuiltInGenerator.java index 334104dc..1a602633 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/model/BuiltInGenerator.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/model/BuiltInGenerator.java @@ -32,8 +32,8 @@ public interface BuiltInGenerator extends Generator #endif randomizeBlockId(Block key, String dim, Integer yLevel, GeneratorMap candidates, @Nullable String biome) { ResultList blockIds = candidates.getOrDefault( - CGIdentifier.fromMC(Util.getBlockId(key)), - candidates.getOrDefault(CGIdentifier.wildcard(), new ResultList()) + CGIdentifier.fromBlock(key), + candidates.getOrDefault(CGIdentifier.wildcard(), new ResultList()) ); ResultList filteredBlockIds = new ResultList(); @@ -58,7 +58,7 @@ public interface BuiltInGenerator extends Generator try { List taggedBlocks = Util.getTaggedBlockIds(ResourceLocation.tryParse(block.id.substring(1))); for (ResourceLocation taggedBlock : taggedBlocks) { - filteredBlockIds.add(new WeightedBlock(taggedBlock.toString(), block.weight)); + filteredBlockIds.add(new WeightedBlock.Builder().setId(taggedBlock.toString()).setWeight(block.weight).build()); totalWeight.updateAndGet(v -> v + block.weight); } } catch (Exception ignored) { diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/model/Generator.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/model/Generator.java index 9fd185cc..bd7722b8 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/data/model/Generator.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/data/model/Generator.java @@ -1,7 +1,6 @@ package io.github.null2264.cobblegen.data.model; #if MC>=12005 -import io.github.null2264.cobblegen.data.model.Generator; import io.netty.buffer.ByteBuf; #endif @@ -24,6 +23,7 @@ import java.lang.reflect.Method; import java.util.Optional; +// TODO: Simplify this interface to make it truly a public API public interface Generator extends PacketSerializable { #if MC>=12005 diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/BlockGenerationTest.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/BlockGenerationTest.java index e01dad4d..14614ebd 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/BlockGenerationTest.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/BlockGenerationTest.java @@ -56,6 +56,7 @@ * -> Intercepted by CobbleGen's mixin -> Gated by -Dnull2264.cobblegen.gametest=true * -> BlockGenerationTest.registerInstances(...) */ +// TODO: Test modifiers public class BlockGenerationTest { public static final CGIdentifier TEMPLATE = CGIdentifier.of("empty"); public static final Integer TIMEOUT_TICKS = 120; @@ -183,8 +184,7 @@ public void cobbleGenerationTest(GameTestHelper context) { BlockPos generatedPos = new BlockPos(1, 2, 3); context.succeedWhen( () -> { - // A special config is needed for this test - context.assertBlockPresent(Blocks.BEDROCK, generatedPos); + context.assertBlockPresent(Blocks.COBBLED_DEEPSLATE, generatedPos); } ); } @@ -220,8 +220,7 @@ public void basaltGenerationTest(GameTestHelper context) { BlockPos generatedPos = new BlockPos(1, 2, 3); context.succeedWhen( () -> { - // A special config is needed for this test - context.assertBlockPresent(Blocks.BEDROCK, generatedPos); + context.assertBlockPresent(Blocks.BLACKSTONE, generatedPos); } ); } @@ -269,8 +268,7 @@ public void stoneGenerationTest(GameTestHelper context) { BlockPos generatedPos = new BlockPos(1, 1, 1); context.succeedWhen( () -> { - // A special config is needed for this test - context.assertBlockPresent(Blocks.BEDROCK, generatedPos); + context.assertBlockPresent(Blocks.DEEPSLATE, generatedPos); } ); } diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/CobbleGenTestConfig.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/CobbleGenTestConfig.java new file mode 100644 index 00000000..e6449aef --- /dev/null +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/CobbleGenTestConfig.java @@ -0,0 +1,13 @@ +package io.github.null2264.cobblegen.gametest; + +import io.github.null2264.cobblegen.util.Util; + +// NOTE: Do NOT use Minecraft related stuff here! +public class CobbleGenTestConfig { + public static final boolean ENABLED = Boolean.parse( + System.getProperty( + "null2264.cobblegen.gametest", + Util.elvis(System.getenv("ENABLE_NULL2264_COBBLEGEN_GAMETEST"), "false") + ) + ); +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/CobbleGenTestLoader.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/CobbleGenTestLoader.java index 69f43863..8b726653 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/CobbleGenTestLoader.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/gametest/CobbleGenTestLoader.java @@ -2,6 +2,7 @@ package io.github.null2264.cobblegen.gametest; import io.github.null2264.cobblegen.util.CGLog; +import io.github.null2264.cobblegen.util.Util; import net.minecraft.gametest.framework.GameTestHelper; import net.minecraft.gametest.framework.TestFunctionLoader; import net.minecraft.resources.ResourceKey; @@ -14,26 +15,10 @@ public class CobbleGenTestLoader extends TestFunctionLoader { private static final AtomicBoolean SHOULD_REGISTER = new AtomicBoolean(true); - public static final boolean ENABLED = boolFromString( - System.getProperty("null2264.cobblegen.gametest", System.getenv("ENABLE_NULL2264_COBBLEGEN_GAMETEST")) - ); - - private static boolean boolFromString(String string) { - if (string == null) return false; - - List yes = List.of("yes", "y", "true", "t", "1", "enable", "on"); - List no = List.of("no", "n", "false", "f", "0", "disable", "off"); - - if (yes.contains(string.toLowerCase())) return true; - else if (no.contains(string.toLowerCase())) return false; - - // We supposed to throw an exception here, but we'll fallback to false instead - return false; - } public static void init() { - CGLog.info(() -> "Is CobbleGen GameTest enabled: " + ENABLED); - if (ENABLED && SHOULD_REGISTER.getAndSet(false)) + CGLog.info(() -> "Is CobbleGen GameTest enabled: " + CobbleGenTestConfig.ENABLED); + if (CobbleGenTestConfig.ENABLED && SHOULD_REGISTER.getAndSet(false)) TestFunctionLoader.registerLoader(new CobbleGenTestLoader()); } diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/BuiltInPlugin.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/BuiltInPlugin.java index d2b4c6a7..85f5c8e6 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/BuiltInPlugin.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/BuiltInPlugin.java @@ -4,6 +4,7 @@ import io.github.null2264.cobblegen.CobbleGenPlugin; import io.github.null2264.cobblegen.compat.LoaderCompat; import io.github.null2264.cobblegen.data.CGIdentifier; +import io.github.null2264.cobblegen.data.config.Config; import io.github.null2264.cobblegen.data.config.ConfigData; import io.github.null2264.cobblegen.data.config.GeneratorMap; import io.github.null2264.cobblegen.data.config.ResultList; @@ -23,16 +24,15 @@ import java.io.File; import java.nio.file.Path; -import java.util.Optional; import java.util.concurrent.atomic.AtomicInteger; import static io.github.null2264.cobblegen.CobbleGen.MOD_ID; -import static io.github.null2264.cobblegen.data.config.ConfigHelper.loadConfig; -import static io.github.null2264.cobblegen.util.Util.notNullOr; +import static io.github.null2264.cobblegen.util.Util.elvis; @CGPlugin public class BuiltInPlugin implements CobbleGenPlugin { + private static final Config.Factory factory = new ConfigData.Factory(); private static final Path configPath = LoaderCompat.getConfigDir(); private static final File configFile = new File(configPath + File.separator + MOD_ID + ".json5"); @Nullable @@ -61,24 +61,30 @@ private Block getBlockFromString(String string) { @Override public void registerInteraction(CGRegistry registry) { CGLog.info((!isReload ? "L" : "Rel") + "oading config..."); - if (config == null || isReload) config = loadConfig(isReload, configFile, config, ConfigData.defaultConfig(), ConfigData.class); + if (config == null || isReload) config = isReload ? factory.reload(configFile) : factory.load(configFile); if (config == null) throw new RuntimeException("How?"); AtomicInteger count = new AtomicInteger(); GeneratorMap stoneGen = new GeneratorMap(); - if (config.customGen != null && config.customGen.stoneGen != null) - stoneGen = config.customGen.stoneGen; GeneratorMap cobbleGen = new GeneratorMap(); - if (config.customGen != null && config.customGen.cobbleGen != null) - cobbleGen = config.customGen.cobbleGen; GeneratorMap basaltGen = new GeneratorMap(); - if (config.customGen != null && config.customGen.basaltGen != null) - basaltGen = config.customGen.basaltGen; - stoneGen.put(CGIdentifier.wildcard(), notNullOr(config.stoneGen, new ResultList())); - cobbleGen.put(CGIdentifier.wildcard(), notNullOr(config.cobbleGen, new ResultList())); - basaltGen.put(CGIdentifier.fromBlock(Blocks.SOUL_SOIL), notNullOr(config.basaltGen, new ResultList())); + elvis(config.stoneGen, new ResultList()) + .forEach(result -> { + CGIdentifier id = CGIdentifier.of(result.getModifier().orElse("*")); + stoneGen.computeIfAbsent(id, r -> new ResultList()).add(result); + }); + elvis(config.cobbleGen, new ResultList()) + .forEach(result -> { + CGIdentifier id = CGIdentifier.of(result.getModifier().orElse("*")); + cobbleGen.computeIfAbsent(id, r -> new ResultList()).add(result); + }); + elvis(config.basaltGen, new ResultList()) + .forEach(result -> { + CGIdentifier id = result.getModifier().map(CGIdentifier::of).orElseGet(() -> CGIdentifier.fromBlock(Blocks.SOUL_SOIL)); + basaltGen.computeIfAbsent(id, r -> new ResultList()).add(result); + }); if (config.advanced != null) config.advanced.forEach((fluid, value) -> { @@ -141,4 +147,4 @@ public void onReload() { CGLog.info("Reloading built-in plugin..."); isReload = true; } -} \ No newline at end of file +} diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/CreatePlugin.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/CreatePlugin.java index 0865594a..f6ad49c6 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/CreatePlugin.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/CreatePlugin.java @@ -25,7 +25,9 @@ public void registerInteraction(CGRegistry registry) { registry.addGenerator( Fluids.LAVA, new CobbleGenerator( - ResultList.of(WeightedBlock.fromBlock(Util.getBlock(Util.identifierOf("create", "limestone")), 1.0)), + ResultList.of( + WeightedBlock.Builder.of(Util.getBlock(Util.identifierOf("create", "limestone"))).setWeight(1.0).build() + ), Util.getFluid(Util.identifierOf("create", "honey")), false ) @@ -33,7 +35,9 @@ public void registerInteraction(CGRegistry registry) { registry.addGenerator( Fluids.LAVA, new CobbleGenerator( - ResultList.of(WeightedBlock.fromBlock(Util.getBlock(Util.identifierOf("create", "scoria")), 1.0)), + ResultList.of( + WeightedBlock.Builder.of(Util.getBlock(Util.identifierOf("create", "scoria"))).setWeight(1.0).build() + ), Util.getFluid(Util.identifierOf("create", "chocolate")), false ) diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/emi/CGEMIPlugin.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/emi/CGEMIPlugin.java index 8bfdb39a..aa7cfaae 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/emi/CGEMIPlugin.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/emi/CGEMIPlugin.java @@ -101,11 +101,11 @@ public void register(EmiRegistry registry) { registry.addRecipe( new FluidInteractionRecipe( fluid, - Util.notNullOr(generator.getFluid(), Fluids.EMPTY), - Util.notNullOr(generator.getBlock(), Blocks.AIR), + Util.elvis(generator.getFluid(), Fluids.EMPTY), + Util.elvis(generator.getBlock(), Blocks.AIR), block, generator.getType(), - Util.notNullOr(modifier, Blocks.AIR) + Util.elvis(modifier, Blocks.AIR) ) ); }))); diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/jei/CGJEIPlugin.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/jei/CGJEIPlugin.java index a5561339..160b3af7 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/jei/CGJEIPlugin.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/jei/CGJEIPlugin.java @@ -63,11 +63,11 @@ public void registerRecipes(IRecipeRegistration registration) { recipes.add( new FluidInteractionRecipeHolder( fluid, - Util.notNullOr(generator.getFluid(), Fluids.EMPTY), - Util.notNullOr(generator.getBlock(), Blocks.AIR), + Util.elvis(generator.getFluid(), Fluids.EMPTY), + Util.elvis(generator.getBlock(), Blocks.AIR), block, generator.getType(), - Util.notNullOr(modifier, Blocks.AIR) + Util.elvis(modifier, Blocks.AIR) ) ); registration.addRecipes(new RecipeType<>( diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/rei/CGREIPlugin.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/rei/CGREIPlugin.java index 960b54dc..c3aad6a4 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/rei/CGREIPlugin.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/integration/viewer/rei/CGREIPlugin.java @@ -44,11 +44,11 @@ public void registerDisplays(DisplayRegistry registry) { registry.add( new FluidInteractionRecipe( fluid, - Util.notNullOr(generator.getFluid(), Fluids.EMPTY), - Util.notNullOr(generator.getBlock(), Blocks.AIR), + Util.elvis(generator.getFluid(), Fluids.EMPTY), + Util.elvis(generator.getBlock(), Blocks.AIR), block, generator.getType(), - Util.notNullOr(modifier, Blocks.AIR) + Util.elvis(modifier, Blocks.AIR) ) ); }))); diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/mixin/core/CobbleGenMixinPlugin.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/mixin/core/CobbleGenMixinPlugin.java index feb43bcd..7b3cfb56 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/mixin/core/CobbleGenMixinPlugin.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/mixin/core/CobbleGenMixinPlugin.java @@ -91,7 +91,7 @@ public boolean shouldApplyMixin(String targetClassName, String mixinClassName) { } #if MC>=12105 - if (mixinClassName.endsWith("$GameTest") && io.github.null2264.cobblegen.gametest.CobbleGenTestLoader.ENABLED) { + if (mixinClassName.endsWith("$GameTest") && io.github.null2264.cobblegen.gametest.CobbleGenTestConfig.ENABLED) { // Datapack will not register automatically in Fabric without FAPI. // I usually prefer not depending on FAPI, but I'll make this one an exception... // because I ain't dealing with Resource Pack loading ever again diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/util/PluginFinder.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/util/PluginFinder.java index 205e3114..2a5c2c33 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/util/PluginFinder.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/util/PluginFinder.java @@ -5,8 +5,6 @@ import java.util.*; -import static io.github.null2264.cobblegen.compat.CollectionCompat.streamToList; - #if FABRIC import net.fabricmc.loader.api.FabricLoader; #else @@ -28,12 +26,11 @@ public class PluginFinder { public static List getModPlugins() { #if FABRIC - return streamToList( - FabricLoader.getInstance() - .getEntrypointContainers("cobblegen_plugin", CobbleGenPlugin.class) - .stream() - .map(entrypoint -> new PlugInContainer(entrypoint.getProvider().getMetadata().getId(), entrypoint.getEntrypoint())) - ); + return FabricLoader.getInstance() + .getEntrypointContainers("cobblegen_plugin", CobbleGenPlugin.class) + .stream() + .map(entrypoint -> new PlugInContainer(entrypoint.getProvider().getMetadata().getId(), entrypoint.getEntrypoint())) + .toList(); #else return AnnotatedFinder.getInstances(CGPlugin.class, CobbleGenPlugin.class); #endif @@ -46,11 +43,10 @@ public static List getInstances(Class annotationClass, C List allScanData = ModList.get().getAllScanData(); List instances = new ArrayList<>(); for (ModFileScanData data : allScanData) { - List modIds = streamToList( - data.getIModInfoData().stream() - .flatMap(info -> info.getMods().stream()) - .map(IModInfo::getModId) - ); + List modIds = data.getIModInfoData().stream() + .flatMap(info -> info.getMods().stream()) + .map(IModInfo::getModId) + .toList(); String modId = "[" + String.join(", ", modIds) + "]"; Iterable annotations = data.getAnnotations(); diff --git a/cobblegen/src/main/java/io/github/null2264/cobblegen/util/Util.java b/cobblegen/src/main/java/io/github/null2264/cobblegen/util/Util.java index 84f9c7ea..12bcd156 100644 --- a/cobblegen/src/main/java/io/github/null2264/cobblegen/util/Util.java +++ b/cobblegen/src/main/java/io/github/null2264/cobblegen/util/Util.java @@ -3,7 +3,6 @@ import io.github.null2264.cobblegen.compat.LoaderCompat; import io.github.null2264.cobblegen.compat.RegistryCompat; import net.minecraft.core.BlockPos; -import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -15,7 +14,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.NoSuchElementException; import java.util.Optional; import static io.github.null2264.cobblegen.CobbleGen.MOD_ID; @@ -47,7 +45,7 @@ public static ResourceLocation identifierOf(String namespace, String id) { } @NotNull - public static T notNullOr(@Nullable T nullable, @NotNull T notNull) { + public static T elvis(@Nullable T nullable, @NotNull T notNull) { if (nullable == null) return notNull; return nullable; @@ -100,7 +98,7 @@ public static List getTaggedBlockIds(ResourceLocation tagId) { #if MC>11605 final TagKey blockTag = TagKey.create( #if MC<=11902 - Registry.BLOCK_REGISTRY, + net.minecraft.core.Registry.BLOCK_REGISTRY, #else net.minecraft.core.registries.Registries.BLOCK, #endif @@ -147,7 +145,7 @@ public static String getDimension(LevelAccessor level) { .registryOrThrow( #endif #if MC<=11902 - Registry.DIMENSION_TYPE_REGISTRY + net.minecraft.core.Registry.DIMENSION_TYPE_REGISTRY #else net.minecraft.core.registries.Registries.DIMENSION_TYPE #endif @@ -170,7 +168,7 @@ public static String getBiome(LevelAccessor level, BlockPos position) { .registryOrThrow( #endif #if MC<=11902 - Registry.BIOME_REGISTRY + net.minecraft.core.Registry.BIOME_REGISTRY #else net.minecraft.core.registries.Registries.BIOME #endif diff --git a/mclib/src/main/java/io/github/null2264/cobblegen/extensions/java/lang/Boolean/BooleanExt.java b/mclib/src/main/java/io/github/null2264/cobblegen/extensions/java/lang/Boolean/BooleanExt.java new file mode 100644 index 00000000..d0e9cbdc --- /dev/null +++ b/mclib/src/main/java/io/github/null2264/cobblegen/extensions/java/lang/Boolean/BooleanExt.java @@ -0,0 +1,19 @@ +package io.github.null2264.cobblegen.extensions.java.lang.Boolean; + +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; + +@manifold.ext.rt.api.Extension +public final class BooleanExt { + @manifold.ext.rt.api.Extension + public static boolean parse(@Nullable String string) { + if (string == null) return false; + + String[] yes = {"yes", "y", "true", "t", "1", "enable", "on"}; + //String[] no = {"no", "n", "false", "f", "0", "disable", "off"}; + + return Arrays.asList(yes).contains(string.toLowerCase()); + //else if (Arrays.asList(no).contains(string.toLowerCase())) return false; + } +} diff --git a/mclib/src/main/java/io/github/null2264/cobblegen/extensions/java/util/List/ListExt.java b/mclib/src/main/java/io/github/null2264/cobblegen/extensions/java/util/List/ListExt.java new file mode 100644 index 00000000..0b498fb4 --- /dev/null +++ b/mclib/src/main/java/io/github/null2264/cobblegen/extensions/java/util/List/ListExt.java @@ -0,0 +1,19 @@ +package io.github.null2264.cobblegen.extensions.java.util.List; + +#if MC<11700 +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +#endif + +@manifold.ext.rt.api.Extension +public final class ListExt { + + #if MC<11700 + @manifold.ext.rt.api.Extension + @SafeVarargs + public static List of(T... items) { + return new ArrayList<>(Arrays.asList(items)); + } + #endif +} diff --git a/mclib/src/main/java/io/github/null2264/cobblegen/extensions/java/util/stream/Stream/StreamExt.java b/mclib/src/main/java/io/github/null2264/cobblegen/extensions/java/util/stream/Stream/StreamExt.java new file mode 100644 index 00000000..0f37ca9c --- /dev/null +++ b/mclib/src/main/java/io/github/null2264/cobblegen/extensions/java/util/stream/Stream/StreamExt.java @@ -0,0 +1,23 @@ +package io.github.null2264.cobblegen.extensions.java.util.stream.Stream; + +import manifold.ext.rt.api.Extension; + +#if MC<11700 +import manifold.ext.rt.api.This; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Stream; +#endif + +@Extension +public final class StreamExt { + + #if MC<11700 + @SuppressWarnings("unchecked") + public static List toList(@This Stream stream) { + return (List) Collections.unmodifiableList(new ArrayList<>(Arrays.asList(stream.toArray()))); + } + #endif +}