diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/CustomCubicMod.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/CustomCubicMod.java index d09d94a..b0be707 100644 --- a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/CustomCubicMod.java +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/CustomCubicMod.java @@ -32,7 +32,6 @@ import io.github.opencubicchunks.cubicchunks.cubicgen.common.biome.replacer.SwampWaterWithLilypadReplacer; import io.github.opencubicchunks.cubicchunks.cubicgen.common.biome.replacer.TaigaSurfaceReplacer; import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.CustomCubicWorldType; -import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.CustomGeneratorSettings; import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.populator.DefaultDecorator; import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.populator.DesertDecorator; import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.populator.ForestDecorator; @@ -43,6 +42,7 @@ import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.populator.SwampDecorator; import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.populator.TaigaDecorator; import io.github.opencubicchunks.cubicchunks.cubicgen.flat.FlatCubicWorldType; +import io.github.opencubicchunks.cubicchunks.cubicgen.proxy.CommonProxy; import mcp.MethodsReturnNonnullByDefault; import net.minecraft.util.ResourceLocation; import net.minecraft.world.biome.Biome; @@ -63,10 +63,9 @@ import net.minecraft.world.biome.BiomeStoneBeach; import net.minecraft.world.biome.BiomeSwamp; import net.minecraft.world.biome.BiomeTaiga; -import net.minecraftforge.common.util.ModFixs; import net.minecraftforge.event.RegistryEvent; -import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; @@ -93,6 +92,10 @@ public class CustomCubicMod { public static final int FIXER_VERSION = 2; public static final boolean DEBUG_ENABLED = false; public static Logger LOGGER = null; + + @SidedProxy(clientSide = "io.github.opencubicchunks.cubicchunks.cubicgen.proxy.ClientProxy", serverSide = "io.github.opencubicchunks.cubicchunks.cubicgen.proxy.ServerProxy") + public static CommonProxy proxy; + @Mod.EventHandler public void preInit(FMLPreInitializationEvent e) { @@ -102,10 +105,7 @@ public void preInit(FMLPreInitializationEvent e) { FlatCubicWorldType.create(); CustomCubicWorldType.create(); DebugWorldType.create(); - - - ModFixs fixes = FMLCommonHandler.instance().getDataFixer().init(MODID, FIXER_VERSION); - CustomGeneratorSettings.registerDataFixers(fixes); + proxy.preInit(); } @Mod.EventHandler diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/common/gui/GuiEventHandler.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/common/gui/GuiEventHandler.java new file mode 100644 index 0000000..f40c6c6 --- /dev/null +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/common/gui/GuiEventHandler.java @@ -0,0 +1,68 @@ +/* + * This file is part of Cubic World Generation, licensed under the MIT License (MIT). + * + * Copyright (c) 2015 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.opencubicchunks.cubicchunks.cubicgen.common.gui; + +import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.CustomCubicWorldType; +import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.CustomGeneratorSettings; +import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.gui.CustomCubicGui; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiListWorldSelectionEntry; +import net.minecraft.client.gui.GuiWorldSelection; +import net.minecraft.world.storage.ISaveHandler; +import net.minecraft.world.storage.WorldInfo; +import net.minecraftforge.client.event.GuiScreenEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +/** + * This GUI handler serve a sole purpose to copy CustomCubic generator settings + * in case if player making a copy of such world + */ +public class GuiEventHandler { + + @SubscribeEvent + public void onButtonPressed(GuiScreenEvent.ActionPerformedEvent.Pre action) { + if (action.getGui() instanceof GuiWorldSelection) { + if (!action.getButton().enabled) + return; + // "Recreate world" has button id = 5 + if (action.getButton().id != 5) + return; + GuiWorldSelection gui = (GuiWorldSelection) action.getGui(); + if (gui.selectionList.getSelectedWorld() == null) + return; + GuiListWorldSelectionEntry entry = gui.selectionList.getSelectedWorld(); + ISaveHandler isavehandler = Minecraft.getMinecraft().getSaveLoader() + .getSaveLoader(entry.worldSummary.getFileName(), false); + WorldInfo worldinfo = isavehandler.loadWorldInfo(); + + if (worldinfo == null || !(worldinfo.getTerrainType() instanceof CustomCubicWorldType)) + return; + String json = CustomGeneratorSettings.loadJsonStringFromSaveFolder(isavehandler); + isavehandler.flush(); + if (json != null) { + CustomCubicWorldType.pendingCustomCubicSettingsJsonString = json; + } + } + } +} diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomCubicWorldType.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomCubicWorldType.java index 7ebe582..07993c8 100644 --- a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomCubicWorldType.java +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomCubicWorldType.java @@ -33,9 +33,7 @@ import net.minecraft.client.gui.GuiCreateWorld; import net.minecraft.client.gui.GuiErrorScreen; import net.minecraft.init.Biomes; -import net.minecraft.world.DimensionType; import net.minecraft.world.World; -import net.minecraft.world.WorldProvider; import net.minecraft.world.WorldProviderSurface; import net.minecraft.world.WorldServer; import net.minecraft.world.WorldType; @@ -56,6 +54,11 @@ @MethodsReturnNonnullByDefault public class CustomCubicWorldType extends WorldType implements ICubicWorldType { + // This string is not empty when and only when someone used a CustomCubicGUI + // and press a Done button both in this CustomCubicGUI and in a WorldCreationGUI + public static String pendingCustomCubicSettingsJsonString = ""; + public static boolean createNewWorld = false; + private CustomCubicWorldType() { super("CustomCubic"); } @@ -65,8 +68,7 @@ public static CustomCubicWorldType create() { } @Override public IntRange calculateGenerationHeightRange(WorldServer world) { - String string = world.getWorldInfo().getGeneratorOptions(); - CustomGeneratorSettings opts = CustomGeneratorSettings.fromJson(string); + CustomGeneratorSettings opts = CustomGeneratorSettings.load(world); // TODO: better handling of min height return new IntRange(0, (int) opts.actualHeight); } @@ -94,6 +96,11 @@ public ICubeGenerator createCubeGenerator(World world) { public boolean isCustomizable() { return true; } + + @Override + public void onGUICreateWorldPress() { + createNewWorld = true; + } @SideOnly(Side.CLIENT) public void onCustomizeButton(Minecraft mc, GuiCreateWorld guiCreateWorld) { diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomGeneratorSettings.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomGeneratorSettings.java index 5578fbb..498c131 100644 --- a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomGeneratorSettings.java +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomGeneratorSettings.java @@ -25,7 +25,23 @@ import static io.github.opencubicchunks.cubicchunks.cubicgen.CustomCubicMod.MODID; -import com.google.common.base.Objects; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.nio.CharBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.Nullable; + import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.JsonArray; @@ -39,7 +55,7 @@ import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializer; import com.google.gson.JsonSyntaxException; -import com.google.gson.stream.JsonReader; + import io.github.opencubicchunks.cubicchunks.api.world.ICube; import io.github.opencubicchunks.cubicchunks.cubicgen.ConversionUtils; import io.github.opencubicchunks.cubicchunks.cubicgen.CustomCubicMod; @@ -54,26 +70,11 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTUtil; import net.minecraft.util.ResourceLocation; -import net.minecraft.util.datafix.FixTypes; -import net.minecraft.util.datafix.IFixableData; +import net.minecraft.world.World; import net.minecraft.world.biome.Biome; -import net.minecraft.world.gen.ChunkGeneratorSettings; -import net.minecraftforge.common.util.ModFixs; +import net.minecraft.world.storage.ISaveHandler; import net.minecraftforge.fml.common.registry.ForgeRegistries; -import java.io.StringReader; -import java.lang.reflect.Field; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.annotation.Nullable; - public class CustomGeneratorSettings { /** * Note: many of these values are unused yet @@ -174,6 +175,7 @@ public class CustomGeneratorSettings { public BiomeBlockReplacerConfig replacerConfig = BiomeBlockReplacerConfig.defaults(); // TODO: public boolean negativeHeightVariationInvertsTerrain = true; + public int version = CustomGeneratorSettingsFixer.VERSION; public CustomGeneratorSettings() { } @@ -185,17 +187,84 @@ public BiomeBlockReplacerConfig createBiomeBlockReplacerConfig() { return replacerConfig; } - public String toJson(boolean minimize) { - Gson gson = gson(minimize); + public String toJson() { + Gson gson = gson(); return gson.toJson(this); } + + public static boolean isOutdated(String settingsJsonString) { + JsonObject root = CustomGeneratorSettingsFixer.stringToJson(settingsJsonString); + return !root.has("version") || root.get("version").getAsInt() != CustomGeneratorSettingsFixer.VERSION; + } - public static CustomGeneratorSettings fromJson(String json) { - if (json.isEmpty()) { + public static CustomGeneratorSettings fromJson(String jsonString) { + if (jsonString.isEmpty()) { return defaults(); } - Gson gson = gson(true); // minimize option shouldn't matter when deserializing - return gson.fromJson(json, CustomGeneratorSettings.class); + if (isOutdated(jsonString)) { + jsonString = CustomGeneratorSettingsFixer.fixGeneratorOptions(jsonString, null); + } + Gson gson = gson(); + return gson.fromJson(jsonString, CustomGeneratorSettings.class); + } + + @Nullable + public static String loadJsonStringFromSaveFolder(ISaveHandler saveHandler) { + File externalGeneratorPresetFile = getPresetFile(saveHandler); + if (externalGeneratorPresetFile.exists()) { + try (FileReader reader = new FileReader(externalGeneratorPresetFile)){ + CharBuffer sb = CharBuffer.allocate((int) externalGeneratorPresetFile.length()); + reader.read(sb); + sb.flip(); + return sb.toString(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return null; + } + + public static File getPresetFile(ISaveHandler saveHandler) { + return new File(saveHandler.getWorldDirectory(), + "/data/" + CustomCubicMod.MODID + "/custom_generator_settings.json"); + } + + public static CustomGeneratorSettings load(World world) { + String jsonString = loadJsonStringFromSaveFolder(world.getSaveHandler()); + CustomGeneratorSettings settings = null; + if (jsonString != null) { + boolean isOutdated = isOutdated(jsonString); + settings = fromJson(jsonString); + if (isOutdated) + settings.save(world); + } else if (CustomCubicWorldType.createNewWorld && !CustomCubicWorldType.pendingCustomCubicSettingsJsonString.isEmpty()) { + settings = CustomGeneratorSettings.fromJson(CustomCubicWorldType.pendingCustomCubicSettingsJsonString); + CustomCubicWorldType.pendingCustomCubicSettingsJsonString = ""; + CustomCubicWorldType.createNewWorld = false; + settings.save(world); + } else { + CustomCubicMod.LOGGER + .info("No settings provided at " + getPresetFile(world.getSaveHandler()).getAbsolutePath()); + CustomCubicMod.LOGGER.info("Loading settings from 'level.dat'"); + // Use old format to keep backward-compatibility + settings = fromJson(world.getWorldInfo().getGeneratorOptions()); + settings.save(world); + } + return settings; + } + + public void save(World world) { + File folder = new File(world.getSaveHandler().getWorldDirectory(), "/data/" + CustomCubicMod.MODID +"/"); + folder.mkdirs(); + File settingsFile = new File(folder, "custom_generator_settings.json"); + try (FileWriter writer = new FileWriter(settingsFile)) { + writer.write(this.toJson()); + CustomCubicMod.LOGGER.info("Generator settings saved at " + settingsFile.getAbsolutePath()); + } catch (IOException e) { + CustomCubicMod.LOGGER.error("Cannot create new directory at " + folder.getAbsolutePath()); + CustomCubicMod.LOGGER.error(this.toJson()); + CustomCubicMod.LOGGER.catching(e); + } } public static CustomGeneratorSettings defaults() { @@ -277,280 +346,20 @@ public static CustomGeneratorSettings defaults() { return settings; } - public static CustomGeneratorSettings fromVanilla(ChunkGeneratorSettings settings) { - CustomGeneratorSettings obj = defaults(); - - obj.lowNoiseFactor = 512.0f / settings.lowerLimitScale; - obj.highNoiseFactor = 512.0f / settings.upperLimitScale; - - obj.depthNoiseFrequencyX = ConversionUtils.frequencyFromVanilla(settings.depthNoiseScaleX, 16); - obj.depthNoiseFrequencyZ = ConversionUtils.frequencyFromVanilla(settings.depthNoiseScaleZ, 16); - // settings.depthNoiseScaleExponent is ignored by vanilla - - obj.selectorNoiseFrequencyX = ConversionUtils.frequencyFromVanilla(settings.coordinateScale / settings.mainNoiseScaleX, 8); - obj.selectorNoiseFrequencyY = ConversionUtils.frequencyFromVanilla(settings.heightScale / settings.mainNoiseScaleY, 8); - obj.selectorNoiseFrequencyZ = ConversionUtils.frequencyFromVanilla(settings.coordinateScale / settings.mainNoiseScaleZ, 8); - - obj.lowNoiseFrequencyX = ConversionUtils.frequencyFromVanilla(settings.coordinateScale, 16); - obj.lowNoiseFrequencyY = ConversionUtils.frequencyFromVanilla(settings.heightScale, 16); - obj.lowNoiseFrequencyZ = ConversionUtils.frequencyFromVanilla(settings.coordinateScale, 16); - - obj.highNoiseFrequencyX = ConversionUtils.frequencyFromVanilla(settings.coordinateScale, 16); - obj.highNoiseFrequencyY = ConversionUtils.frequencyFromVanilla(settings.heightScale, 16); - obj.highNoiseFrequencyZ = ConversionUtils.frequencyFromVanilla(settings.coordinateScale, 16); - - return obj; - } - - public static void registerDataFixers(ModFixs fixes) { - // TODO: redo data fixers - - fixes.registerFix(FixTypes.LEVEL, new IFixableData() { - @Override public int getFixVersion() { - return 0; - } - - @Override public NBTTagCompound fixTagCompound(NBTTagCompound compound) { - if (!compound.getString("generatorName").equals("CustomCubic")) { - return compound; - } - String generatorOptions = compound.getString("generatorOptions"); - if (generatorOptions.isEmpty()) { - generatorOptions = new CustomGeneratorSettings().toJson(false); - } - Gson gson = gson(false); - - JsonReader reader = new JsonReader(new StringReader(generatorOptions)); - JsonObject root = new JsonParser().parse(reader).getAsJsonObject(); - - // some old saves are broken, especially 1.11.2 ones from the 1.12.2->1.11.2 backport, build 847 - // this preserves the existing ores - JsonArray standardOres = - root.has("standardOres") ? root.getAsJsonArray("standardOres") : new JsonArray(); - JsonArray periodicGaussianOres = - root.has("periodicGaussianOres") ? - root.getAsJsonArray("periodicGaussianOres") : new JsonArray(); - - - // kind of ugly but I don'twant to make a special class just so store these 3 objects... - String[] standard = { - "dirt", - "gravel", - "granite", - "diorite", - "andesite", - "coalOre", - "ironOre", - "goldOre", - "redstoneOre", - "diamondOre", - "hillsEmeraldOre", - "hillsSilverfishStone", - "mesaAddedGoldOre" - }; - IBlockState[] standardBlockstates = { - Blocks.DIRT.getDefaultState(), - Blocks.GRAVEL.getDefaultState(), - Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.GRANITE), - Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.DIORITE), - Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.ANDESITE), - Blocks.COAL_ORE.getDefaultState(), - Blocks.IRON_ORE.getDefaultState(), - Blocks.GOLD_ORE.getDefaultState(), - Blocks.REDSTONE_ORE.getDefaultState(), - Blocks.DIAMOND_ORE.getDefaultState(), - Blocks.EMERALD_ORE.getDefaultState(), - Blocks.MONSTER_EGG.getDefaultState().withProperty(BlockSilverfish.VARIANT, BlockSilverfish.EnumType.STONE), - Blocks.GOLD_ORE.getDefaultState() - }; - Biome[][] standardBiomes = { - null, // dirt - null, // gravel - null, // granite - null, // diorite - null, // andesite - null, // coal - null, // iron - null, // gold - null, // redstone - null, // diamond - {Biomes.EXTREME_HILLS, Biomes.EXTREME_HILLS_EDGE, Biomes.EXTREME_HILLS_WITH_TREES, Biomes.MUTATED_EXTREME_HILLS, - Biomes.MUTATED_EXTREME_HILLS_WITH_TREES},//emerald - {Biomes.EXTREME_HILLS, Biomes.EXTREME_HILLS_EDGE, Biomes.EXTREME_HILLS_WITH_TREES, Biomes.MUTATED_EXTREME_HILLS, - Biomes.MUTATED_EXTREME_HILLS_WITH_TREES},//monster egg - {Biomes.MESA, Biomes.MESA_CLEAR_ROCK, Biomes.MESA_ROCK, Biomes.MUTATED_MESA, Biomes.MUTATED_MESA_CLEAR_ROCK, - Biomes.MUTATED_MESA_ROCK},//mesa gold - }; - for (int i = 0; i < standard.length; i++) { - JsonObject obj = convertStandardOre(gson, root, standard[i], standardBlockstates[i], standardBiomes[i]); - if (obj != null) { - standardOres.add(obj); - } - - } - JsonObject lapis = convertGaussianPeriodicOre(gson, root, "lapisLazuli", Blocks.LAPIS_ORE.getDefaultState(), null); - if (lapis != null) { - periodicGaussianOres.add(lapis); - } - root.add("standardOres", standardOres); - root.add("periodicGaussianOres", periodicGaussianOres); - compound.setString("generatorOptions", gson.toJson(root)); - return compound; - } - - private JsonObject convertStandardOre(Gson gson, JsonObject root, String ore, IBlockState state, Biome[] biomes) { - if (!root.has(ore + "SpawnTries")) { - // some old saves are broken, especially 1.11.2 ones from the 1.12.2->1.11.2 backport, build 847 - // this avoids adding a lot of air ores - return null; - } - - JsonObject obj = new JsonObject(); - obj.add("blockstate", gson.toJsonTree(state)); - if (biomes != null) { - obj.add("biomes", gson.toJsonTree(biomes)); - } - if (root.has(ore + "SpawnSize")) { - obj.add("spawnSize", root.remove(ore + "SpawnSize")); - } else { - // emerald doesn't have size defined in the old format - obj.add("spawnSize", new JsonPrimitive(3)); - } - obj.add("spawnTries", root.remove(ore + "SpawnTries")); - obj.add("spawnProbability", root.remove(ore + "SpawnProbability")); - obj.add("minHeight", root.remove(ore + "SpawnMinHeight")); - obj.add("maxHeight", root.remove(ore + "SpawnMaxHeight")); - return obj; - } - - private JsonObject convertGaussianPeriodicOre(Gson gson, JsonObject root, String ore, IBlockState state, Biome[] biomes) { - JsonObject obj = convertStandardOre(gson, root, ore, state, biomes); - if (obj == null) { - return null; - } - obj.add("heightMean", root.remove(ore + "HeightMean")); - obj.add("heightStdDeviation", root.remove(ore + "HeightStdDeviation")); - obj.add("heightSpacing", root.remove(ore + "HeightSpacing")); - return obj; - } - }); - - fixes.registerFix(FixTypes.LEVEL, new IFixableData() { - @Override public int getFixVersion() { - return 1; - } - - @Override public NBTTagCompound fixTagCompound(NBTTagCompound compound) { - if (!compound.getString("generatorName").equals("CustomCubic")) { - return compound; - } - String generatorOptions = compound.getString("generatorOptions"); - if (generatorOptions.isEmpty()) { - generatorOptions = new CustomGeneratorSettings().toJson(false); - } - Gson gson = gson(false); - - JsonReader reader = new JsonReader(new StringReader(generatorOptions)); - JsonObject root = new JsonParser().parse(reader).getAsJsonObject(); - - float heightVariationOffset = root.get("heightVariationOffset").getAsFloat(); - float offset = root.get("heightOffset").getAsFloat(); - float factor = root.get("heightFactor").getAsFloat(); - if (!root.has("expectedBaseHeight")) { - root.add("expectedBaseHeight", root.get("heightOffset")); - } - if (!root.has("expectedHeightVariation")) { - root.add("expectedHeightVariation", root.get("heightFactor")); - } - if (!root.has("actualHeight")) { - root.add("actualHeight", new JsonPrimitive( - (offset + heightVariationOffset + - Math.max(factor * 2 + heightVariationOffset, factor + heightVariationOffset * 2)) - )); - } - if (!root.has("cubeAreas")) { - root.add("cubeAreas", new JsonObject()); - } - if (!root.has("replacerConfig")) { - JsonObject replacerConf = new JsonObject(); - { - JsonObject defaults = new JsonObject(); - { - defaults.add(MODID + ":horizontal_gradient_depth_decrease_weight", new JsonPrimitive(1.0f)); - defaults.add(MODID + ":height_offset", new JsonPrimitive(offset)); - JsonObject terrainfill = new JsonObject(); - { - JsonObject properties = new JsonObject(); - properties.add("variant", new JsonPrimitive("stone")); - terrainfill.add("Properties", properties); - terrainfill.add("Name", new JsonPrimitive("minecraft:stone")); - } - JsonObject oceanblock = new JsonObject(); - - { - JsonObject properties = new JsonObject(); - properties.add("level", new JsonPrimitive("0")); - oceanblock.add("Properties", properties); - oceanblock.add("Name", new JsonPrimitive("minecraft:water")); - } - defaults.add(MODID + ":biome_fill_depth_offset", new JsonPrimitive(3.0f)); - defaults.add(MODID + ":biome_fill_noise_octaves", new JsonPrimitive(4.0f)); - defaults.add(MODID + ":height_scale", new JsonPrimitive(factor)); - defaults.add(MODID + ":biome_fill_depth_factor", new JsonPrimitive(2.3333333333333335f)); - defaults.add(MODID + ":mesa_depth", new JsonPrimitive(16.0f)); - defaults.add(MODID + ":water_level", root.get("waterLevel")); - defaults.add(MODID + ":biome_fill_noise_freq", new JsonPrimitive(0.0078125f)); - } - replacerConf.add("defaults", defaults); - replacerConf.add("overrides", new JsonObject()); - } - - root.add("replacerConfig", replacerConf); - } - compound.setString("generatorOptions", gson.toJson(root)); - return compound; - } - }); - - - fixes.registerFix(FixTypes.LEVEL, new IFixableData() { - @Override public int getFixVersion() { - return 2; - } - - @Override public NBTTagCompound fixTagCompound(NBTTagCompound compound) { - if (!compound.getString("generatorName").equals("CustomCubic")) { - return compound; - } - String generatorOptions = compound.getString("generatorOptions"); - if (generatorOptions.isEmpty()) { - generatorOptions = new CustomGeneratorSettings().toJson(true); - } - // this is far simpler that walking through the json and figurring out all the places where it occurs - // instead, just do string search and replace. The string shouldn't occur in any other context - compound.setString("generatorOptions", generatorOptions.replaceAll(MODID + ":", MODID + ":")); - return compound; - } - }); - } - - public static Gson gson(boolean minimize) { - return new GsonBuilder().serializeSpecialFloatingPointValues() - .enableComplexMapKeySerialization() - .registerTypeAdapter(CustomGeneratorSettings.class, new Serializer(minimize)) - .registerTypeHierarchyAdapter(IBlockState.class, BlockStateSerializer.INSTANCE) - .registerTypeHierarchyAdapter(Biome.class, new BiomeSerializer()) - .registerTypeAdapter(BiomeBlockReplacerConfig.class, new BiomeBlockReplacerConfigSerializer(minimize)) - .create(); + public static Gson gson() { + return gsonBuilder().create(); } - public static GsonBuilder gsonBuilder(boolean minimize) { - return new GsonBuilder().serializeSpecialFloatingPointValues() - .enableComplexMapKeySerialization() - .registerTypeAdapter(CustomGeneratorSettings.class, new Serializer(minimize)) - .registerTypeHierarchyAdapter(IBlockState.class, BlockStateSerializer.INSTANCE) - .registerTypeHierarchyAdapter(Biome.class, new BiomeSerializer()) - .registerTypeAdapter(BiomeBlockReplacerConfig.class, new BiomeBlockReplacerConfigSerializer(minimize)); + public static GsonBuilder gsonBuilder() { + GsonBuilder builder = new GsonBuilder(); + builder.setPrettyPrinting(); + builder.serializeSpecialFloatingPointValues(); + builder.enableComplexMapKeySerialization(); + builder.registerTypeAdapter(CustomGeneratorSettings.class, new Serializer()); + builder.registerTypeHierarchyAdapter(IBlockState.class, BlockStateSerializer.INSTANCE); + builder.registerTypeHierarchyAdapter(Biome.class, new BiomeSerializer()); + builder.registerTypeAdapter(BiomeBlockReplacerConfig.class, new BiomeBlockReplacerConfigSerializer()); + return builder; } public static class StandardOreConfig { @@ -591,7 +400,6 @@ public static class Builder { private float spawnProbability; private float minHeight = Float.NEGATIVE_INFINITY; private float maxHeight = Float.POSITIVE_INFINITY; - private Set blockstates = new HashSet<>(); public Builder block(IBlockState blockstate) { this.blockstate = blockstate; @@ -817,11 +625,6 @@ private static class Serializer implements JsonDeserializer entry : src.cubeAreas.entrySet()) { @@ -928,12 +727,6 @@ private static class BlockStateSerializer implements JsonDeserializer, JsonSerializer { - private final boolean minimize; - - public BiomeBlockReplacerConfigSerializer(boolean minimize) { - this.minimize = minimize; - } - @Override public BiomeBlockReplacerConfig deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { @@ -968,19 +761,13 @@ private Object getObject(JsonDeserializationContext context, Map.Entry e : src.getDefaults().entrySet()) { - if (minimize && Objects.equal(defaultValues.getValue(e.getKey()), e.getValue())) { - continue; - } defaults.add(e.getKey().toString(), getJsonElement(context, e)); } for (Map.Entry e : src.getOverrides().entrySet()) { - // don't "minimize" overrides overrides.add(e.getKey().toString(), getJsonElement(context, e)); } root.add("defaults", defaults); diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomGeneratorSettingsFixer.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomGeneratorSettingsFixer.java new file mode 100644 index 0000000..7661d5b --- /dev/null +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomGeneratorSettingsFixer.java @@ -0,0 +1,513 @@ +/* + * This file is part of Cubic World Generation, licensed under the MIT License (MIT). + * + * Copyright (c) 2015 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.opencubicchunks.cubicchunks.cubicgen.customcubic; + +import static io.github.opencubicchunks.cubicchunks.cubicgen.CustomCubicMod.MODID; + +import java.io.StringReader; + +import javax.annotation.Nullable; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import com.google.gson.stream.JsonReader; + +import net.minecraft.block.BlockSilverfish; +import net.minecraft.block.BlockStone; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Biomes; +import net.minecraft.init.Blocks; +import net.minecraft.world.biome.Biome; + +public class CustomGeneratorSettingsFixer { + + public static final int VERSION = 3; + + private static final String[] standard = { "dirt", "gravel", "granite", "diorite", "andesite", "coalOre", "ironOre", + "goldOre", "redstoneOre", "diamondOre", "hillsEmeraldOre", "hillsSilverfishStone", "mesaAddedGoldOre" }; + + private static final IBlockState[] standardBlockstates = { Blocks.DIRT.getDefaultState(), + Blocks.GRAVEL.getDefaultState(), + Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.GRANITE), + Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.DIORITE), + Blocks.STONE.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.ANDESITE), + Blocks.COAL_ORE.getDefaultState(), Blocks.IRON_ORE.getDefaultState(), Blocks.GOLD_ORE.getDefaultState(), + Blocks.REDSTONE_ORE.getDefaultState(), Blocks.DIAMOND_ORE.getDefaultState(), + Blocks.EMERALD_ORE.getDefaultState(), + Blocks.MONSTER_EGG.getDefaultState().withProperty(BlockSilverfish.VARIANT, BlockSilverfish.EnumType.STONE), + Blocks.GOLD_ORE.getDefaultState() }; + private static final Biome[][] standardBiomes = { null, // dirt + null, // gravel + null, // granite + null, // diorite + null, // andesite + null, // coal + null, // iron + null, // gold + null, // redstone + null, // diamond + { Biomes.EXTREME_HILLS, Biomes.EXTREME_HILLS_EDGE, Biomes.EXTREME_HILLS_WITH_TREES, + Biomes.MUTATED_EXTREME_HILLS, Biomes.MUTATED_EXTREME_HILLS_WITH_TREES }, // emerald + { Biomes.EXTREME_HILLS, Biomes.EXTREME_HILLS_EDGE, Biomes.EXTREME_HILLS_WITH_TREES, + Biomes.MUTATED_EXTREME_HILLS, Biomes.MUTATED_EXTREME_HILLS_WITH_TREES }, // monster + // egg + { Biomes.MESA, Biomes.MESA_CLEAR_ROCK, Biomes.MESA_ROCK, Biomes.MUTATED_MESA, + Biomes.MUTATED_MESA_CLEAR_ROCK, Biomes.MUTATED_MESA_ROCK },// mesa + // gold + }; + + private static boolean isActual(JsonObject root) { + return root.has("version") && root.get("version").getAsInt() == 3; + } + + public static String fixGeneratorOptions(String json, @Nullable JsonObject parent) { + Gson gson = CustomGeneratorSettings.gson(); + JsonObject oldRoot = CustomGeneratorSettingsFixer.stringToJson(json); + boolean rootIsActual = isActual(oldRoot); + if (rootIsActual) { + if (parent != null) { + return json; + } else { + boolean cubeAreasHasOutdatedContent = false; + if (oldRoot.has("cubeAreas") && oldRoot.get("cubeAreas").isJsonArray()) { + JsonArray array = oldRoot.get("cubeAreas").getAsJsonArray(); + for (JsonElement entry : array) { + JsonArray mapEntry = entry.getAsJsonArray(); + JsonObject value = mapEntry.get(1).getAsJsonObject(); + if (!isActual(value)) { + cubeAreasHasOutdatedContent = true; + break; + } + } + } + if (!cubeAreasHasOutdatedContent) { + // Do not touch anything if all data is OK + return json; + } + } + } + JsonObject newRoot = stringToJson("{}"); + newRoot.add("version", new JsonPrimitive(3)); + newRoot.add("waterLevel", getWaterLevel(oldRoot,parent)); + newRoot.add("caves", getCaves(oldRoot,parent)); + newRoot.add("strongholds", getStrongholds(oldRoot,parent)); + newRoot.add("alternateStrongholdsPositions", getAlternateStrongholdsPositions(oldRoot,parent)); + newRoot.add("villages", getVillages(oldRoot,parent)); + newRoot.add("mineshafts", getMineshafts(oldRoot,parent)); + newRoot.add("temples", getTemples(oldRoot,parent)); + newRoot.add("oceanMonuments", getOceanMonuments(oldRoot,parent)); + newRoot.add("woodlandMansions", getWoodlandMansions(oldRoot,parent)); + newRoot.add("ravines", getRavines(oldRoot,parent)); + newRoot.add("dungeons", getDungeons(oldRoot,parent)); + newRoot.add("dungeonCount", getDungeonCount(oldRoot,parent)); + newRoot.add("waterLakes", getWaterLakes(oldRoot,parent)); + newRoot.add("waterLakeRarity", getWaterLakeRarity(oldRoot,parent)); + newRoot.add("lavaLakes", getLavaLakes(oldRoot,parent)); + newRoot.add("lavaLakeRarity", getLavaLakeRarity(oldRoot,parent)); + newRoot.add("aboveSeaLavaLakeRarity", getAboveSeaLavaLakeRarity(oldRoot,parent)); + newRoot.add("lavaOceans", getLavaOceans(oldRoot,parent)); + newRoot.add("biome", getBiome(oldRoot,parent)); + newRoot.add("biomeSize", getBiomeSize(oldRoot,parent)); + newRoot.add("riverSize", getRiverSize(oldRoot,parent)); + newRoot.add("standardOres", getStandardOres(oldRoot,parent)); + newRoot.add("periodicGaussianOres", getPeriodicGaussianOres(oldRoot,parent)); + newRoot.add("expectedBaseHeight", getExpectedBaseHeight(oldRoot,parent)); + newRoot.add("expectedHeightVariation", getExpectedHeightVariation(oldRoot,parent)); + newRoot.add("actualHeight", getActualHeight(oldRoot,parent)); + newRoot.add("heightVariationFactor", getHeightVariationFactor(oldRoot,parent)); + newRoot.add("specialHeightVariationFactorBelowAverageY", getSpecialHeightVariationFactorBelowAverageY(oldRoot,parent)); + newRoot.add("heightVariationOffset", getHeightVariationOffset(oldRoot,parent)); + newRoot.add("heightFactor", getHeightFactor(oldRoot,parent)); + newRoot.add("heightOffset", getHeightOffset(oldRoot,parent)); + newRoot.add("depthNoiseFactor", getDepthNoiseFactor(oldRoot,parent)); + newRoot.add("depthNoiseOffset", getDepthNoiseOffset(oldRoot,parent)); + newRoot.add("depthNoiseFrequencyX", getDepthNoiseFrequencyX(oldRoot,parent)); + newRoot.add("depthNoiseFrequencyZ", getDepthNoiseFrequencyZ(oldRoot,parent)); + newRoot.add("depthNoiseOctaves", getDepthNoiseOctaves(oldRoot,parent)); + newRoot.add("selectorNoiseFactor", getSelectorNoiseFactor(oldRoot,parent)); + newRoot.add("selectorNoiseOffset", getSelectorNoiseOffset(oldRoot,parent)); + newRoot.add("selectorNoiseFrequencyX", getSelectorNoiseFrequencyX(oldRoot,parent)); + newRoot.add("selectorNoiseFrequencyY", getSelectorNoiseFrequencyY(oldRoot,parent)); + newRoot.add("selectorNoiseFrequencyZ", getSelectorNoiseFrequencyZ(oldRoot,parent)); + newRoot.add("selectorNoiseOctaves", getSelectorNoiseOctaves(oldRoot,parent)); + newRoot.add("lowNoiseFactor", getLowNoiseFactor(oldRoot,parent)); + newRoot.add("lowNoiseOffset", getLowNoiseOffset(oldRoot,parent)); + newRoot.add("lowNoiseFrequencyX", getLowNoiseFrequencyX(oldRoot,parent)); + newRoot.add("lowNoiseFrequencyY", getLowNoiseFrequencyY(oldRoot,parent)); + newRoot.add("lowNoiseFrequencyZ", getLowNoiseFrequencyZ(oldRoot,parent)); + newRoot.add("lowNoiseOctaves", getLowNoiseOctaves(oldRoot,parent)); + newRoot.add("highNoiseFactor", getHighNoiseFactor(oldRoot,parent)); + newRoot.add("highNoiseOffset", getHighNoiseOffset(oldRoot,parent)); + newRoot.add("highNoiseFrequencyX", getHighNoiseFrequencyX(oldRoot,parent)); + newRoot.add("highNoiseFrequencyY", getHighNoiseFrequencyY(oldRoot,parent)); + newRoot.add("highNoiseFrequencyZ", getHighNoiseFrequencyZ(oldRoot,parent)); + newRoot.add("highNoiseOctaves", getHighNoiseOctaves(oldRoot,parent)); + newRoot.add("replacerConfig", getReplacerConfig(oldRoot,parent)); + if (parent == null) // cube areas allowed only for root + newRoot.add("cubeAreas", getCubeAreas(oldRoot)); + + String newGeneratorOptions = gson.toJson(newRoot).replaceAll("cubicchunks:", MODID + ":"); + return newGeneratorOptions; + } + + private static JsonElement getReplacerConfig(JsonObject json, @Nullable JsonObject parent) { + JsonReader reader = new JsonReader(new StringReader("{\"defaults\":{\"cubicgen:biome_fill_noise_octaves\":4.0,\"cubicgen:ocean_block\":{\"Properties\":{\"level\":\"0\"},\"Name\":\"minecraft:water\"},\"cubicgen:height_scale\":64.0,\"cubicgen:biome_fill_noise_freq\":0.0078125,\"cubicgen:water_level\":63.0,\"cubicgen:biome_fill_depth_factor\":2.3333333333333335,\"cubicgen:terrain_fill_block\":{\"Properties\":{\"variant\":\"stone\"},\"Name\":\"minecraft:stone\"},\"cubicgen:mesa_depth\":16.0,\"cubicgen:biome_fill_depth_offset\":3.0,\"cubicgen:horizontal_gradient_depth_decrease_weight\":1.0,\"cubicgen:height_offset\":64.0},\"overrides\":{}}")); + JsonObject biomeBlockReplacerConfigDefaultJson = new JsonParser().parse(reader).getAsJsonObject(); + return getOrDefault(json, parent, "replacerConfig", biomeBlockReplacerConfigDefaultJson); + } + + private static JsonElement getCubeAreas(JsonObject json) { + JsonArray cubeAreas = new JsonArray(); + if (json.has("cubeAreas") && json.get("cubeAreas").isJsonArray()) { + JsonArray array = json.get("cubeAreas").getAsJsonArray(); + for (JsonElement entry : array) { + JsonArray mapEntry = entry.getAsJsonArray(); + JsonElement key = mapEntry.get(0); + JsonObject value = stringToJson(fixGeneratorOptions(CustomGeneratorSettings.gson().toJson(mapEntry.get(1).getAsJsonObject()), json)); + JsonArray newEntry = new JsonArray(); + newEntry.add(key); + newEntry.add(value); + cubeAreas.add(newEntry); + } + } + return cubeAreas; + } + + private static JsonElement getHighNoiseOctaves(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "highNoiseOctaves", new JsonPrimitive(16)); + } + + private static JsonElement getHighNoiseFrequencyZ(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "highNoiseFrequencyZ", + new JsonPrimitive(0.005221649)); + } + + private static JsonElement getHighNoiseFrequencyY(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "highNoiseFrequencyY", + new JsonPrimitive(0.0026108245)); + } + + private static JsonElement getHighNoiseFrequencyX(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "highNoiseFrequencyX", + new JsonPrimitive(0.005221649)); + } + + private static JsonElement getHighNoiseOffset(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "highNoiseOffset", new JsonPrimitive(0)); + } + + private static JsonElement getHighNoiseFactor(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "highNoiseFactor", new JsonPrimitive(1)); + } + + private static JsonElement getLowNoiseFrequencyZ(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "lowNoiseFrequencyZ", + new JsonPrimitive(0.005221649)); + } + + private static JsonElement getLowNoiseFrequencyY(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "lowNoiseFrequencyY", + new JsonPrimitive(0.0026108245)); + } + + private static JsonElement getLowNoiseFrequencyX(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "lowNoiseFrequencyX", + new JsonPrimitive(0.005221649)); + } + + private static JsonElement getLowNoiseOffset(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "lowNoiseOffset", new JsonPrimitive(0)); + } + + private static JsonElement getLowNoiseFactor(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "lowNoiseFactor", new JsonPrimitive(1)); + } + + private static JsonElement getLowNoiseOctaves(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "lowNoiseOctaves", new JsonPrimitive(16)); + } + + private static JsonElement getSelectorNoiseOctaves(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "selectorNoiseOctaves", new JsonPrimitive(8)); + } + + private static JsonElement getSelectorNoiseFrequencyZ(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "selectorNoiseFrequencyZ", + new JsonPrimitive(0.016709277)); + } + + private static JsonElement getSelectorNoiseFrequencyX(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "selectorNoiseFrequencyX", + new JsonPrimitive(0.016709277)); + } + + private static JsonElement getSelectorNoiseFrequencyY(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "selectorNoiseFrequencyY", + new JsonPrimitive(0.008354639)); + } + + private static JsonElement getSelectorNoiseOffset(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "selectorNoiseOffset", + new JsonPrimitive(0.5)); + } + + private static JsonElement getSelectorNoiseFactor(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "selectorNoiseFactor", + new JsonPrimitive(12.75)); + } + + private static JsonElement getDepthNoiseOctaves(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "depthNoiseOctaves", new JsonPrimitive(16)); + } + + private static JsonElement getDepthNoiseFrequencyZ(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "depthNoiseFrequencyZ", + new JsonPrimitive(0.0015258789)); + } + + private static JsonElement getDepthNoiseFrequencyX(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "depthNoiseFrequencyX", + new JsonPrimitive(0.0015258789)); + } + + private static JsonElement getDepthNoiseOffset(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "depthNoiseOffset", new JsonPrimitive(0)); + } + + private static JsonElement getDepthNoiseFactor(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "depthNoiseFactor", new JsonPrimitive(1.024)); + } + + private static JsonElement getHeightOffset(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "heightOffset", new JsonPrimitive(64)); + } + + private static JsonElement getHeightFactor(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "heightFactor", new JsonPrimitive(64)); + } + + private static JsonElement getHeightVariationOffset(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "heightVariationOffset", new JsonPrimitive(0)); + } + + private static JsonElement getSpecialHeightVariationFactorBelowAverageY(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "specialHeightVariationFactorBelowAverageY", new JsonPrimitive(0.25f)); + } + + private static JsonElement getHeightVariationFactor(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "heightVariationFactor", new JsonPrimitive(64)); + } + + private static JsonElement getActualHeight(JsonObject json, @Nullable JsonObject parent) { + if (json.has("heightOffset") && json.has("heightVariationOffset") && json.has("heightFactor")) { + float heightVariationOffset = json.get("heightVariationOffset").getAsFloat(); + float offset = json.get("heightOffset").getAsFloat(); + float factor = json.get("heightFactor").getAsFloat(); + return getOrDefault(json, parent, "actualHeight", new JsonPrimitive((offset + heightVariationOffset + + Math.max(factor * 2 + heightVariationOffset, factor + heightVariationOffset * 2)))); + } + return getOrDefault(json, parent, "actualHeight", new JsonPrimitive(64)); + } + + private static JsonElement getExpectedBaseHeight(JsonObject json, @Nullable JsonObject parent) { + if (json.has("expectedBaseHeight")) + return json.get("expectedBaseHeight"); + return getOrDefault(json, parent, "heightOffset", new JsonPrimitive(64)); + } + + private static JsonElement getExpectedHeightVariation(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "expectedHeightVariation", getOrDefault(json, parent, "heightFactor", new JsonPrimitive(64))); + } + + private static JsonElement getPeriodicGaussianOres(JsonObject oldRoot, JsonObject parent) { + if (oldRoot.has("periodicGaussianOres")) + return oldRoot.get("periodicGaussianOres"); + if (parent != null && parent.has("periodicGaussianOres")) + return parent.get("periodicGaussianOres"); + Gson gson = CustomGeneratorSettings.gson(); + JsonArray periodicGaussianOres = new JsonArray(); + JsonObject obj = convertGaussianPeriodicOre(gson, oldRoot, "lapisLazuli", Blocks.LAPIS_ORE.getDefaultState(), + null); + if (obj != null) { + periodicGaussianOres.add(obj); + } + return periodicGaussianOres; + } + + private static JsonElement getStandardOres(JsonObject oldRoot, JsonObject parent) { + if (oldRoot.has("standardOres")) + return oldRoot.get("standardOres"); + if (parent != null && parent.has("standardOres")) + return parent.get("standardOres"); + Gson gson = CustomGeneratorSettings.gson(); + JsonArray standardOres = new JsonArray(); + for (int i = 0; i < standard.length; i++) { + JsonObject obj = convertStandardOre(gson, oldRoot, standard[i], standardBlockstates[i], standardBiomes[i]); + if (obj != null) { + standardOres.add(obj); + } + } + return standardOres; + } + + private static JsonElement getRiverSize(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "riverSize", new JsonPrimitive(4)); + } + + private static JsonElement getBiomeSize(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "biomeSize", new JsonPrimitive(4)); + } + + private static JsonElement getBiome(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "biome", new JsonPrimitive(-1)); + } + + private static JsonElement getLavaOceans(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "lavaOceans", new JsonPrimitive(false)); + } + + private static JsonElement getAboveSeaLavaLakeRarity(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "aboveSeaLavaLakeRarity", new JsonPrimitive(13)); + } + + private static JsonElement getLavaLakeRarity(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "lavaLakeRarity", new JsonPrimitive(8)); + } + + private static JsonElement getLavaLakes(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "lavaLakes", new JsonPrimitive(true)); + } + + private static JsonElement getWaterLakeRarity(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "waterLakeRarity", new JsonPrimitive(4)); + } + + private static JsonElement getWaterLakes(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "waterLakes", new JsonPrimitive(true)); + } + + private static JsonElement getDungeonCount(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "dungeonCount", new JsonPrimitive(7)); + } + + private static JsonElement getDungeons(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "dungeons", new JsonPrimitive(true)); + } + + private static JsonElement getRavines(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "ravines", new JsonPrimitive(true)); + } + + private static JsonElement getWoodlandMansions(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "woodlandMansions", new JsonPrimitive(true)); + } + + private static JsonElement getOceanMonuments(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "oceanMonuments", new JsonPrimitive(true)); + } + + private static JsonElement getTemples(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "temples", new JsonPrimitive(true)); + } + + private static JsonElement getMineshafts(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "mineshafts", new JsonPrimitive(true)); + } + + private static JsonElement getVillages(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "villages", new JsonPrimitive(true)); + } + + private static JsonElement getAlternateStrongholdsPositions(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "alternateStrongholdsPositions", new JsonPrimitive(false)); + } + + private static JsonElement getStrongholds(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "strongholds", new JsonPrimitive(true)); + } + + private static JsonElement getCaves(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "caves", new JsonPrimitive(true)); + } + + private static JsonElement getWaterLevel(JsonObject json, @Nullable JsonObject parent) { + return getOrDefault(json, parent, "waterLevel", new JsonPrimitive(63)); + } + + private static JsonElement getOrDefault(JsonObject source, @Nullable JsonObject parent, String name, JsonElement jsonElement) { + if (source.has(name)) + return source.get(name); + if (parent != null && parent.has(name)) + return parent.get(name); + return jsonElement; + } + + private static JsonObject convertStandardOre(Gson gson, JsonObject root, String ore, IBlockState state, + Biome[] biomes) { + if (!root.has(ore + "SpawnTries")) { + // some old saves are broken, especially 1.11.2 ones from the + // 1.12.2->1.11.2 backport, build 847 + // this avoids adding a lot of air ores + return null; + } + + JsonObject obj = new JsonObject(); + obj.add("blockstate", gson.toJsonTree(state)); + if (biomes != null) { + obj.add("biomes", gson.toJsonTree(biomes)); + } + if (root.has(ore + "SpawnSize")) { + obj.add("spawnSize", root.remove(ore + "SpawnSize")); + } else { + // emerald doesn't have size defined in the old format + obj.add("spawnSize", new JsonPrimitive(3)); + } + obj.add("spawnTries", root.remove(ore + "SpawnTries")); + obj.add("spawnProbability", root.remove(ore + "SpawnProbability")); + obj.add("minHeight", root.remove(ore + "SpawnMinHeight")); + obj.add("maxHeight", root.remove(ore + "SpawnMaxHeight")); + return obj; + } + + private static JsonObject convertGaussianPeriodicOre(Gson gson, JsonObject root, String ore, IBlockState state, + Biome[] biomes) { + JsonObject obj = convertStandardOre(gson, root, ore, state, biomes); + if (obj == null) { + return null; + } + obj.add("heightMean", root.remove(ore + "HeightMean")); + obj.add("heightStdDeviation", root.remove(ore + "HeightStdDeviation")); + obj.add("heightSpacing", root.remove(ore + "HeightSpacing")); + return obj; + } + + public static JsonObject stringToJson(String jsonString) { + JsonReader reader = new JsonReader(new StringReader(jsonString)); + return new JsonParser().parse(reader).getAsJsonObject(); + } +} diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomTerrainGenerator.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomTerrainGenerator.java index db8137e..22bea6b 100644 --- a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomTerrainGenerator.java +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/CustomTerrainGenerator.java @@ -92,7 +92,7 @@ public class CustomTerrainGenerator extends BasicCubeGenerator { @Nonnull private CubicFeatureGenerator strongholds; public CustomTerrainGenerator(World world, final long seed) { - this(world, CustomGeneratorSettings.fromJson(world.getWorldInfo().getGeneratorOptions()), seed); + this(world, CustomGeneratorSettings.load(world), seed); } public CustomTerrainGenerator(World world, CustomGeneratorSettings settings, final long seed) { diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/gui/CustomCubicGui.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/gui/CustomCubicGui.java index 53b1c13..67b47e4 100644 --- a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/gui/CustomCubicGui.java +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/customcubic/gui/CustomCubicGui.java @@ -28,22 +28,19 @@ import com.google.common.eventbus.Subscribe; import com.google.gson.JsonSyntaxException; -import io.github.opencubicchunks.cubicchunks.cubicgen.CustomCubicMod; import io.github.opencubicchunks.cubicchunks.cubicgen.common.biome.BiomeBlockReplacerConfig; import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.ExtraGui; -import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.MalisisGuiUtils; import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.component.UISplitLayout; import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.component.UITextFieldFixed; +import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.CustomCubicWorldType; import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.CustomGeneratorSettings; import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.component.NoTranslationFont; import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.component.UIBorderLayout; import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.component.UIColoredPanel; import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.component.UIMultilineLabel; import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.component.UITabbedContainer; -import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.component.UIVerticalTableLayout; import mcp.MethodsReturnNonnullByDefault; import net.malisis.core.client.gui.Anchor; -import net.malisis.core.client.gui.GuiTexture; import net.malisis.core.client.gui.MalisisGui; import net.malisis.core.client.gui.component.UIComponent; import net.malisis.core.client.gui.component.container.UIContainer; @@ -53,8 +50,6 @@ import net.malisis.core.renderer.font.FontOptions; import net.minecraft.client.gui.GuiCreateWorld; import net.minecraft.client.resources.I18n; -import net.minecraft.util.ResourceLocation; - import java.util.Map; import javax.annotation.ParametersAreNonnullByDefault; @@ -93,7 +88,11 @@ public CustomCubicGui(GuiCreateWorld parent) { */ @Override public void construct() { - CustomGeneratorSettings conf = CustomGeneratorSettings.fromJson(parent.chunkProviderSettingsJson); + CustomGeneratorSettings conf = null; + if (!CustomCubicWorldType.pendingCustomCubicSettingsJsonString.isEmpty()) + conf = CustomGeneratorSettings.fromJson(CustomCubicWorldType.pendingCustomCubicSettingsJsonString); + else + conf = CustomGeneratorSettings.defaults(); reinit(conf); } @@ -192,7 +191,7 @@ public void onChange(ComponentEvent.ValueChange event) { public void onChange(ComponentEvent.ValueChange event) { try { CustomGeneratorSettings settings = CustomGeneratorSettings.fromJson(event.getNewValue()); - textMinified.setText(getSettingsJson(settings, true)); + textMinified.setText(getSettingsJson(settings)); } catch (JsonSyntaxException | NumberFormatException ex) { textMinified.setText(I18n.format("cubicgen.gui.cubicgen.presets.invalid_json")); } @@ -207,7 +206,7 @@ public void onChange(ComponentEvent.ValueChange event) { // textField, making the text invisible by default textMinified.setSize(this.width - HORIZONTAL_PADDING*2, 10); textMinified.setFont(NoTranslationFont.DEFAULT); - textMinified.setText(getSettingsJson(getConfig(), true)); + textMinified.setText(getSettingsJson(getConfig())); textMinified.getCursorPosition().jumpToEnd(); done.register(new Object() { @@ -252,7 +251,7 @@ public void onClick(UIButton.ClickEvent evt) { } private void done() { - parent.chunkProviderSettingsJson = getSettingsJson(getConfig(), true); + CustomCubicWorldType.pendingCustomCubicSettingsJsonString = getSettingsJson(getConfig()); this.mc.displayGuiScreen(parent); } @@ -267,11 +266,11 @@ public CustomGeneratorSettings getConfig() { return conf; } - String getSettingsJson(CustomGeneratorSettings conf, boolean minimized) { - return conf.toJson(minimized); + String getSettingsJson(CustomGeneratorSettings conf) { + return conf.toJson(); } String getFormattedJson(CustomGeneratorSettings conf) { - return CustomGeneratorSettings.gsonBuilder(false).setPrettyPrinting().create().toJson(conf); + return CustomGeneratorSettings.gsonBuilder().setPrettyPrinting().create().toJson(conf); } } diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/proxy/ClientProxy.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/proxy/ClientProxy.java new file mode 100644 index 0000000..8a41761 --- /dev/null +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/proxy/ClientProxy.java @@ -0,0 +1,35 @@ +/* + * This file is part of Cubic World Generation, licensed under the MIT License (MIT). + * + * Copyright (c) 2015 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.opencubicchunks.cubicchunks.cubicgen.proxy; + +import io.github.opencubicchunks.cubicchunks.cubicgen.common.gui.GuiEventHandler; +import net.minecraftforge.common.MinecraftForge; + +public class ClientProxy extends CommonProxy { + + @Override + public void preInit() { + MinecraftForge.EVENT_BUS.register(new GuiEventHandler()); + } +} diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/proxy/CommonProxy.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/proxy/CommonProxy.java new file mode 100644 index 0000000..c3afebf --- /dev/null +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/proxy/CommonProxy.java @@ -0,0 +1,29 @@ +/* + * This file is part of Cubic World Generation, licensed under the MIT License (MIT). + * + * Copyright (c) 2015 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.opencubicchunks.cubicchunks.cubicgen.proxy; + +public class CommonProxy { + + public void preInit() {} +} diff --git a/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/proxy/ServerProxy.java b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/proxy/ServerProxy.java new file mode 100644 index 0000000..dad53d9 --- /dev/null +++ b/src/main/java/io/github/opencubicchunks/cubicchunks/cubicgen/proxy/ServerProxy.java @@ -0,0 +1,28 @@ +/* + * This file is part of Cubic World Generation, licensed under the MIT License (MIT). + * + * Copyright (c) 2015 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.opencubicchunks.cubicchunks.cubicgen.proxy; + +public class ServerProxy extends CommonProxy { + +} diff --git a/src/main/resources/META-INF/cubicchunks_cubicgen_at.cfg b/src/main/resources/META-INF/cubicchunks_cubicgen_at.cfg index 3e8e116..0d4f183 100644 --- a/src/main/resources/META-INF/cubicchunks_cubicgen_at.cfg +++ b/src/main/resources/META-INF/cubicchunks_cubicgen_at.cfg @@ -1,5 +1,8 @@ public net.minecraft.world.biome.BiomeProvider field_76944_d # genBiomes public net.minecraft.world.biome.BiomeProvider field_76945_e # biomeIndexLayer +public net.minecraft.client.gui.GuiCreateWorld field_146336_i # saveDirName +public net.minecraft.client.gui.GuiWorldSelection field_184866_u # selectionList +public net.minecraft.client.gui.GuiListWorldSelectionEntry field_186786_g # worldSummary # used by cubic chunks biome populators public net.minecraft.world.biome.Biome field_180281_af # GRASS_COLOR_NOISE diff --git a/src/test/java/io/github/opencubicchunks/cubicchunks/cubicgen/TestCustomGeneratorSettingsFixer.java b/src/test/java/io/github/opencubicchunks/cubicchunks/cubicgen/TestCustomGeneratorSettingsFixer.java new file mode 100644 index 0000000..5c34ca0 --- /dev/null +++ b/src/test/java/io/github/opencubicchunks/cubicchunks/cubicgen/TestCustomGeneratorSettingsFixer.java @@ -0,0 +1,344 @@ +/* + * This file is part of Cubic World Generation, licensed under the MIT License (MIT). + * + * Copyright (c) 2015 contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package io.github.opencubicchunks.cubicchunks.cubicgen; + +import static org.junit.Assert.assertEquals; + +import java.lang.reflect.Field; + +import javax.annotation.ParametersAreNonnullByDefault; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.core.Logger; +import org.junit.Before; +import org.junit.Test; + +import com.google.gson.JsonObject; + +import io.github.opencubicchunks.cubicchunks.cubicgen.common.biome.CubicBiome; +import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.CustomGeneratorSettings; +import io.github.opencubicchunks.cubicchunks.cubicgen.customcubic.CustomGeneratorSettingsFixer; +import io.github.opencubicchunks.cubicchunks.cubicgen.testutil.MinecraftEnvironment; +import mcp.MethodsReturnNonnullByDefault; + +@ParametersAreNonnullByDefault +@MethodsReturnNonnullByDefault +public class TestCustomGeneratorSettingsFixer { + String cc655ExamplePreset = "{\n" + + " \"waterLevel\":100,\n" + + " \"caves\":false,\n" + + " \"strongholds\":false,\n" + + " \"villages\":false,\n" + + " \"mineshafts\":false,\n" + + " \"temples\":false,\n" + + " \"oceanMonuments\":false,\n" + + " \"woodlandMansions\":false,\n" + + " \"ravines\":false,\n" + + " \"dungeons\":false,\n" + + " \"dungeonCount\":101,\n" + + " \"waterLakes\":false,\n" + + " \"waterLakeRarity\":102,\n" + + " \"lavaLakes\":false,\n" + + " \"lavaLakeRarity\":103,\n" + + " \"aboveSeaLavaLakeRarity\":104,\n" + + " \"lavaOceans\":true,\n" + + " \"biome\":1,\n" + + " \"biomeSize\":104,\n" + + " \"riverSize\":105,\n" + + " \"dirtSpawnSize\":134,\n" + + " \"dirtSpawnTries\":135,\n" + + " \"dirtSpawnProbability\":136.0,\n" + + " \"dirtSpawnMinHeight\":-Infinity,\n" + + " \"dirtSpawnMaxHeight\":Infinity,\n" + + " \"gravelSpawnSize\":137,\n" + + " \"gravelSpawnTries\":138,\n" + + " \"gravelSpawnProbability\":139.0,\n" + + " \"gravelSpawnMinHeight\":-Infinity,\n" + + " \"gravelSpawnMaxHeight\":Infinity,\n" + + " \"graniteSpawnSize\":140,\n" + + " \"graniteSpawnTries\":141,\n" + + " \"graniteSpawnProbability\":142.0,\n" + + " \"graniteSpawnMinHeight\":-Infinity,\n" + + " \"graniteSpawnMaxHeight\":143.0,\n" + + " \"dioriteSpawnSize\":144,\n" + + " \"dioriteSpawnTries\":145,\n" + + " \"dioriteSpawnProbability\":146.0,\n" + + " \"dioriteSpawnMinHeight\":-Infinity,\n" + + " \"dioriteSpawnMaxHeight\":147.0,\n" + + " \"andesiteSpawnSize\":148,\n" + + " \"andesiteSpawnTries\":149,\n" + + " \"andesiteSpawnProbability\":150.0,\n" + + " \"andesiteSpawnMinHeight\":-Infinity,\n" + + " \"andesiteSpawnMaxHeight\":151.0,\n" + + " \"coalOreSpawnSize\":152,\n" + + " \"coalOreSpawnTries\":153,\n" + + " \"coalOreSpawnProbability\":154.0,\n" + + " \"coalOreSpawnMinHeight\":-Infinity,\n" + + " \"coalOreSpawnMaxHeight\":155.0,\n" + + " \"ironOreSpawnSize\":156,\n" + + " \"ironOreSpawnTries\":157,\n" + + " \"ironOreSpawnProbability\":158.0,\n" + + " \"ironOreSpawnMinHeight\":-Infinity,\n" + + " \"ironOreSpawnMaxHeight\":159.0,\n" + + " \"goldOreSpawnSize\":160,\n" + + " \"goldOreSpawnTries\":161,\n" + + " \"goldOreSpawnProbability\":162.0,\n" + + " \"goldOreSpawnMinHeight\":-Infinity,\n" + + " \"goldOreSpawnMaxHeight\":-163.0,\n" + + " \"redstoneOreSpawnSize\":164,\n" + + " \"redstoneOreSpawnTries\":165,\n" + + " \"redstoneOreSpawnProbability\":166.0,\n" + + " \"redstoneOreSpawnMinHeight\":-Infinity,\n" + + " \"redstoneOreSpawnMaxHeight\":-167.0,\n" + + " \"diamondOreSpawnSize\":168,\n" + + " \"diamondOreSpawnTries\":169,\n" + + " \"diamondOreSpawnProbability\":170.0,\n" + + " \"diamondOreSpawnMinHeight\":-Infinity,\n" + + " \"diamondOreSpawnMaxHeight\":-178.0,\n" + + " \"lapisLazuliSpawnSize\":179,\n" + + " \"lapisLazuliSpawnTries\":180,\n" + + " \"lapisLazuliSpawnProbability\":181.0,\n" + + " \"lapisLazuliHeightMean\":182.0,\n" + + " \"lapisLazuliHeightStdDeviation\":183.0,\n" + + " \"hillsEmeraldOreSpawnTries\":184,\n" + + " \"hillsEmeraldOreSpawnProbability\":185.0,\n" + + " \"hillsEmeraldOreSpawnMinHeight\":-Infinity,\n" + + " \"hillsEmeraldOreSpawnMaxHeight\":-186.0,\n" + + " \"hillsSilverfishStoneSpawnSize\":187,\n" + + " \"hillsSilverfishStoneSpawnTries\":188,\n" + + " \"hillsSilverfishStoneSpawnProbability\":189.0,\n" + + " \"hillsSilverfishStoneSpawnMinHeight\":-Infinity,\n" + + " \"hillsSilverfishStoneSpawnMaxHeight\":190.0,\n" + + " \"mesaAddedGoldOreSpawnSize\":191,\n" + + " \"mesaAddedGoldOreSpawnTries\":192,\n" + + " \"mesaAddedGoldOreSpawnProbability\":193.0,\n" + + " \"mesaAddedGoldOreSpawnMinHeight\":-194.0,\n" + + " \"mesaAddedGoldOreSpawnMaxHeight\":196.0,\n" + + " \"heightVariationFactor\":106.0,\n" + + " \"specialHeightVariationFactorBelowAverageY\":107.0,\n" + + " \"heightVariationOffset\":108.0,\n" + + " \"heightFactor\":109.0,\n" + + " \"heightOffset\":110.0,\n" + + " \"depthNoiseFactor\":111.0,\n" + + " \"depthNoiseOffset\":112.0,\n" + + " \"depthNoiseFrequencyX\":113.0,\n" + + " \"depthNoiseFrequencyZ\":114.0,\n" + + " \"depthNoiseOctaves\":5,\n" + + " \"selectorNoiseFactor\":116.0,\n" + + " \"selectorNoiseOffset\":117.0,\n" + + " \"selectorNoiseFrequencyX\":118.0,\n" + + " \"selectorNoiseFrequencyY\":119.0,\n" + + " \"selectorNoiseFrequencyZ\":120.0,\n" + + " \"selectorNoiseOctaves\":1,\n" + + " \"lowNoiseFactor\":122.0,\n" + + " \"lowNoiseOffset\":123.0,\n" + + " \"lowNoiseFrequencyX\":124.0,\n" + + " \"lowNoiseFrequencyY\":125.0,\n" + + " \"lowNoiseFrequencyZ\":126.0,\n" + + " \"lowNoiseOctaves\":7,\n" + + " \"highNoiseFactor\":128.0,\n" + + " \"highNoiseOffset\":129.0,\n" + + " \"highNoiseFrequencyX\":130.0,\n" + + " \"highNoiseFrequencyY\":131.0,\n" + + " \"highNoiseFrequencyZ\":132.0,\n" + + " \"highNoiseOctaves\":3\n" + + "}"; + + String expectedConversionResult = "{\"waterLevel\":100," + + "\"caves\":false," + + "\"strongholds\":false," + + "\"alternateStrongholdsPositions\":false," + + "\"villages\":false," + + "\"mineshafts\":false," + + "\"temples\":false," + + "\"oceanMonuments\":false," + + "\"woodlandMansions\":false," + + "\"ravines\":false," + + "\"dungeons\":false," + + "\"dungeonCount\":101," + + "\"waterLakes\":false," + + "\"waterLakeRarity\":102," + + "\"lavaLakes\":false," + + "\"lavaLakeRarity\":103," + + "\"aboveSeaLavaLakeRarity\":104," + + "\"lavaOceans\":true," + + "\"biome\":1," + + "\"biomeSize\":104," + + "\"riverSize\":105," + + "\"standardOres\":[" + + "{\"blockstate\":{\"Properties\":{\"variant\":\"dirt\",\"snowy\":\"false\"},\"Name\":\"minecraft:dirt\"}," + + "\"spawnSize\":134," + + "\"spawnTries\":135," + + "\"spawnProbability\":136.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":Infinity}," + + "{\"blockstate\":{\"Name\":\"minecraft:gravel\"}," + + "\"spawnSize\":137," + + "\"spawnTries\":138," + + "\"spawnProbability\":139.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":Infinity}," + + "{\"blockstate\":{\"Properties\":{\"variant\":\"granite\"},\"Name\":\"minecraft:stone\"}," + + "\"spawnSize\":140," + + "\"spawnTries\":141," + + "\"spawnProbability\":142.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":143.0}," + + "{\"blockstate\":{\"Properties\":{\"variant\":\"diorite\"},\"Name\":\"minecraft:stone\"}," + + "\"spawnSize\":144," + + "\"spawnTries\":145," + + "\"spawnProbability\":146.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":147.0}," + + "{\"blockstate\":{\"Properties\":{\"variant\":\"andesite\"},\"Name\":\"minecraft:stone\"}," + + "\"spawnSize\":148," + + "\"spawnTries\":149," + + "\"spawnProbability\":150.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":151.0}," + + "{\"blockstate\":{\"Name\":\"minecraft:coal_ore\"}," + + "\"spawnSize\":152," + + "\"spawnTries\":153," + + "\"spawnProbability\":154.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":155.0}," + + "{\"blockstate\":{\"Name\":\"minecraft:iron_ore\"}," + + "\"spawnSize\":156," + + "\"spawnTries\":157," + + "\"spawnProbability\":158.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":159.0}," + + "{\"blockstate\":{\"Name\":\"minecraft:gold_ore\"}," + + "\"spawnSize\":160," + + "\"spawnTries\":161," + + "\"spawnProbability\":162.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":-163.0}," + + "{\"blockstate\":{\"Name\":\"minecraft:redstone_ore\"}," + + "\"spawnSize\":164," + + "\"spawnTries\":165," + + "\"spawnProbability\":166.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":-167.0}," + + "{\"blockstate\":{\"Name\":\"minecraft:diamond_ore\"}," + + "\"spawnSize\":168," + + "\"spawnTries\":169," + + "\"spawnProbability\":170.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":-178.0}," + + "{\"blockstate\":{\"Name\":\"minecraft:emerald_ore\"}," + + "\"biomes\":[\"minecraft:extreme_hills\",\"minecraft:smaller_extreme_hills\",\"minecraft:extreme_hills_with_trees\",\"minecraft:mutated_extreme_hills\",\"minecraft:mutated_extreme_hills_with_trees\"]," + + "\"spawnSize\":3," + + "\"spawnTries\":184," + + "\"spawnProbability\":185.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":-186.0}," + + "{\"blockstate\":{\"Properties\":{\"variant\":\"stone\"},\"Name\":\"minecraft:monster_egg\"}," + + "\"biomes\":[\"minecraft:extreme_hills\",\"minecraft:smaller_extreme_hills\",\"minecraft:extreme_hills_with_trees\",\"minecraft:mutated_extreme_hills\",\"minecraft:mutated_extreme_hills_with_trees\"]," + + "\"spawnSize\":187," + + "\"spawnTries\":188," + + "\"spawnProbability\":189.0," + + "\"minHeight\":-Infinity," + + "\"maxHeight\":190.0}," + + "{\"blockstate\":{\"Name\":\"minecraft:gold_ore\"}," + + "\"biomes\":[\"minecraft:mesa\",\"minecraft:mesa_clear_rock\",\"minecraft:mesa_rock\",\"minecraft:mutated_mesa\",\"minecraft:mutated_mesa_clear_rock\",\"minecraft:mutated_mesa_rock\"]," + + "\"spawnSize\":191," + + "\"spawnTries\":192," + + "\"spawnProbability\":193.0," + + "\"minHeight\":-194.0," + + "\"maxHeight\":196.0}]," + + "\"periodicGaussianOres\":[" + + "{\"blockstate\":{\"Name\":\"minecraft:lapis_ore\"}," + + "\"spawnSize\":179," + + "\"spawnTries\":180," + + "\"spawnProbability\":181.0," + + "\"heightMean\":182.0," + + "\"heightStdDeviation\":183.0," + + "\"heightSpacing\":0.0," + + "\"minHeight\":0.0," + + "\"maxHeight\":0.0}]," + + "\"expectedBaseHeight\":110.0," + + "\"expectedHeightVariation\":109.0," + + "\"actualHeight\":544.0," + + "\"heightVariationFactor\":106.0," + + "\"specialHeightVariationFactorBelowAverageY\":107.0," + + "\"heightVariationOffset\":108.0," + + "\"heightFactor\":109.0," + + "\"heightOffset\":110.0," + + "\"depthNoiseFactor\":111.0," + + "\"depthNoiseOffset\":112.0," + + "\"depthNoiseFrequencyX\":113.0," + + "\"depthNoiseFrequencyZ\":114.0," + + "\"depthNoiseOctaves\":5," + + "\"selectorNoiseFactor\":116.0," + + "\"selectorNoiseOffset\":117.0," + + "\"selectorNoiseFrequencyX\":118.0," + + "\"selectorNoiseFrequencyY\":119.0," + + "\"selectorNoiseFrequencyZ\":120.0," + + "\"selectorNoiseOctaves\":1," + + "\"lowNoiseFactor\":122.0," + + "\"lowNoiseOffset\":123.0," + + "\"lowNoiseFrequencyX\":124.0," + + "\"lowNoiseFrequencyY\":125.0," + + "\"lowNoiseFrequencyZ\":126.0," + + "\"lowNoiseOctaves\":7," + + "\"highNoiseFactor\":128.0," + + "\"highNoiseOffset\":129.0," + + "\"highNoiseFrequencyX\":130.0," + + "\"highNoiseFrequencyY\":131.0," + + "\"highNoiseFrequencyZ\":132.0," + + "\"highNoiseOctaves\":3," + + "\"cubeAreas\":[]," + + "\"replacerConfig\":{" + + "\"defaults\":{" + + "\"cubicgen:biome_fill_noise_octaves\":4.0," + + "\"cubicgen:ocean_block\":{\"Properties\":{\"level\":\"0\"},\"Name\":\"minecraft:water\"}," + + "\"cubicgen:height_scale\":64.0," + + "\"cubicgen:biome_fill_noise_freq\":0.0078125," + + "\"cubicgen:water_level\":63.0," + + "\"cubicgen:biome_fill_depth_factor\":2.3333333333333335," + + "\"cubicgen:terrain_fill_block\":{\"Properties\":{\"variant\":\"stone\"},\"Name\":\"minecraft:stone\"}," + + "\"cubicgen:mesa_depth\":16.0," + + "\"cubicgen:biome_fill_depth_offset\":3.0," + + "\"cubicgen:horizontal_gradient_depth_decrease_weight\":1.0," + + "\"cubicgen:height_offset\":64.0}," + + "\"overrides\":{}}," + + "\"version\":3}"; + + @Before + public void setUp() { + MinecraftEnvironment.init(); + CustomCubicMod.LOGGER = LogManager.getLogger("CustomCubicModTest");; + CubicBiome.init(); + CubicBiome.postInit(); + } + + @Test + public void testCustomGeneratorSettingsFixer() { + CustomGeneratorSettings settings = CustomGeneratorSettings.fromJson(cc655ExamplePreset); + JsonObject fixed = CustomGeneratorSettingsFixer.stringToJson(settings.toJson()); + JsonObject expected = CustomGeneratorSettingsFixer.stringToJson(expectedConversionResult); + assertEquals(expected,fixed); + } +}