From 2f16625fdd24953566e3ad354430d2f0d0772083 Mon Sep 17 00:00:00 2001 From: rjnasers Date: Sun, 12 Apr 2026 23:12:12 +0200 Subject: [PATCH 1/5] Build limits in place --- dependencies.gradle | 4 +- .../cardinalstar/cubicchunks/CubicChunks.java | 26 +- .../cubicchunks/CubicChunksConfig.java | 596 ++++-------------- .../early/common/MixinMinecraftServer.java | 20 +- .../common/MixinNetHandlerPlayServer.java | 51 +- .../server/ICubicChunksServer.java | 8 + .../world/CubicChunksSavedData.java | 107 +++- .../cubicchunks/world/cube/Cube.java | 9 - .../cubicchunks/worldgen/FillerInfo.java | 18 + .../cubicchunks/worldgen/HeightInfo.java | 7 + .../worldgen/VanillaWorldGenerator.java | 62 +- 11 files changed, 366 insertions(+), 542 deletions(-) create mode 100644 src/main/java/com/cardinalstar/cubicchunks/server/ICubicChunksServer.java create mode 100644 src/main/java/com/cardinalstar/cubicchunks/worldgen/FillerInfo.java create mode 100644 src/main/java/com/cardinalstar/cubicchunks/worldgen/HeightInfo.java diff --git a/dependencies.gradle b/dependencies.gradle index 235bbb35..c73f2400 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -44,8 +44,8 @@ dependencies { // ========================= Compat Deps ========================= // - compileOnly("com.falsepattern:chunkapi-mc1.7.10:0.8.0:dev") - compileOnly("com.falsepattern:endlessids-mc1.7.10:1.7.0:dev") + compileOnly("com.falsepattern:chunkapi-mc1.7.10:0.8.1:dev") + compileOnly("com.falsepattern:endlessids-mc1.7.10:1.7.1:dev") compileOnly("ganymedes01.etfuturum:Et-Futurum-Requiem:2.6.2.21-GTNH-daily:dev") // ========================= Test Deps ========================= // diff --git a/src/main/java/com/cardinalstar/cubicchunks/CubicChunks.java b/src/main/java/com/cardinalstar/cubicchunks/CubicChunks.java index f6d07b8b..adfa2b35 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/CubicChunks.java +++ b/src/main/java/com/cardinalstar/cubicchunks/CubicChunks.java @@ -30,6 +30,9 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import com.cardinalstar.cubicchunks.server.ICubicChunksServer; +import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; +import net.minecraft.server.MinecraftServer; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraft.world.storage.ISaveHandler; @@ -163,6 +166,12 @@ public String call() throws Exception { @Mod.EventHandler public void init(FMLInitializationEvent event) { + try { + CubicChunksConfig.init(); + } catch (ConfigException ex) { + throw new RuntimeException(ex); + } + CommonEventHandler eventHandler = new CommonEventHandler(); MinecraftForge.EVENT_BUS.register(eventHandler); FMLCommonHandler.instance() @@ -187,18 +196,12 @@ public void postInit(FMLPostInitializationEvent event) { } } - @Mod.EventHandler - public void serverStarting(FMLServerStartingEvent evt) { - CubicChunksConfig.registerCommands(evt); - } - @Mod.EventHandler public void onServerAboutToStart(FMLServerAboutToStartEvent event) { SideUtils.runForSide(() -> () -> { - IIntegratedServer integratedServer = cast(event.getServer()); - ICubicWorldSettings settings = cast(integratedServer.getWorldSettings()); - event.getServer() - .setBuildLimit(CubicChunks.MAX_SUPPORTED_BLOCK_Y); + MinecraftServer server = event.getServer(); + server.setBuildLimit(CubicChunks.MAX_SUPPORTED_BLOCK_Y); + ((ICubicChunksServer) server).setBuildMinimum(CubicChunks.MIN_SUPPORTED_BLOCK_Y); }, () -> () -> { // no-op, done by mixin }); @@ -212,10 +215,7 @@ public static void registerAnvil3dStorageFormatProvider() { public static boolean checkCanConnectWithMods(Map modVersions, Side remoteSide) { String remoteFullVersion = modVersions.get(MODID); if (remoteFullVersion == null) { - if (remoteSide.isClient()) { - return CubicChunksConfig.allowVanillaClients; // don't allow client without CC to connect - } - return true; // allow connecting to server without CC + return !remoteSide.isClient(); // don't allow client without CC to connect } if (!checkVersionFormat(MOD_VERSION, remoteSide.isClient() ? Side.SERVER : Side.CLIENT)) { return true; diff --git a/src/main/java/com/cardinalstar/cubicchunks/CubicChunksConfig.java b/src/main/java/com/cardinalstar/cubicchunks/CubicChunksConfig.java index b7c6561d..ce397d05 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/CubicChunksConfig.java +++ b/src/main/java/com/cardinalstar/cubicchunks/CubicChunksConfig.java @@ -39,6 +39,12 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import com.cardinalstar.cubicchunks.worldgen.FillerInfo; +import com.cardinalstar.cubicchunks.worldgen.HeightInfo; +import com.gtnewhorizon.gtnhlib.config.ConfigException; +import com.gtnewhorizon.gtnhlib.util.data.BlockMeta; +import cpw.mods.fml.common.registry.GameRegistry; +import net.minecraft.block.Block; import net.minecraft.client.resources.I18n; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; @@ -61,37 +67,43 @@ @Config(modid = CubicChunks.MODID, category = "general") public class CubicChunksConfig { - @Config.Comment("Chunk garbage collector update interval. Lower value will increase CPU usage, but can reduce memory usage.") - @Config.LangKey("cubicchunks.config.chunk_gc_interval") - public static int chunkGCInterval = 20 * 10; - @Config.Comment("Eliminates a few data copies in compatibility generator. May break some mods." + " Disable if you experience issues in modded dimensions or world types") @Config.LangKey("cubicchunks.config.optimized_compatibility_generator") public static boolean optimizedCompatibilityGenerator = true; - @Config.LangKey("cubicchunks.config.force_cc") - @Config.Comment(""" - Determines when a cubic chunks world should be created for non-cubic-chunks world types. - DEFAULT - only when cubic chunks world type - LOAD_NOT_EXCLUDED - load all worlds as cubic chunks, except excluded dimensions - ALWAYS - load everything as cubic chunks. Overrides forceDimensionExcludes""") - public static ForceCCMode forceLoadCubicChunks = ForceCCMode.DEFAULT; - - @Config.LangKey("cubicchunks.config.cubegen_per_tick") - @Config.Comment("The maximum number of cubic chunks to generate per tick.") - public static int maxGeneratedCubesPerTick = 49 * 16; - - @Config.LangKey("cubicchunks.config.max_cube_generation_time_millis") - @Config.Comment("Maximum amount of time spent on generating chunks per dimension.") - public static int maxCubeGenerationTimeMillis = 50; - - @Config.LangKey("cubicchunks.config.use_vanilla_world_generators") - @Config.Comment("Enabling this option will force cubic chunks to use world generators designed for two dimensional chunks, which are often used " - + "for custom ore generators added by mods. To do so cubic chunks will pregenerate cubes in a range of height from 0 to 255. This is " - + "very likely to break a lot of mods, cause the game to hang, and make the world generation depend on the order in which things are " - + "generated. Use at your own risk.") - public static boolean useVanillaChunkWorldGenerators = false; + @Config.Ignore + public static Map configuredDimensionalFillerMap = new HashMap<>(); + + @Config.LangKey("cubicchunks.config.filler_blocks") + @Config.Comment("Determines the filler block for dimensions. Default will attempt to be auto generated based on bottom layer blocks.\n" + + "Specifications are done as follows: 'dimensionId:direction:resourceLocation:meta'.\n" + + "Valid directions are 'top', 'bottom', and 'both' " + + "Meta is defaulted to 0.\n" + + "Example:\n" + + " S:defaultFillerBlocks <\n" + + " 0:bottom:minecraft:stone:3,\n" + + " 0:top:minecraft:air,\n" + + " -1:both:minecraft:netherrack\n" + + " >\n" + + "Spaces and tabs are not necessary. NEI is a good tool for this if you don't know the meta and resource location of blocks. (f3 + H)\n" + + "It's highly recommend to define these, as block are chosen before population is done on chunks, meaning that if bottom layers are normally\n" + + "populated to some block it might be missed.") + public static String[] default_filler_blocks = { "0:bottom:minecraft:stone", "0:top:minecraft:air", "-1:both:minecraft:netherrack", "1:both:minecraft:air"}; + + @Config.Ignore + public static Map configuredDimensionalHeightMap = new HashMap<>(); + + @Config.LangKey("cubicchunks.config.dimensional_height_limits") + @Config.Comment("Set the height limits for dimensions specifically. Note that this will override the default max and min heights. \n" + + "Format is dimensionId:top/bottom:height.\n" + + "Note that these heights must be multiples of 16. If not multiples of 16 they will be rounded towards 0 on the nearest multiple of 16.\n" + + "Example:\n" + + " S:dimensional_height_overrides <\n" + + " 0:bottom:-128, \n" + + " 0:top:1024 \n" + + " >\n") + public static String[] dimensional_height_overrides = {}; @Config.LangKey("cubicchunks.config.vert_view_distance") @Config.Comment("Similar to Minecraft's view distance, only for vertical chunks. Automatically adjusted by vertical view distance slider on the" @@ -102,25 +114,6 @@ public class CubicChunksConfig { @Config.Comment("Displays coloured boxes over cubes at Y=8 for debugging purposes.") public static boolean enableChunkStatusDebugging = false; - @Config.LangKey("cubicchunks.config.dimension_blacklist") - @Config.Comment("The specified dimension ID ranges won't be created as cubic chunks world for new worlds, and worlds created before this option" - + " has been added, unless forceDimensionExcludes is set to true. IDs can be specified either as range in format min:max, or as single " - + "numbers.\n" - + "Example:\n" - + " S:excludedDimensions <\n" - + " 1\n" - + " 10:100\n" - + " 101:200\n" - + " -5\n" - + " >\n" - + "The ranges specified can overlap, and the bounds can be specified in reversed order.") - public static String[] excludedDimensions = { "1" }; - - @Config.LangKey("cubicchunks.config.force_dimension_blacklist") - @Config.Comment("If this is set to true, cubic chunks will respect excluded dimensions even for already existing worlds. If this results in a " - + "existing dimension switching between cubic chunks and vanilla, the contents of that dimension won't be converted.") - public static boolean forceDimensionExcludes = false; - @Config.LangKey("cubicchunks.config.relight_checks_per_tick_per_column") @Config.Comment("In an attempt to fix lighting glitches over time, cubic chunks will keep updating light in specified amount of blocks per " + "column (chunk) per tick. This option shouldn't be necessary but may be useful for old worlds where lighting is broken or when " @@ -132,18 +125,6 @@ public class CubicChunksConfig { + "fix lighting on the clientside.") public static boolean doClientLightFixes = false; - @Config.LangKey("cubicchunks.config.biome_temperature_center_y") - @Config.Comment("Heights below this value will have normal, unmodified biome temperature") - public static int biomeTemperatureCenterY = 64; - - @Config.LangKey("cubicchunks.config.biome_temperature_y_factor") - @Config.Comment("How much should biome temperature increase with height (negative values decrease temperature)") - public static float biomeTemperatureHeightFactor = -0.05F / 30.0F; - - @Config.LangKey("cubicchunks.config.biome_temperature_scale_max_y") - @Config.Comment("Above this height, biome temperature will no longer change") - public static int biomeTemperatureScaleMaxY = 256; - @Config.LangKey("cubicchunks.config.storage_format") @Config.Comment("The storage format. Note: this will be used for all newly created worlds. Existing worlds will continue to use the format they were created with.\n" + "If empty, the storage format for new worlds will be determined automatically.") @@ -180,51 +161,19 @@ public class CubicChunksConfig { + "crash.") public static int worldgenWatchdogTimeLimit = 10000; - @Config.LangKey("cubicchunks.config.allow_vanilla_clients") - @Config.Comment("Allows clients without cubic chunks to join. " + "THIS IS INTENDED FOR VANILLA CLIENTS. " - + "This is VERY likely to break when used with other mods") - public static boolean allowVanillaClients = false; - - @Config.LangKey("cubicchunks.config.cubes_to_send_per_tick") - @Config.Comment("Max amount of cubes sent to client per tick to players") - public static int cubesToSendPerTick = 81 * 8 + 1; - - @Config.LangKey("cubicchunks.config.vanilla_clients") - @Config.Comment("Options relating to support for vanilla clients.") - public static VanillaClients vanillaClients = new VanillaClients(); - @Config.LangKey("cubicchunks.config.use_shadow_paging_io") @Config.Comment("Whether cubic chunks save format IO should use shadow paging. This may be slightly slower and use " + "a bit more storage but should significantly improve reliability in case of improper shutdown.") @Config.RequiresWorldRestart public static boolean useShadowPagingIO = true; - @Config.LangKey("cubicchunks.config.ignore_corrupted_chunks") - @Config.Comment("Ignores and regenerates corrupted chunks instead of crashing the server") - public static boolean ignoreCorruptedChunks = false; - @Config.LangKey("cubicchunks.config.disable_lighting") @Config.Comment("Disables all light propagation") public static boolean disableLighting = false; - public static final class VanillaClients { - - @Config.LangKey("cubicchunks.config.vanilla_clients.horizontal_slices") - @Config.Comment("Enables horizontal slices for vanilla clients. " - + "This will cause coordinates to wrap around on the X and Z axes in the same way as on Y.") - public boolean horizontalSlices = true; - - @Config.LangKey("cubicchunks.config.vanilla_clients.horizontal_slices_bedrock_only") - @Config.Comment("If horizontal slices is enabled, restricts horizontal slices to Bedrock edition clients.\n" - + "Note that Bedrock clients are not supported directly, but only when connecting through a proxy such as Geyser.") - public boolean horizontalSlicesBedrockOnly = true; - @Config.LangKey("cubicchunks.config.vanilla_clients.horizontal_slice_size") - @Config.Comment("The size (radius) of a horizontal slice.") - public int horizontalSliceSize = 65536; - } - @Config.Ignore public static int defaultMaxCubesPerChunkloadingTicket = 25 * 16; + @Config.Ignore public static Map modMaxCubesPerChunkloadingTicket = new HashMap<>(); @@ -244,30 +193,14 @@ public static final class Optimizations { static { modMaxCubesPerChunkloadingTicket.put("cubicchunks", defaultMaxCubesPerChunkloadingTicket); } - @Config.Ignore - private static TreeRangeSet excludedDimensionsRanges = null; - // TODO: Watch this carefully. - public static void sync() { - ConfigurationManager.save(CubicChunksConfig.class); - initDimensionRanges(); + public static void init() throws ConfigException + { validateConfigValues(); - ConfigurationManager.save(CubicChunksConfig.class); + initDimensionalConfiguration(); } private static void validateConfigValues() { - // if (!VanillaCompatibilityGeneratorProviderBase.REGISTRY.containsKey(new - // ResourceLocation(compatibilityGeneratorType))) { - // CubicChunks.LOGGER.error("CubicChunksConfig: Compatibility generator type {} doesn't exist, resetting config - // to default", compatibilityGeneratorType); - // compatibilityGeneratorType = VanillaCompatibilityGeneratorProviderBase.DEFAULT.toString(); - // } - // if (!storageFormat.isEmpty() && !StorageFormatProviderBase.REGISTRY.containsKey(new - // ResourceLocation(storageFormat))) { - // CubicChunks.LOGGER.error("CubicChunksConfig: Storage format {} doesn't exist, resetting config to default", - // storageFormat); - // storageFormat = ""; - // } if ((defaultMinHeight & 0xF) != 0) { CubicChunks.LOGGER.error( "CubicChunksConfig: defaultMinHeight not a multiple of 16, got {}, setting to {}", @@ -284,393 +217,112 @@ private static void validateConfigValues() { } } - private static void initDimensionRanges() { - if (excludedDimensionsRanges == null) { - excludedDimensionsRanges = TreeRangeSet.create(); - } - excludedDimensionsRanges.clear(); - - final Predicate NUMBER_PATTERN = Pattern.compile("^-?\\d+$") - .asPredicate(); - final Predicate NUMBER_RANGE_PATTERN = Pattern.compile("^-?\\d+:-?\\d+$") - .asPredicate(); - - for (String str : excludedDimensions) { - try { - parseRange(NUMBER_PATTERN, NUMBER_RANGE_PATTERN, str); - } catch (NumberFormatException ex) { - CubicChunks.LOGGER - .error("Error parsing excluded dimension ranges: " + str + " is not a valid range, ignoring"); + private static void initDimensionalConfiguration() throws ConfigException { + // Height Limit Configs + int i = 1; + for (String config : dimensional_height_overrides) + { + String[] entries = config.split(":"); + if (entries.length != 3) + { + throw new ConfigException("Dimensional Height Overrides configuration is malformed for entry: " + i); } - } - Set> ranges = excludedDimensionsRanges.asRanges(); - excludedDimensions = new String[ranges.size()]; - int i = 0; - for (Range range : ranges) { - int min = range.lowerBoundType() == BoundType.CLOSED ? range.lowerEndpoint() : range.lowerEndpoint() + 1; - int max = range.upperBoundType() == BoundType.CLOSED ? range.upperEndpoint() : range.upperEndpoint() - 1; - excludedDimensions[i] = min == max ? String.valueOf(min) : (min + ":" + max); - i++; - } - } - private static void parseRange(Predicate NUMBER_PATTERN, Predicate NUMBER_RANGE_PATTERN, - String str) { - // add ranges as open where possible to allow merging - if (NUMBER_PATTERN.test(str)) { - int value = Integer.parseInt(str); - if (value == Integer.MIN_VALUE || value == Integer.MAX_VALUE) { - excludedDimensionsRanges.add(Range.singleton(value)); - } else { - excludedDimensionsRanges.add(Range.open(value - 1, value + 1)); - } - } else if (NUMBER_RANGE_PATTERN.test(str)) { - String[] parts = str.split(":"); - int lower = Integer.parseInt(parts[0]); - int upper = Integer.parseInt(parts[1]); - if (lower == upper) { - if (lower == Integer.MIN_VALUE || lower == Integer.MAX_VALUE) { - excludedDimensionsRanges.add(Range.singleton(lower)); - } else { - excludedDimensionsRanges.add(Range.open(lower - 1, lower + 2)); + try + { + int dimension = Integer.parseInt(entries[0]); + int height = Integer.parseInt(entries[2]); + if ((height & 0xF) != 0) { + CubicChunks.LOGGER.error( + "CubicChunksConfig: dimensional height configured to a non multiple of 16, got {}, setting to {}", + height, + height & ~0xF); + height &= ~0xF; } - } else { - if (lower == Integer.MIN_VALUE && upper == Integer.MAX_VALUE) { - excludedDimensionsRanges.add(Range.closed(lower, upper)); - } else if (lower == Integer.MIN_VALUE) { - excludedDimensionsRanges.add(Range.closedOpen(lower, upper + 1)); - } else if (upper == Integer.MAX_VALUE) { - excludedDimensionsRanges.add(Range.openClosed(lower - 1, upper)); - } else { - excludedDimensionsRanges.add(Range.open(lower - 1, upper + 1)); - } - } - } else { - CubicChunks.LOGGER - .error("Error parsing excluded dimension ranges: " + str + " is not a valid range, ignoring"); - } - } - - @SubscribeEvent - public static void onConfigChanged(ConfigChangedEvent.OnConfigChangedEvent event) { - if (event.modID.equals(CubicChunks.MODID)) { - sync(); - } - } - - @SubscribeEvent - public static void registerCommands(FMLServerStartingEvent evt) { - evt.registerServerCommand(new BaseCubicChunksCommand()); - } - - public static void setVerticalViewDistance(int value) { - verticalCubeLoadDistance = value; - sync(); - } - - public static boolean isDimensionExcluded(int dimension) { - if (excludedDimensionsRanges == null) { - initDimensionRanges(); - } - return excludedDimensionsRanges.contains(dimension); - } - - public enum ForceCCMode { - /// only when cubic chunks world type - DEFAULT, - /// load all worlds as cubic chunks, except excluded dimensions - LOAD_NOT_EXCLUDED, - /// load everything as cubic chunks. Overrides forceDimensionExcludes - ALWAYS - } - - static class BaseCubicChunksCommand extends SubCommandBase { - - public BaseCubicChunksCommand() { - super(CubicCommandBase.PermissionLevel.OP); - addSubcommand(new ConfigCommand(CubicCommandBase.PermissionLevel.OP)); - } - - @Override - public String getCommandName() { - return "cubicchunks"; - } - - @Override - public String getCommandUsage(ICommandSender sender) { - return "cubicchunks.command.usage.cubicchunks"; - } - } - - static class ConfigCommand extends SubCommandBase { - - public ConfigCommand(PermissionLevel permissionLevel) { - super(permissionLevel); - addSubcommand(new ReloadConfig(permissionLevel)); - addSubcommand(new SetConfigBase(permissionLevel)); - } - - @Override - public String getCommandName() { - return "config"; - } - - @Override - public String getCommandUsage(ICommandSender sender) { - return "cubicchunks.command.usage.config"; - } - } - - static class SetConfigBase extends SubCommandBase { - - public SetConfigBase(CubicCommandBase.PermissionLevel permissionLevelRequired) { - super(permissionLevelRequired); - Field[] fields = CubicChunksConfig.class.getFields(); - try { - registerConfigCommandsFor(null, fields, ""); - } catch (ReflectiveOperationException e) { - throw new IllegalStateException(e); - } - } + HeightInfo info = configuredDimensionalHeightMap.getOrDefault(dimension, new HeightInfo()); - private void registerConfigCommandsFor(@Nullable Object object, Field[] fields, String prefix) - throws ReflectiveOperationException { - for (Field field : fields) { - if (field.getAnnotationsByType(Config.Ignore.class).length != 0) { - continue; + String direction = entries[1]; + if (direction.equals("bottom")) + { + info.minHeight = height; + if (info.maxHeight == null) + { + info.maxHeight = defaultMaxHeight; + } } - boolean requiresWorldRestart = field.getAnnotationsByType(Config.RequiresWorldRestart.class).length - != 0; - String name = prefix + field.getName(); - Class type = field.getType(); - boolean isSimpleType = type.isPrimitive() || type == String.class; - boolean isCollection = type.isArray() || Map.class.isAssignableFrom(type) - || List.class.isAssignableFrom(type); - boolean isEnum = type.isEnum(); - if (!isSimpleType && !isCollection && !isEnum) { - registerConfigCommandsFor(field.get(object), type.getFields(), name + "."); - continue; + else if (direction.equals("top")) + { + info.maxHeight = height; + if (info.minHeight == null) + { + info.minHeight = defaultMinHeight; + } } - addSubcommand( - new SetConfig(name, object, field, requiresWorldRestart, this.getRequiredPermissionEnum())); - } - } - - @Override - public String getCommandName() { - return "set"; - } - - @Override - public String getCommandUsage(ICommandSender sender) { - return "cubicchunks.command.usage.config.set"; - } - } - - static class SetConfig extends CubicCommandBase { - - private static final Set TRUE_STRINGS = new HashSet<>( - Arrays.asList("true", "1", "yes", "on", "enable", "enabled")); - private static final Set FALSE_STRINGS = new HashSet<>( - Arrays.asList("false", "0", "no", "off", "disable", "disabled")); - - private final String name; - private final Object object; - private final Field field; - private final boolean requiresWorldRestart; - - public SetConfig(String name, @Nullable Object object, Field field, boolean requiresWorldRestart, - PermissionLevel permissionLevel) { - super(permissionLevel); - this.name = name; - this.object = object; - this.field = field; - this.requiresWorldRestart = requiresWorldRestart; - } - - @Override - public String getCommandName() { - return name; - } - - @SuppressWarnings("deprecation") - @Override - public String getCommandUsage(ICommandSender sender) { - return I18n.format("cubicchunks.command.usage.config.set_option", name); // TODO? - // if (FMLCommonHandler.instance().getSide() == Side.CLIENT) { - // - // } else { - // //we have to use this on the dedicated server, as the client I18n class isn't available there... - // // unfortunately this could result in a client being sent a string in a language other than their - // configured locale, but i don't - // // see any alternative other than adding separate translation keys for every single config option - // return - // net.minecraft.util.text.translation.I18n.translateToLocalFormatted("cubicchunks.command.usage.config.set_option", - // name); - // } - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - Object newValue = parseConfigValue(args, sender); - try { - field.set(object, newValue); - CubicChunksConfig.sync(); - sender.addChatMessage( - new ChatComponentTranslation( - "cubicchunks.command.config.set.done", - name, - stringify(field.get(object)))); - if (requiresWorldRestart) { - sender.addChatMessage( - new ChatComponentTranslation("cubicchunks.command.config.set.requires_restart", name)); + else + { + throw new ConfigException("Directional argument for height limits is invalid for entry: " + i + ". Invalid:" + direction + " Valid directions bottom and top."); } - } catch (ReflectiveOperationException e) { - throw new CommandException("cubicchunks.command.config.set.failed", name); - } - } - private String stringify(@Nullable Object o) { - if (o == null) { - return "null"; + configuredDimensionalHeightMap.put(dimension, info); } - if (o.getClass() - .isPrimitive() - || o.getClass() - .isEnum() - || o instanceof String - || o instanceof Collection) { - return o.toString(); + catch (NumberFormatException e) + { + throw new ConfigException("Dimensional Height Overrides configuration is malformed for entry: " + i); } - if (o instanceof int[]) { - return Arrays.toString((int[]) o); - } - if (o instanceof String[]) { - return Arrays.deepToString((Object[]) o); - } - throw new IllegalArgumentException(o.toString()); + i++; } - private Object parseConfigValue(String[] args, ICommandSender sender) throws CommandException { - Class type = field.getType(); - if (type == String.class) { - return String.join(" ", args); - } - if ((type.isPrimitive() || type.isEnum()) && args.length != 1) { - throw new WrongUsageException( - "cubicchunks.command.usage.config.set.primitive", - name, - type.getSimpleName()); + i = 1; + // Filler Configs + for (String config : default_filler_blocks) + { + String[] entries = config.split(":"); + if (entries.length != 4 && entries.length != 5) + { + throw new ConfigException("Dimensional Filler block configuration is malformed for entry: " + i); } - Object o = tryParseSimpleType(type, args[0], sender); - if (o != null) { - return o; - } - if (type == int[].class) { - int[] value = new int[args.length]; - for (int i = 0; i < args.length; i++) { - value[i] = parseInt(sender, args[i]); + try { + int dimension = Integer.parseInt(entries[0]); + Block fillerBlock = GameRegistry.findBlock(entries[2], entries[3]); + if (fillerBlock == null) + { + throw new ConfigException("Dimensional Height Overrides configuration is malformed for entry: " + i + ". Block not found for resource location " + entries[2] + ":" + entries[3]); } - return value; - } - if (type == String[].class) { - return args; - } - if (type == Map.class) { - Type genericType = field.getGenericType(); - if (!(genericType instanceof ParameterizedType)) { - throw new IllegalStateException( - "Field " + field.getDeclaringClass() - + "." - + field.getName() - + " appears to be a raw type Map!"); + int meta = entries.length == 4 ? 0 : Integer.parseInt(entries[4]); + + FillerInfo info = configuredDimensionalFillerMap.getOrDefault(dimension, new FillerInfo()); + + String direction = entries[1]; + if (direction.equals("bottom")) + { + info.bottomFiller = new BlockMeta(fillerBlock, meta); } - Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments(); - Type key = actualTypeArguments[0]; - if (!(key instanceof Class)) { - throw new IllegalStateException( - "Field " + field.getDeclaringClass() - + "." - + field.getName() - + " key generic type is not a class!"); + else if (direction.equals("top")) + { + info.topFiller = new BlockMeta(fillerBlock, meta); } - Type value = actualTypeArguments[1]; - if (!(value instanceof Class)) { - throw new IllegalStateException( - "Field " + field.getDeclaringClass() - + "." - + field.getName() - + " key generic type is not a class!"); + else if (direction.equals("both")) + { + info.bottomFiller = new BlockMeta(fillerBlock, meta); + info.topFiller = new BlockMeta(fillerBlock, meta); } - Map map = new HashMap<>(); - for (String arg : args) { - String[] split = arg.split("="); - Object k = tryParseSimpleType((Class) key, split[0], sender); - Object v = tryParseSimpleType((Class) value, split[1], sender); - map.put(k, v); + else + { + throw new ConfigException("Directional argument for filler blocks is invalid for entry: " + i + ". Invalid:" + direction + " Valid directions are both, bottom, and top."); } - return map; - } - throw new IllegalStateException("Unsupported field type " + field); - } - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Nullable - private Object tryParseSimpleType(Class type, String value, ICommandSender sender) throws CommandException { - if (type == String.class) { - return value; - } - if (type == int.class) { - return parseInt(sender, value); - } - if (type == boolean.class) { - return parseBool(value); - } - if (type == float.class) { - return (float) parseDouble(sender, value); - } - if (type == double.class) { - return parseDouble(sender, value); + configuredDimensionalFillerMap.put(dimension, info); } - if (type.isEnum()) { - return Enum.valueOf((Class) type, value); + catch (NumberFormatException e) + { + throw new ConfigException("Dimensional filler default configuration is malformed for entry: " + i); } - return null; - } - - private boolean parseBool(String value) throws CommandException { - value = value.toLowerCase(Locale.ROOT); - if (TRUE_STRINGS.contains(value)) { - return true; - } - if (FALSE_STRINGS.contains(value)) { - return false; - } - throw new CommandException("commands.generic.boolean.invalid", value); } } - static class ReloadConfig extends CubicCommandBase { - - public ReloadConfig(PermissionLevel permissionLevelRequired) { - super(permissionLevelRequired); - } - - @Override - public String getCommandName() { - return "reload"; - } - - @Override - public String getCommandUsage(ICommandSender sender) { - return "cubicchunks.command.usage.config.reload"; - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - CubicChunksConfig.sync(); - sender.addChatMessage(new ChatComponentTranslation("cubicchunks.command.config.reload.done")); - } + public static void setVerticalViewDistance(int value) { + verticalCubeLoadDistance = value; + ConfigurationManager.save(CubicChunksConfig.class); } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinMinecraftServer.java b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinMinecraftServer.java index 627ab787..e59f543d 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinMinecraftServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinMinecraftServer.java @@ -20,11 +20,13 @@ */ package com.cardinalstar.cubicchunks.mixin.early.common; +import com.cardinalstar.cubicchunks.server.ICubicChunksServer; import net.minecraft.server.MinecraftServer; import net.minecraft.world.World; import net.minecraftforge.common.DimensionManager; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -33,7 +35,11 @@ import com.cardinalstar.cubicchunks.server.SpawnCubes; @Mixin(MinecraftServer.class) -public class MixinMinecraftServer { +public class MixinMinecraftServer implements ICubicChunksServer +{ + @Unique + private int cubicChunks$buildMinimum; + @Inject(method = "initialWorldChunkLoad", at = @At("HEAD"), cancellable = true) private void onInitialSpawnLoad(CallbackInfo ci) { @@ -43,4 +49,16 @@ private void onInitialSpawnLoad(CallbackInfo ci) { .update(world); ci.cancel(); } + + @Override + public void setBuildMinimum(int minBuildHeight) + { + cubicChunks$buildMinimum = minBuildHeight; + } + + @Override + public int getBuildMinimum() + { + return cubicChunks$buildMinimum; + } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java index 61f5b857..26f0e8c9 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java @@ -1,20 +1,63 @@ package com.cardinalstar.cubicchunks.mixin.early.common; +import com.cardinalstar.cubicchunks.world.api.IMinMaxHeight; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; import net.minecraft.network.NetHandlerPlayServer; +import net.minecraft.network.play.server.S02PacketChat; import net.minecraft.server.MinecraftServer; - +import net.minecraft.server.management.ItemInWorldManager; +import net.minecraft.util.ChatComponentTranslation; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(NetHandlerPlayServer.class) public class MixinNetHandlerPlayServer { +// @Redirect( +// method = "processPlayerBlockPlacement", +// at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getBuildLimit()I")) +// public int noopHeightChecks(MinecraftServer instance) { +// return Integer.MAX_VALUE; +// } + + @Shadow + public EntityPlayerMP playerEntity; + @Redirect( method = "processPlayerBlockPlacement", - at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getBuildLimit()I")) - public int noopHeightChecks(MinecraftServer instance) { - return Integer.MAX_VALUE; + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/server/management/ItemInWorldManager;activateBlockOrUseItem(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;IIIIFFF)Z" + ) + ) + private boolean preventLowPlacement(ItemInWorldManager manager, EntityPlayer player, World world, + ItemStack stack, int x, int y, int z, + int side, float hitX, float hitY, float hitZ, + @Local(type = WorldServer.class) WorldServer server) + { + if (y < ((IMinMaxHeight)server).getMinHeight()) { + ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("build.tooLow", ((IMinMaxHeight) server).getMinHeight()); + chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.RED); + this.playerEntity.playerNetServerHandler.sendPacket(new S02PacketChat(chatcomponenttranslation)); + return false; + } + + return manager.activateBlockOrUseItem(player, world, stack, x, y, z, side, hitX, hitY, hitZ); } + @Redirect( + method = "processPlayerBlockPlacement", + at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getBuildLimit()I")) + public int noopHeightChecks(MinecraftServer instance, @Local(type = WorldServer.class) WorldServer server) + { + return ((IMinMaxHeight)server).getMaxHeight(); + } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/server/ICubicChunksServer.java b/src/main/java/com/cardinalstar/cubicchunks/server/ICubicChunksServer.java new file mode 100644 index 00000000..b4acc6dc --- /dev/null +++ b/src/main/java/com/cardinalstar/cubicchunks/server/ICubicChunksServer.java @@ -0,0 +1,8 @@ +package com.cardinalstar.cubicchunks.server; + +public interface ICubicChunksServer +{ + void setBuildMinimum(int minBuildHeight); + + int getBuildMinimum(); +} diff --git a/src/main/java/com/cardinalstar/cubicchunks/world/CubicChunksSavedData.java b/src/main/java/com/cardinalstar/cubicchunks/world/CubicChunksSavedData.java index 0582db0b..adc0819d 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/world/CubicChunksSavedData.java +++ b/src/main/java/com/cardinalstar/cubicchunks/world/CubicChunksSavedData.java @@ -20,51 +20,134 @@ */ package com.cardinalstar.cubicchunks.world; +import com.cardinalstar.cubicchunks.CubicChunksConfig; +import com.cardinalstar.cubicchunks.worldgen.FillerInfo; +import com.cardinalstar.cubicchunks.worldgen.HeightInfo; +import com.gtnewhorizon.gtnhlib.util.data.BlockMeta; +import com.gtnewhorizon.gtnhlib.util.data.ImmutableBlockMeta; +import net.minecraft.block.Block; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraft.world.WorldSavedData; + public class CubicChunksSavedData extends WorldSavedData { public int minHeight = 0, maxHeight = 256; + private FillerInfo fillerInfo; + private World world; public CubicChunksSavedData(String name) { super(name); } - public CubicChunksSavedData(int minHeight, int maxHeight) { + public CubicChunksSavedData(int dimensionId, World world) { this("cubicChunksData"); - this.minHeight = minHeight; - this.maxHeight = maxHeight; + HeightInfo heightInfo = CubicChunksConfig.configuredDimensionalHeightMap.get(dimensionId); + if (heightInfo != null) + { + this.minHeight = heightInfo.minHeight; + this.maxHeight = heightInfo.maxHeight; + } + else + { + this.minHeight = CubicChunksConfig.defaultMinHeight; + this.maxHeight = CubicChunksConfig.defaultMaxHeight; + } + + this.fillerInfo = CubicChunksConfig.configuredDimensionalFillerMap.get(dimensionId); + if (this.fillerInfo == null) + { + fillerInfo = new FillerInfo(); + } } public static CubicChunksSavedData get(World world) { - var data = (CubicChunksSavedData) world.mapStorage.loadData(CubicChunksSavedData.class, "cubicChunksData"); - + var data = (CubicChunksSavedData) world.perWorldStorage.loadData(CubicChunksSavedData.class, "cubicChunksData"); if (data == null) { - int maxY = ((ICubicWorldProvider) world.provider).getOriginalActualHeight(); - - data = new CubicChunksSavedData(0, maxY); + data = new CubicChunksSavedData(world.provider.dimensionId, world); data.markDirty(); - world.mapStorage.setData(data.mapName, data); - world.mapStorage.saveAllData(); + world.perWorldStorage.setData(data.mapName, data); + world.perWorldStorage.saveAllData(); } - + data.world = world; return data; } + public FillerInfo getFillerInfo() + { + return fillerInfo; + } + + public void setBottomFiller(ImmutableBlockMeta block) + { + fillerInfo.bottomFiller = block; + this.markDirty(); + + world.perWorldStorage.setData(this.mapName, this); + world.perWorldStorage.saveAllData(); + } + + public void setTopFiller(ImmutableBlockMeta block) + { + fillerInfo.topFiller = block; + this.markDirty(); + + world.perWorldStorage.setData(this.mapName, this); + world.perWorldStorage.saveAllData(); + } + @Override - public void readFromNBT(NBTTagCompound nbt) { + public void readFromNBT(NBTTagCompound nbt) + { // set 4 least significant bits to zero to ensure they are always multiples of 16 minHeight = nbt.getInteger("minHeight") & ~0xF; maxHeight = nbt.getInteger("maxHeight") & ~0xF; + + if (fillerInfo == null) + { + fillerInfo = new FillerInfo(); + } + + NBTTagCompound fillerCompound = nbt.getCompoundTag("fillerBlocks"); + + if (fillerCompound.hasKey("topId")) + { + int topBlock = fillerCompound.getInteger("topId"); + short topMeta = fillerCompound.getShort("topMeta"); + fillerInfo.topFiller = new BlockMeta(Block.getBlockById(topBlock), topMeta); + } + + if (fillerCompound.hasKey("bottomId")) + { + int bottomBlock = fillerCompound.getInteger("bottomId"); + short bottomMeta = fillerCompound.getShort("bottomMeta"); + fillerInfo.bottomFiller = new BlockMeta(Block.getBlockById(bottomBlock), bottomMeta); + } + } @Override public void writeToNBT(NBTTagCompound compound) { compound.setInteger("minHeight", minHeight); compound.setInteger("maxHeight", maxHeight); + + NBTTagCompound filler = new NBTTagCompound(); + + if (fillerInfo.bottomFiller != null) + { + filler.setInteger("bottomId", Block.getIdFromBlock(fillerInfo.bottomFiller.getBlock())); + filler.setShort("bottomMeta", (short) fillerInfo.bottomFiller.getBlockMeta()); + } + + if (fillerInfo.topFiller != null) + { + filler.setInteger("topId", Block.getIdFromBlock(fillerInfo.topFiller.getBlock())); + filler.setShort("topMeta", (short) fillerInfo.topFiller.getBlockMeta()); + } + + compound.setTag("fillerBlocks", filler); } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/world/cube/Cube.java b/src/main/java/com/cardinalstar/cubicchunks/world/cube/Cube.java index d1b56832..4981fe05 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/world/cube/Cube.java +++ b/src/main/java/com/cardinalstar/cubicchunks/world/cube/Cube.java @@ -674,15 +674,6 @@ public void onCubeLoad() { .onCubeLoad(this); CompatHandler.onCubeLoad(new ChunkEvent.Load(getColumn())); EVENT_BUS.post(new CubeEvent.Load(world, coords, this)); - - ICubicWorldInternal world = this.getWorld(); - - int min = this.getY() << 4; - int max = (this.getY() + 1) << 4; - - if (min < world.getMinHeight() || max > world.getMaxHeight()) { - world.setHeightBounds(Math.min(min, world.getMinHeight()), Math.max(max, world.getMaxHeight())); - } } @SuppressWarnings("deprecation") diff --git a/src/main/java/com/cardinalstar/cubicchunks/worldgen/FillerInfo.java b/src/main/java/com/cardinalstar/cubicchunks/worldgen/FillerInfo.java new file mode 100644 index 00000000..e52666b1 --- /dev/null +++ b/src/main/java/com/cardinalstar/cubicchunks/worldgen/FillerInfo.java @@ -0,0 +1,18 @@ +package com.cardinalstar.cubicchunks.worldgen; + +import com.github.bsideup.jabel.Desugar; +import com.gtnewhorizon.gtnhlib.util.data.ImmutableBlockMeta; + +@Desugar +public class FillerInfo +{ + public ImmutableBlockMeta topFiller; + public ImmutableBlockMeta bottomFiller; + public FillerInfo(ImmutableBlockMeta topFiller, ImmutableBlockMeta bottomFiller) + { + this.topFiller = topFiller; + this.bottomFiller = bottomFiller; + } + + public FillerInfo() {} +} diff --git a/src/main/java/com/cardinalstar/cubicchunks/worldgen/HeightInfo.java b/src/main/java/com/cardinalstar/cubicchunks/worldgen/HeightInfo.java new file mode 100644 index 00000000..8d780229 --- /dev/null +++ b/src/main/java/com/cardinalstar/cubicchunks/worldgen/HeightInfo.java @@ -0,0 +1,7 @@ +package com.cardinalstar.cubicchunks.worldgen; + +public class HeightInfo +{ + public Integer maxHeight; + public Integer minHeight; +} diff --git a/src/main/java/com/cardinalstar/cubicchunks/worldgen/VanillaWorldGenerator.java b/src/main/java/com/cardinalstar/cubicchunks/worldgen/VanillaWorldGenerator.java index 5c3b3020..8c3e6295 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/worldgen/VanillaWorldGenerator.java +++ b/src/main/java/com/cardinalstar/cubicchunks/worldgen/VanillaWorldGenerator.java @@ -30,6 +30,7 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; import net.minecraft.block.Block; import net.minecraft.entity.EnumCreatureType; import net.minecraft.init.Blocks; @@ -70,7 +71,6 @@ import com.cardinalstar.cubicchunks.world.cube.blockview.IMutableBlockView; import com.cardinalstar.cubicchunks.world.cube.blockview.SafeMutableBlockView; import com.cardinalstar.cubicchunks.world.cube.blockview.UniformBlockView; -import com.github.bsideup.jabel.Desugar; import com.gtnewhorizon.gtnhlib.util.data.BlockMeta; import com.gtnewhorizon.gtnhlib.util.data.ImmutableBlockMeta; @@ -88,9 +88,6 @@ @ParametersAreNonnullByDefault public class VanillaWorldGenerator implements IWorldGenerator, IPreloadFailureDelegate { - @Desugar - record FillerInfo(ImmutableBlockMeta filler) {} - @Nonnull private final IChunkProvider vanilla; @Nonnull @@ -98,10 +95,10 @@ record FillerInfo(ImmutableBlockMeta filler) {} @Nonnull private final IWorldDecorator decorator; - private final int worldHeightBlocks; - private final int worldHeightCubes; + private final int vanillaGenerationHeight; + private final int vanillaGenerationHeightCubes; - private FillerInfo bottom, top; + private FillerInfo fillerInfo; /** * Create a new VanillaCompatibilityGenerator @@ -109,13 +106,16 @@ record FillerInfo(ImmutableBlockMeta filler) {} * @param vanilla The vanilla generator to mirror * @param world The world in which cubes are being generated */ - public VanillaWorldGenerator(IChunkProvider vanilla, World world, IWorldDecorator decorator) { + public VanillaWorldGenerator(IChunkProvider vanilla, World world, IWorldDecorator decorator) + { + this.fillerInfo = CubicChunksSavedData.get(world).getFillerInfo(); + this.vanilla = vanilla; this.world = world; this.decorator = decorator; - worldHeightBlocks = ((ICubicWorld) this.world).getMaxGenerationHeight(); - worldHeightCubes = Coords.blockCeilToCube(worldHeightBlocks); + vanillaGenerationHeight = ((ICubicWorld) this.world).getMaxGenerationHeight(); + vanillaGenerationHeightCubes = Coords.blockCeilToCube(vanillaGenerationHeight); } private ICubeLoader getCubeLoader() { @@ -126,19 +126,23 @@ private CubeProviderServer getCubeProviderServer() { return ((ICubicWorldInternal.Server) world).getCubeCache(); } - private FillerInfo getBottomFillerInfo() { - if (bottom != null) return bottom; + private ImmutableBlockMeta getBottomFillerInfo() + { + if (fillerInfo.bottomFiller != null) return fillerInfo.bottomFiller; Chunk chunk = vanilla.provideChunk(0, 0); ((IColumnInternal) chunk).setColumn(false); - bottom = analyzeBottomFiller(new ChunkBlockView(chunk)); + fillerInfo.bottomFiller = analyzeBottomFiller(new ChunkBlockView(chunk)); + + CubicChunksSavedData saveData = CubicChunksSavedData.get(world); + saveData.setBottomFiller(fillerInfo.bottomFiller); - return bottom; + return fillerInfo.bottomFiller; } - private FillerInfo analyzeBottomFiller(IBlockView blockView) { + private ImmutableBlockMeta analyzeBottomFiller(IBlockView blockView) { Object2IntOpenHashMap histogram = new Object2IntOpenHashMap<>(); // Scan three layers for top and bottom cubes to guard against bedrock walls @@ -165,25 +169,27 @@ private FillerInfo analyzeBottomFiller(IBlockView blockView) { }) .max(Comparator.comparingInt(Object2IntMap.Entry::getIntValue)); - ImmutableBlockMeta filler = bottomBlock.map(Map.Entry::getKey) + return bottomBlock.map(Map.Entry::getKey) .orElse(new BlockMeta(Blocks.air, 0)); - - return new FillerInfo(filler); } - private FillerInfo getTopFillerInfo() { - if (top != null) return top; + private ImmutableBlockMeta getTopFillerInfo() + { + if (fillerInfo.topFiller != null) return fillerInfo.topFiller; Chunk chunk = vanilla.provideChunk(0, 0); ((IColumnInternal) chunk).setColumn(false); - top = analyzeTopFiller(new ChunkBlockView(chunk)); + fillerInfo.topFiller = analyzeTopFiller(new ChunkBlockView(chunk)); + + CubicChunksSavedData saveData = CubicChunksSavedData.get(world); + saveData.setTopFiller(fillerInfo.topFiller); - return top; + return fillerInfo.topFiller; } - private FillerInfo analyzeTopFiller(IBlockView blockView) { + private ImmutableBlockMeta analyzeTopFiller(IBlockView blockView) { Object2IntOpenHashMap histogram = new Object2IntOpenHashMap<>(); int top = blockView.getBounds() @@ -205,10 +211,8 @@ private FillerInfo analyzeTopFiller(IBlockView blockView) { .getBlock() != Blocks.bedrock) .max(Comparator.comparingInt(Object2IntMap.Entry::getIntValue)); - ImmutableBlockMeta filler = topBlock.map(Map.Entry::getKey) + return topBlock.map(Map.Entry::getKey) .orElse(new BlockMeta(Blocks.air, 0)); - - return new FillerInfo(filler); } @Override @@ -308,8 +312,8 @@ public GenerationResult provideCube(@Nullable Chunk chunk, int cubeX, int } if (cubeY < 0 || cubeY >= 16) { - FillerInfo fillerInfo = cubeY < 0 ? getBottomFillerInfo() : getTopFillerInfo(); - IBlockView cubeData = new UniformBlockView(fillerInfo.filler); + ImmutableBlockMeta filler = cubeY < 0 ? getBottomFillerInfo() : getTopFillerInfo(); + IBlockView cubeData = new UniformBlockView(filler); Cube cube = new Cube(chunk, cubeY, cubeData); @@ -362,7 +366,7 @@ private Pair getVanillaChunkView(int cubeX, int cubeZ) { wrapBlockArray(compatBlocks), wrapByteArray(compatBlockMeta)); - view = new SafeMutableBlockView(Box.horizontalChunkSlice(0, worldHeightBlocks), view); + view = new SafeMutableBlockView(Box.horizontalChunkSlice(0, vanillaGenerationHeight), view); return Pair.of(chunk, view); } From aa048c454088f67ac731b8c6b48738ece016cc4e Mon Sep 17 00:00:00 2001 From: rjnasers Date: Sun, 19 Apr 2026 19:39:15 +0200 Subject: [PATCH 2/5] Should be mostly working now --- .../common/MixinNetHandlerPlayServer.java | 26 ++++++---- .../network/PacketEncoderCubes.java | 1 - .../server/CubeProviderServer.java | 18 ++++--- .../server/CubicPlayerManager.java | 5 +- .../server/chunkio/CubeLoaderServer.java | 50 ++++++++++++++++++- .../cubicchunks/visibility/CubeSelector.java | 4 ++ .../visibility/CuboidalCubeSelector.java | 6 ++- .../cubicchunks/world/cube/BlankCube.java | 42 ---------------- .../cubicchunks/world/cube/BoundaryCube.java | 18 +++++++ 9 files changed, 105 insertions(+), 65 deletions(-) create mode 100644 src/main/java/com/cardinalstar/cubicchunks/world/cube/BoundaryCube.java diff --git a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java index 26f0e8c9..3b0967b3 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java @@ -1,6 +1,9 @@ package com.cardinalstar.cubicchunks.mixin.early.common; import com.cardinalstar.cubicchunks.world.api.IMinMaxHeight; +import com.llamalad7.mixinextras.expression.Definition; +import com.llamalad7.mixinextras.expression.Expression; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; @@ -21,13 +24,6 @@ @Mixin(NetHandlerPlayServer.class) public class MixinNetHandlerPlayServer { -// @Redirect( -// method = "processPlayerBlockPlacement", -// at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getBuildLimit()I")) -// public int noopHeightChecks(MinecraftServer instance) { -// return Integer.MAX_VALUE; -// } - @Shadow public EntityPlayerMP playerEntity; @@ -43,14 +39,14 @@ private boolean preventLowPlacement(ItemInWorldManager manager, EntityPlayer pla int side, float hitX, float hitY, float hitZ, @Local(type = WorldServer.class) WorldServer server) { - if (y < ((IMinMaxHeight)server).getMinHeight()) { + if (y < ((IMinMaxHeight)server).getMinHeight() + 1 && (side == 0 || y < ((IMinMaxHeight)server).getMinHeight())) { ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("build.tooLow", ((IMinMaxHeight) server).getMinHeight()); chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.RED); this.playerEntity.playerNetServerHandler.sendPacket(new S02PacketChat(chatcomponenttranslation)); return false; } - return manager.activateBlockOrUseItem(player, world, stack, x, y, z, side, hitX, hitY, hitZ); + return !manager.activateBlockOrUseItem(player, world, stack, x, y, z, side, hitX, hitY, hitZ); } @Redirect( @@ -60,4 +56,16 @@ public int noopHeightChecks(MinecraftServer instance, @Local(type = WorldServer. { return ((IMinMaxHeight)server).getMaxHeight(); } + + @Definition(id = "serverController", field = "Lnet/minecraft/network/NetHandlerPlayServer;serverController:Lnet/minecraft/server/MinecraftServer;") + @Definition(id = "getBuildLimit", method = "Lnet/minecraft/server/MinecraftServer;getBuildLimit()I") + @Expression("? >= this.serverController.getBuildLimit()") + @ModifyExpressionValue( + method = "processPlayerDigging", + at = @At("MIXINEXTRAS:EXPRESSION") + ) + public boolean setDimensionalBounds(boolean original, @Local(type = WorldServer.class) WorldServer server, @Local(type = int.class, name = "j") int j) + { + return j >= ((IMinMaxHeight) server).getMaxHeight() || j < ((IMinMaxHeight) server).getMinHeight(); + } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/network/PacketEncoderCubes.java b/src/main/java/com/cardinalstar/cubicchunks/network/PacketEncoderCubes.java index da5b7697..5acabff0 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/network/PacketEncoderCubes.java +++ b/src/main/java/com/cardinalstar/cubicchunks/network/PacketEncoderCubes.java @@ -139,7 +139,6 @@ public void process(World world, PacketCubes packet) { for (CubePos pos : packet.cubePos) { Cube cube = cubeCache.loadCube(pos); // new cube - // isEmpty actually checks if the column is a BlankColumn if (cube == null) { CubicChunks.LOGGER.error("Out of order cube received! No column for cube at {} exists!", pos); } diff --git a/src/main/java/com/cardinalstar/cubicchunks/server/CubeProviderServer.java b/src/main/java/com/cardinalstar/cubicchunks/server/CubeProviderServer.java index 5fddbe5b..a035a52d 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/server/CubeProviderServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/server/CubeProviderServer.java @@ -38,6 +38,7 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.profiler.Profiler; @@ -123,7 +124,6 @@ public CubeProviderServer(WorldServer worldServer, IChunkLoader chunkLoader, IWo worldServer.provider.createChunkGenerator()); // let's create the chunk generator, for now the vanilla one // may be enough - // this.cubePrimer = new CubePrimer(); this.worldGenerator = worldGenerator; this.worldServer = worldServer; this.profiler = worldServer.theProfiler; @@ -363,8 +363,7 @@ private void doEagerLoading() { cubeLoader.pauseLoadCalls(); - Cube cube = cubeLoader - .getCube(request.pos.getX(), request.pos.getY(), request.pos.getZ(), request.effort); + Cube cube = cubeLoader.getCube(request.pos.getX(), request.pos.getY(), request.pos.getZ(), request.effort); cubeLoader.unpauseLoadCalls(); @@ -536,7 +535,8 @@ public int getZ() { } } - public EagerCubeLoadRequest loadCubeEagerly(int x, int y, int z, Requirement effort) { + public EagerCubeLoadRequest loadCubeEagerly(int x, int y, int z, Requirement effort) + { CubePos pos = new CubePos(x, y, z); ChunkCoordIntPair coord = new ChunkCoordIntPair(x, z); @@ -560,20 +560,22 @@ public EagerCubeLoadRequest loadCubeEagerly(int x, int y, int z, Requirement eff @Nullable @Override - public Cube getCube(int cubeX, int cubeY, int cubeZ, Requirement effort) { + public Cube getCube(int cubeX, int cubeY, int cubeZ, Requirement effort) + { Cube cube = cubeLoader.getCube(cubeX, cubeY, cubeZ, effort); - return cube == null ? emptyCube : cube; } @Override - public boolean cubeExists(int cubeX, int cubeY, int cubeZ) { + public boolean cubeExists(int cubeX, int cubeY, int cubeZ) + { return cubeLoader.cubeExists(cubeX, cubeY, cubeZ); } @Nullable @Override - public Chunk getColumn(int columnX, int columnZ, Requirement effort) { + public Chunk getColumn(int columnX, int columnZ, Requirement effort) + { return cubeLoader.getColumn(columnX, columnZ, effort); } diff --git a/src/main/java/com/cardinalstar/cubicchunks/server/CubicPlayerManager.java b/src/main/java/com/cardinalstar/cubicchunks/server/CubicPlayerManager.java index 6eaaa441..9c3b442f 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/server/CubicPlayerManager.java +++ b/src/main/java/com/cardinalstar/cubicchunks/server/CubicPlayerManager.java @@ -33,6 +33,7 @@ import javax.annotation.ParametersAreNonnullByDefault; +import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.Packet; import net.minecraft.server.management.PlayerManager; @@ -126,8 +127,8 @@ public CubicPlayerManager(WorldServer worldServer) { ((ICubicPlayerList) worldServer.func_73046_m() .getConfigurationManager()).getVerticalViewDistance()); - provider = ((Server) worldServer).getCubeCache(); - provider.registerCallback(this); + this.provider = ((Server) worldServer).getCubeCache(); + this.provider.registerCallback(this); } public Collection getColumns() { diff --git a/src/main/java/com/cardinalstar/cubicchunks/server/chunkio/CubeLoaderServer.java b/src/main/java/com/cardinalstar/cubicchunks/server/chunkio/CubeLoaderServer.java index 79d55dd2..c4fd4a17 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/server/chunkio/CubeLoaderServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/server/chunkio/CubeLoaderServer.java @@ -6,6 +6,9 @@ import java.util.ArrayList; import java.util.List; +import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; +import com.cardinalstar.cubicchunks.world.column.EmptyColumn; +import com.cardinalstar.cubicchunks.world.cube.BoundaryCube; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.WorldServer; @@ -37,6 +40,8 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import lombok.Setter; +import javax.annotation.Nonnull; + public class CubeLoaderServer implements ICubeLoader { private static final MetaKey CUBE_INFO = new MetaKey<>() {}; @@ -57,12 +62,28 @@ public class CubeLoaderServer implements ICubeLoader { @Setter private long now; + private final int maxCube; + private final int minCube; + + @Nonnull + private final EmptyColumn emptyColumn; + @Nonnull + private final BlankCube emptyCube; + public CubeLoaderServer(WorldServer world, ICubicStorage storage, IWorldGenerator generator, CubeLoaderCallback callback) { this.world = world; this.cubeIO = new CubeIO(storage, generator instanceof IPreloadFailureDelegate delegate ? delegate : null); this.generator = generator; this.callback = callback; + + CubicChunksSavedData data =CubicChunksSavedData.get(world); + + this.minCube = data.minHeight >> 4; + this.maxCube = (data.maxHeight - 1) >> 4; + + this.emptyColumn = new EmptyColumn(world, 0, 0); + this.emptyCube = new BlankCube(emptyColumn); } @Override @@ -458,7 +479,8 @@ private enum ObjectSource { None, Disk, Generated, - GeneratedSideEffect + GeneratedSideEffect, + Boundary } private class ColumnInfo implements XZAddressable { @@ -606,6 +628,12 @@ public int getZ() { } public boolean initialize(Requirement effort) throws IOException { + if (pos.getY() < minCube || pos.getY() > maxCube) + { + loadBoundaryCube(); + return true; + } + if (effort == Requirement.GET_CACHED) { return cube != null; } @@ -634,6 +662,26 @@ public boolean initialize(Requirement effort) throws IOException { return generate(requestedInitLevel); } + private void loadBoundaryCube() + { + ensureColumn(Requirement.LOAD); + + if (this.column == null) { + CubicChunks.LOGGER.error( + "Tried to load a cube that did not have a saved column: it will be regenerated ({},{},{})", + getX(), + getY(), + getZ(), + new Exception()); + this.cube = null; + this.tag = null; + return; + } + + this.cube = new BoundaryCube(this.column.column, this.getY()); + onCubeLoaded(); + } + private boolean loadNBT() { if (tag != null) return true; diff --git a/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java b/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java index ba21d1af..5dad1549 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java +++ b/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java @@ -32,13 +32,17 @@ @ParametersAreNonnullByDefault public abstract class CubeSelector { + /// For all cube positions visible from an input cubePos and view distances give it to a consumer public abstract void forAllVisibleFrom(CubePos cubePos, int horizontalViewDistance, int verticalViewDistance, Consumer consumer); + /// Find the difference in current position given view distances and the old position in terms of what cubes need to be removed + /// or added public abstract void findChanged(CubePos oldAddress, CubePos newAddress, int horizontalViewDistance, int verticalViewDistance, Set cubesToRemove, Set cubesToLoad, Set columnsToRemove, Set columnsToLoad); + /// Find what cubes need to be removed given a view distance decrease public abstract void findAllUnloadedOnViewDistanceDecrease(CubePos playerAddress, int oldHorizontalViewDistance, int newHorizontalViewDistance, int oldVerticalViewDistance, int newVerticalViewDistance, Set cubesToUnload, Set columnsToUnload); diff --git a/src/main/java/com/cardinalstar/cubicchunks/visibility/CuboidalCubeSelector.java b/src/main/java/com/cardinalstar/cubicchunks/visibility/CuboidalCubeSelector.java index 361e40d6..60568245 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/visibility/CuboidalCubeSelector.java +++ b/src/main/java/com/cardinalstar/cubicchunks/visibility/CuboidalCubeSelector.java @@ -104,7 +104,8 @@ public void findChanged(CubePos oldPos, CubePos newPos, int horizontalViewDistan currentY, currentZ, horizontalViewDistance, - verticalViewDistance)) { + verticalViewDistance)) + { cubesToLoad.add(new CubePos(currentX, currentY, currentZ)); } if (!this.isPointWithinCubeVolume( @@ -115,7 +116,8 @@ public void findChanged(CubePos oldPos, CubePos newPos, int horizontalViewDistan currentY - dy, currentZ - dz, horizontalViewDistance, - verticalViewDistance)) { + verticalViewDistance)) + { cubesToRemove.add(new CubePos(currentX - dx, currentY - dy, currentZ - dz)); } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/world/cube/BlankCube.java b/src/main/java/com/cardinalstar/cubicchunks/world/cube/BlankCube.java index 02df6c20..538bdbe9 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/world/cube/BlankCube.java +++ b/src/main/java/com/cardinalstar/cubicchunks/world/cube/BlankCube.java @@ -57,51 +57,9 @@ public boolean isEmpty() { return true; } - // @Override - // public boolean containsBlockPos(BlockPos blockPos) { - // return false; - // } - // - // @Override - // public IBlockState getBlockState(BlockPos pos) { - // return Blocks.AIR.getDefaultState(); - // } - // - // @Override - // public IBlockState getBlockState(int blockX, int localOrBlockY, int blockZ) { - // return Blocks.AIR.getDefaultState(); - // } - // - // @Nullable @Override - // public TileEntity getTileEntity(BlockPos pos, Chunk.EnumCreateEntityType creationType) { - // return null; - // } - // @Override public void onCubeLoad() {} @Override public void onCubeUnload() {} - // - // @Override - // public boolean needsSaving() { - // return false; - // } - // - // @Override - // public void markSaved() { - // } - // - // @Override - // public int getLightFor(EnumSkyBlock lightType, BlockPos pos) { - // return lightType.defaultLightValue; - // } - // - // @Override - // public void setLightFor(EnumSkyBlock lightType, BlockPos pos, int light) { - // } - // - // @Override - // public void markForRenderUpdate() { - // } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/world/cube/BoundaryCube.java b/src/main/java/com/cardinalstar/cubicchunks/world/cube/BoundaryCube.java new file mode 100644 index 00000000..707737aa --- /dev/null +++ b/src/main/java/com/cardinalstar/cubicchunks/world/cube/BoundaryCube.java @@ -0,0 +1,18 @@ +package com.cardinalstar.cubicchunks.world.cube; + + +import com.cardinalstar.cubicchunks.server.chunkio.CubeInitLevel; +import net.minecraft.world.chunk.Chunk; + +public class BoundaryCube extends Cube +{ + public BoundaryCube(Chunk column, int cubeY) { + super(column, cubeY); + } + + /// Boundary cubes are always considered to be lit. + public CubeInitLevel getInitLevel() + { + return CubeInitLevel.Lit; + } +} From ec1b866313c815478d16e494687fd22278ee0df3 Mon Sep 17 00:00:00 2001 From: rjnasers Date: Sun, 19 Apr 2026 22:16:15 +0200 Subject: [PATCH 3/5] Fixing some lang stuff --- .../mixin/early/common/MixinNetHandlerPlayServer.java | 2 +- src/main/resources/assets/cubicchunks/lang/en_US.lang | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java index 3b0967b3..c0a97160 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java @@ -40,7 +40,7 @@ private boolean preventLowPlacement(ItemInWorldManager manager, EntityPlayer pla @Local(type = WorldServer.class) WorldServer server) { if (y < ((IMinMaxHeight)server).getMinHeight() + 1 && (side == 0 || y < ((IMinMaxHeight)server).getMinHeight())) { - ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("build.tooLow", ((IMinMaxHeight) server).getMinHeight()); + ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("cubicchunks.build.too.low", ((IMinMaxHeight) server).getMinHeight()); chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.RED); this.playerEntity.playerNetServerHandler.sendPacket(new S02PacketChat(chatcomponenttranslation)); return false; diff --git a/src/main/resources/assets/cubicchunks/lang/en_US.lang b/src/main/resources/assets/cubicchunks/lang/en_US.lang index e3b55d7b..f2388bed 100644 --- a/src/main/resources/assets/cubicchunks/lang/en_US.lang +++ b/src/main/resources/assets/cubicchunks/lang/en_US.lang @@ -31,3 +31,9 @@ cubicchunks.config.optimizations=Optimizations cubicchunks.config.optimizations.background_threads=Background Threads generator.VanillaCubic=Vanilla + Cubic + +################################# +### misc ### +################################# + +cubicchunks.build.too.low=Minimum building depth reached From db283797b60ceca48e75bea5ca16db0b51a5fed0 Mon Sep 17 00:00:00 2001 From: rjnasers Date: Sun, 19 Apr 2026 22:18:41 +0200 Subject: [PATCH 4/5] spotless --- .../cardinalstar/cubicchunks/CubicChunks.java | 8 +- .../cubicchunks/CubicChunksConfig.java | 118 ++++++------------ .../worldgen/decoration/IWorldDecorator.java | 1 - .../early/common/MixinMinecraftServer.java | 13 +- .../common/MixinNetHandlerPlayServer.java | 52 ++++---- .../server/CubeProviderServer.java | 16 +-- .../server/CubicPlayerManager.java | 1 - .../server/ICubicChunksServer.java | 4 +- .../server/chunkio/CubeLoaderServer.java | 18 ++- .../cubicchunks/visibility/CubeSelector.java | 3 +- .../visibility/CuboidalCubeSelector.java | 6 +- .../world/CubicChunksSavedData.java | 47 +++---- .../cubicchunks/world/cube/BoundaryCube.java | 11 +- .../cubicchunks/worldgen/FillerInfo.java | 8 +- .../cubicchunks/worldgen/HeightInfo.java | 4 +- .../worldgen/VanillaWorldGenerator.java | 14 +-- 16 files changed, 127 insertions(+), 197 deletions(-) diff --git a/src/main/java/com/cardinalstar/cubicchunks/CubicChunks.java b/src/main/java/com/cardinalstar/cubicchunks/CubicChunks.java index adfa2b35..abfb05c1 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/CubicChunks.java +++ b/src/main/java/com/cardinalstar/cubicchunks/CubicChunks.java @@ -20,8 +20,6 @@ */ package com.cardinalstar.cubicchunks; -import static com.cardinalstar.cubicchunks.util.ReflectionUtil.cast; - import java.io.IOException; import java.nio.file.Path; import java.util.Map; @@ -30,8 +28,6 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; -import com.cardinalstar.cubicchunks.server.ICubicChunksServer; -import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; import net.minecraft.server.MinecraftServer; import net.minecraft.world.World; import net.minecraft.world.WorldServer; @@ -48,9 +44,8 @@ import com.cardinalstar.cubicchunks.async.TaskPool; import com.cardinalstar.cubicchunks.event.handlers.ClientEventHandler; import com.cardinalstar.cubicchunks.event.handlers.CommonEventHandler; -import com.cardinalstar.cubicchunks.mixin.api.ICubicWorldSettings; -import com.cardinalstar.cubicchunks.mixin.early.common.IIntegratedServer; import com.cardinalstar.cubicchunks.network.NetworkChannel; +import com.cardinalstar.cubicchunks.server.ICubicChunksServer; import com.cardinalstar.cubicchunks.server.chunkio.RegionCubeStorage; import com.cardinalstar.cubicchunks.util.CompatHandler; import com.cardinalstar.cubicchunks.util.Mods; @@ -69,7 +64,6 @@ import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLServerAboutToStartEvent; -import cpw.mods.fml.common.event.FMLServerStartingEvent; import cpw.mods.fml.common.network.NetworkCheckHandler; import cpw.mods.fml.common.network.NetworkRegistry; import cpw.mods.fml.common.network.internal.NetworkModHolder; diff --git a/src/main/java/com/cardinalstar/cubicchunks/CubicChunksConfig.java b/src/main/java/com/cardinalstar/cubicchunks/CubicChunksConfig.java index ce397d05..f216e119 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/CubicChunksConfig.java +++ b/src/main/java/com/cardinalstar/cubicchunks/CubicChunksConfig.java @@ -22,46 +22,21 @@ package com.cardinalstar.cubicchunks; import java.lang.management.ManagementFactory; -import java.lang.reflect.Field; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Set; -import java.util.function.Predicate; -import java.util.regex.Pattern; -import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import net.minecraft.block.Block; + import com.cardinalstar.cubicchunks.worldgen.FillerInfo; import com.cardinalstar.cubicchunks.worldgen.HeightInfo; -import com.gtnewhorizon.gtnhlib.config.ConfigException; -import com.gtnewhorizon.gtnhlib.util.data.BlockMeta; -import cpw.mods.fml.common.registry.GameRegistry; -import net.minecraft.block.Block; -import net.minecraft.client.resources.I18n; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; -import net.minecraft.command.WrongUsageException; -import net.minecraft.util.ChatComponentTranslation; - -import com.cardinalstar.cubicchunks.command.CubicCommandBase; -import com.cardinalstar.cubicchunks.command.SubCommandBase; -import com.google.common.collect.BoundType; -import com.google.common.collect.Range; -import com.google.common.collect.TreeRangeSet; import com.gtnewhorizon.gtnhlib.config.Config; +import com.gtnewhorizon.gtnhlib.config.ConfigException; import com.gtnewhorizon.gtnhlib.config.ConfigurationManager; +import com.gtnewhorizon.gtnhlib.util.data.BlockMeta; -import cpw.mods.fml.client.event.ConfigChangedEvent; -import cpw.mods.fml.common.event.FMLServerStartingEvent; -import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.registry.GameRegistry; @ParametersAreNonnullByDefault @Config(modid = CubicChunks.MODID, category = "general") @@ -89,7 +64,8 @@ public class CubicChunksConfig { + "Spaces and tabs are not necessary. NEI is a good tool for this if you don't know the meta and resource location of blocks. (f3 + H)\n" + "It's highly recommend to define these, as block are chosen before population is done on chunks, meaning that if bottom layers are normally\n" + "populated to some block it might be missed.") - public static String[] default_filler_blocks = { "0:bottom:minecraft:stone", "0:top:minecraft:air", "-1:both:minecraft:netherrack", "1:both:minecraft:air"}; + public static String[] default_filler_blocks = { "0:bottom:minecraft:stone", "0:top:minecraft:air", + "-1:both:minecraft:netherrack", "1:both:minecraft:air" }; @Config.Ignore public static Map configuredDimensionalHeightMap = new HashMap<>(); @@ -194,8 +170,7 @@ public static final class Optimizations { modMaxCubesPerChunkloadingTicket.put("cubicchunks", defaultMaxCubesPerChunkloadingTicket); } - public static void init() throws ConfigException - { + public static void init() throws ConfigException { validateConfigValues(); initDimensionalConfiguration(); } @@ -220,16 +195,13 @@ private static void validateConfigValues() { private static void initDimensionalConfiguration() throws ConfigException { // Height Limit Configs int i = 1; - for (String config : dimensional_height_overrides) - { + for (String config : dimensional_height_overrides) { String[] entries = config.split(":"); - if (entries.length != 3) - { + if (entries.length != 3) { throw new ConfigException("Dimensional Height Overrides configuration is malformed for entry: " + i); } - try - { + try { int dimension = Integer.parseInt(entries[0]); int height = Integer.parseInt(entries[2]); if ((height & 0xF) != 0) { @@ -243,31 +215,26 @@ private static void initDimensionalConfiguration() throws ConfigException { HeightInfo info = configuredDimensionalHeightMap.getOrDefault(dimension, new HeightInfo()); String direction = entries[1]; - if (direction.equals("bottom")) - { + if (direction.equals("bottom")) { info.minHeight = height; - if (info.maxHeight == null) - { + if (info.maxHeight == null) { info.maxHeight = defaultMaxHeight; } - } - else if (direction.equals("top")) - { + } else if (direction.equals("top")) { info.maxHeight = height; - if (info.minHeight == null) - { + if (info.minHeight == null) { info.minHeight = defaultMinHeight; } - } - else - { - throw new ConfigException("Directional argument for height limits is invalid for entry: " + i + ". Invalid:" + direction + " Valid directions bottom and top."); + } else { + throw new ConfigException( + "Directional argument for height limits is invalid for entry: " + i + + ". Invalid:" + + direction + + " Valid directions bottom and top."); } configuredDimensionalHeightMap.put(dimension, info); - } - catch (NumberFormatException e) - { + } catch (NumberFormatException e) { throw new ConfigException("Dimensional Height Overrides configuration is malformed for entry: " + i); } i++; @@ -275,47 +242,44 @@ else if (direction.equals("top")) i = 1; // Filler Configs - for (String config : default_filler_blocks) - { + for (String config : default_filler_blocks) { String[] entries = config.split(":"); - if (entries.length != 4 && entries.length != 5) - { + if (entries.length != 4 && entries.length != 5) { throw new ConfigException("Dimensional Filler block configuration is malformed for entry: " + i); } try { int dimension = Integer.parseInt(entries[0]); Block fillerBlock = GameRegistry.findBlock(entries[2], entries[3]); - if (fillerBlock == null) - { - throw new ConfigException("Dimensional Height Overrides configuration is malformed for entry: " + i + ". Block not found for resource location " + entries[2] + ":" + entries[3]); + if (fillerBlock == null) { + throw new ConfigException( + "Dimensional Height Overrides configuration is malformed for entry: " + i + + ". Block not found for resource location " + + entries[2] + + ":" + + entries[3]); } int meta = entries.length == 4 ? 0 : Integer.parseInt(entries[4]); FillerInfo info = configuredDimensionalFillerMap.getOrDefault(dimension, new FillerInfo()); String direction = entries[1]; - if (direction.equals("bottom")) - { + if (direction.equals("bottom")) { info.bottomFiller = new BlockMeta(fillerBlock, meta); - } - else if (direction.equals("top")) - { + } else if (direction.equals("top")) { info.topFiller = new BlockMeta(fillerBlock, meta); - } - else if (direction.equals("both")) - { + } else if (direction.equals("both")) { info.bottomFiller = new BlockMeta(fillerBlock, meta); info.topFiller = new BlockMeta(fillerBlock, meta); - } - else - { - throw new ConfigException("Directional argument for filler blocks is invalid for entry: " + i + ". Invalid:" + direction + " Valid directions are both, bottom, and top."); + } else { + throw new ConfigException( + "Directional argument for filler blocks is invalid for entry: " + i + + ". Invalid:" + + direction + + " Valid directions are both, bottom, and top."); } configuredDimensionalFillerMap.put(dimension, info); - } - catch (NumberFormatException e) - { + } catch (NumberFormatException e) { throw new ConfigException("Dimensional filler default configuration is malformed for entry: " + i); } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/api/worldgen/decoration/IWorldDecorator.java b/src/main/java/com/cardinalstar/cubicchunks/api/worldgen/decoration/IWorldDecorator.java index 2f9f1bb0..4357175d 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/api/worldgen/decoration/IWorldDecorator.java +++ b/src/main/java/com/cardinalstar/cubicchunks/api/worldgen/decoration/IWorldDecorator.java @@ -1,6 +1,5 @@ package com.cardinalstar.cubicchunks.api.worldgen.decoration; -import com.cardinalstar.cubicchunks.api.worldgen.impl.StandardWorldDecorator; import net.minecraft.world.World; import com.cardinalstar.cubicchunks.util.CubePos; diff --git a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinMinecraftServer.java b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinMinecraftServer.java index e59f543d..982dbc0b 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinMinecraftServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinMinecraftServer.java @@ -20,7 +20,6 @@ */ package com.cardinalstar.cubicchunks.mixin.early.common; -import com.cardinalstar.cubicchunks.server.ICubicChunksServer; import net.minecraft.server.MinecraftServer; import net.minecraft.world.World; import net.minecraftforge.common.DimensionManager; @@ -32,15 +31,15 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.cardinalstar.cubicchunks.mixin.api.ICubicWorldInternal; +import com.cardinalstar.cubicchunks.server.ICubicChunksServer; import com.cardinalstar.cubicchunks.server.SpawnCubes; @Mixin(MinecraftServer.class) -public class MixinMinecraftServer implements ICubicChunksServer -{ +public class MixinMinecraftServer implements ICubicChunksServer { + @Unique private int cubicChunks$buildMinimum; - @Inject(method = "initialWorldChunkLoad", at = @At("HEAD"), cancellable = true) private void onInitialSpawnLoad(CallbackInfo ci) { World world = DimensionManager.getWorld(0); @@ -51,14 +50,12 @@ private void onInitialSpawnLoad(CallbackInfo ci) { } @Override - public void setBuildMinimum(int minBuildHeight) - { + public void setBuildMinimum(int minBuildHeight) { cubicChunks$buildMinimum = minBuildHeight; } @Override - public int getBuildMinimum() - { + public int getBuildMinimum() { return cubicChunks$buildMinimum; } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java index c0a97160..9efb61f5 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/mixin/early/common/MixinNetHandlerPlayServer.java @@ -1,10 +1,5 @@ package com.cardinalstar.cubicchunks.mixin.early.common; -import com.cardinalstar.cubicchunks.world.api.IMinMaxHeight; -import com.llamalad7.mixinextras.expression.Definition; -import com.llamalad7.mixinextras.expression.Expression; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; -import com.llamalad7.mixinextras.sugar.Local; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; @@ -16,11 +11,18 @@ import net.minecraft.util.EnumChatFormatting; import net.minecraft.world.World; import net.minecraft.world.WorldServer; + import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; +import com.cardinalstar.cubicchunks.world.api.IMinMaxHeight; +import com.llamalad7.mixinextras.expression.Definition; +import com.llamalad7.mixinextras.expression.Expression; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.sugar.Local; + @Mixin(NetHandlerPlayServer.class) public class MixinNetHandlerPlayServer { @@ -31,17 +33,17 @@ public class MixinNetHandlerPlayServer { method = "processPlayerBlockPlacement", at = @At( value = "INVOKE", - target = "Lnet/minecraft/server/management/ItemInWorldManager;activateBlockOrUseItem(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;IIIIFFF)Z" - ) - ) - private boolean preventLowPlacement(ItemInWorldManager manager, EntityPlayer player, World world, - ItemStack stack, int x, int y, int z, - int side, float hitX, float hitY, float hitZ, - @Local(type = WorldServer.class) WorldServer server) - { - if (y < ((IMinMaxHeight)server).getMinHeight() + 1 && (side == 0 || y < ((IMinMaxHeight)server).getMinHeight())) { - ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("cubicchunks.build.too.low", ((IMinMaxHeight) server).getMinHeight()); - chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.RED); + target = "Lnet/minecraft/server/management/ItemInWorldManager;activateBlockOrUseItem(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;Lnet/minecraft/item/ItemStack;IIIIFFF)Z")) + private boolean preventLowPlacement(ItemInWorldManager manager, EntityPlayer player, World world, ItemStack stack, + int x, int y, int z, int side, float hitX, float hitY, float hitZ, + @Local(type = WorldServer.class) WorldServer server) { + if (y < ((IMinMaxHeight) server).getMinHeight() + 1 + && (side == 0 || y < ((IMinMaxHeight) server).getMinHeight())) { + ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation( + "cubicchunks.build.too.low", + ((IMinMaxHeight) server).getMinHeight()); + chatcomponenttranslation.getChatStyle() + .setColor(EnumChatFormatting.RED); this.playerEntity.playerNetServerHandler.sendPacket(new S02PacketChat(chatcomponenttranslation)); return false; } @@ -52,20 +54,18 @@ private boolean preventLowPlacement(ItemInWorldManager manager, EntityPlayer pla @Redirect( method = "processPlayerBlockPlacement", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getBuildLimit()I")) - public int noopHeightChecks(MinecraftServer instance, @Local(type = WorldServer.class) WorldServer server) - { - return ((IMinMaxHeight)server).getMaxHeight(); + public int noopHeightChecks(MinecraftServer instance, @Local(type = WorldServer.class) WorldServer server) { + return ((IMinMaxHeight) server).getMaxHeight(); } - @Definition(id = "serverController", field = "Lnet/minecraft/network/NetHandlerPlayServer;serverController:Lnet/minecraft/server/MinecraftServer;") + @Definition( + id = "serverController", + field = "Lnet/minecraft/network/NetHandlerPlayServer;serverController:Lnet/minecraft/server/MinecraftServer;") @Definition(id = "getBuildLimit", method = "Lnet/minecraft/server/MinecraftServer;getBuildLimit()I") @Expression("? >= this.serverController.getBuildLimit()") - @ModifyExpressionValue( - method = "processPlayerDigging", - at = @At("MIXINEXTRAS:EXPRESSION") - ) - public boolean setDimensionalBounds(boolean original, @Local(type = WorldServer.class) WorldServer server, @Local(type = int.class, name = "j") int j) - { + @ModifyExpressionValue(method = "processPlayerDigging", at = @At("MIXINEXTRAS:EXPRESSION")) + public boolean setDimensionalBounds(boolean original, @Local(type = WorldServer.class) WorldServer server, + @Local(type = int.class, name = "j") int j) { return j >= ((IMinMaxHeight) server).getMaxHeight() || j < ((IMinMaxHeight) server).getMinHeight(); } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/server/CubeProviderServer.java b/src/main/java/com/cardinalstar/cubicchunks/server/CubeProviderServer.java index a035a52d..94d7e6b9 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/server/CubeProviderServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/server/CubeProviderServer.java @@ -38,7 +38,6 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; -import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; import net.minecraft.entity.EnumCreatureType; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.profiler.Profiler; @@ -363,7 +362,8 @@ private void doEagerLoading() { cubeLoader.pauseLoadCalls(); - Cube cube = cubeLoader.getCube(request.pos.getX(), request.pos.getY(), request.pos.getZ(), request.effort); + Cube cube = cubeLoader + .getCube(request.pos.getX(), request.pos.getY(), request.pos.getZ(), request.effort); cubeLoader.unpauseLoadCalls(); @@ -535,8 +535,7 @@ public int getZ() { } } - public EagerCubeLoadRequest loadCubeEagerly(int x, int y, int z, Requirement effort) - { + public EagerCubeLoadRequest loadCubeEagerly(int x, int y, int z, Requirement effort) { CubePos pos = new CubePos(x, y, z); ChunkCoordIntPair coord = new ChunkCoordIntPair(x, z); @@ -560,22 +559,19 @@ public EagerCubeLoadRequest loadCubeEagerly(int x, int y, int z, Requirement eff @Nullable @Override - public Cube getCube(int cubeX, int cubeY, int cubeZ, Requirement effort) - { + public Cube getCube(int cubeX, int cubeY, int cubeZ, Requirement effort) { Cube cube = cubeLoader.getCube(cubeX, cubeY, cubeZ, effort); return cube == null ? emptyCube : cube; } @Override - public boolean cubeExists(int cubeX, int cubeY, int cubeZ) - { + public boolean cubeExists(int cubeX, int cubeY, int cubeZ) { return cubeLoader.cubeExists(cubeX, cubeY, cubeZ); } @Nullable @Override - public Chunk getColumn(int columnX, int columnZ, Requirement effort) - { + public Chunk getColumn(int columnX, int columnZ, Requirement effort) { return cubeLoader.getColumn(columnX, columnZ, effort); } diff --git a/src/main/java/com/cardinalstar/cubicchunks/server/CubicPlayerManager.java b/src/main/java/com/cardinalstar/cubicchunks/server/CubicPlayerManager.java index 9c3b442f..af3a54b1 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/server/CubicPlayerManager.java +++ b/src/main/java/com/cardinalstar/cubicchunks/server/CubicPlayerManager.java @@ -33,7 +33,6 @@ import javax.annotation.ParametersAreNonnullByDefault; -import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.network.Packet; import net.minecraft.server.management.PlayerManager; diff --git a/src/main/java/com/cardinalstar/cubicchunks/server/ICubicChunksServer.java b/src/main/java/com/cardinalstar/cubicchunks/server/ICubicChunksServer.java index b4acc6dc..35e84297 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/server/ICubicChunksServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/server/ICubicChunksServer.java @@ -1,7 +1,7 @@ package com.cardinalstar.cubicchunks.server; -public interface ICubicChunksServer -{ +public interface ICubicChunksServer { + void setBuildMinimum(int minBuildHeight); int getBuildMinimum(); diff --git a/src/main/java/com/cardinalstar/cubicchunks/server/chunkio/CubeLoaderServer.java b/src/main/java/com/cardinalstar/cubicchunks/server/chunkio/CubeLoaderServer.java index c4fd4a17..d080c182 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/server/chunkio/CubeLoaderServer.java +++ b/src/main/java/com/cardinalstar/cubicchunks/server/chunkio/CubeLoaderServer.java @@ -6,9 +6,8 @@ import java.util.ArrayList; import java.util.List; -import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; -import com.cardinalstar.cubicchunks.world.column.EmptyColumn; -import com.cardinalstar.cubicchunks.world.cube.BoundaryCube; +import javax.annotation.Nonnull; + import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.WorldServer; @@ -32,16 +31,17 @@ import com.cardinalstar.cubicchunks.util.Array3D; import com.cardinalstar.cubicchunks.util.CubePos; import com.cardinalstar.cubicchunks.util.XZAddressable; +import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; import com.cardinalstar.cubicchunks.world.api.ICubeProviderServer.Requirement; +import com.cardinalstar.cubicchunks.world.column.EmptyColumn; import com.cardinalstar.cubicchunks.world.core.IColumnInternal; import com.cardinalstar.cubicchunks.world.cube.BlankCube; +import com.cardinalstar.cubicchunks.world.cube.BoundaryCube; import com.cardinalstar.cubicchunks.world.cube.Cube; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import lombok.Setter; -import javax.annotation.Nonnull; - public class CubeLoaderServer implements ICubeLoader { private static final MetaKey CUBE_INFO = new MetaKey<>() {}; @@ -77,7 +77,7 @@ public CubeLoaderServer(WorldServer world, ICubicStorage storage, IWorldGenerato this.generator = generator; this.callback = callback; - CubicChunksSavedData data =CubicChunksSavedData.get(world); + CubicChunksSavedData data = CubicChunksSavedData.get(world); this.minCube = data.minHeight >> 4; this.maxCube = (data.maxHeight - 1) >> 4; @@ -628,8 +628,7 @@ public int getZ() { } public boolean initialize(Requirement effort) throws IOException { - if (pos.getY() < minCube || pos.getY() > maxCube) - { + if (pos.getY() < minCube || pos.getY() > maxCube) { loadBoundaryCube(); return true; } @@ -662,8 +661,7 @@ public boolean initialize(Requirement effort) throws IOException { return generate(requestedInitLevel); } - private void loadBoundaryCube() - { + private void loadBoundaryCube() { ensureColumn(Requirement.LOAD); if (this.column == null) { diff --git a/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java b/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java index 5dad1549..59bdc053 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java +++ b/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java @@ -36,7 +36,8 @@ public abstract class CubeSelector { public abstract void forAllVisibleFrom(CubePos cubePos, int horizontalViewDistance, int verticalViewDistance, Consumer consumer); - /// Find the difference in current position given view distances and the old position in terms of what cubes need to be removed + /// Find the difference in current position given view distances and the old position in terms of what cubes need to + /// be removed /// or added public abstract void findChanged(CubePos oldAddress, CubePos newAddress, int horizontalViewDistance, int verticalViewDistance, Set cubesToRemove, Set cubesToLoad, diff --git a/src/main/java/com/cardinalstar/cubicchunks/visibility/CuboidalCubeSelector.java b/src/main/java/com/cardinalstar/cubicchunks/visibility/CuboidalCubeSelector.java index 60568245..361e40d6 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/visibility/CuboidalCubeSelector.java +++ b/src/main/java/com/cardinalstar/cubicchunks/visibility/CuboidalCubeSelector.java @@ -104,8 +104,7 @@ public void findChanged(CubePos oldPos, CubePos newPos, int horizontalViewDistan currentY, currentZ, horizontalViewDistance, - verticalViewDistance)) - { + verticalViewDistance)) { cubesToLoad.add(new CubePos(currentX, currentY, currentZ)); } if (!this.isPointWithinCubeVolume( @@ -116,8 +115,7 @@ public void findChanged(CubePos oldPos, CubePos newPos, int horizontalViewDistan currentY - dy, currentZ - dz, horizontalViewDistance, - verticalViewDistance)) - { + verticalViewDistance)) { cubesToRemove.add(new CubePos(currentX - dx, currentY - dy, currentZ - dz)); } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/world/CubicChunksSavedData.java b/src/main/java/com/cardinalstar/cubicchunks/world/CubicChunksSavedData.java index adc0819d..14dd644d 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/world/CubicChunksSavedData.java +++ b/src/main/java/com/cardinalstar/cubicchunks/world/CubicChunksSavedData.java @@ -20,16 +20,16 @@ */ package com.cardinalstar.cubicchunks.world; -import com.cardinalstar.cubicchunks.CubicChunksConfig; -import com.cardinalstar.cubicchunks.worldgen.FillerInfo; -import com.cardinalstar.cubicchunks.worldgen.HeightInfo; -import com.gtnewhorizon.gtnhlib.util.data.BlockMeta; -import com.gtnewhorizon.gtnhlib.util.data.ImmutableBlockMeta; import net.minecraft.block.Block; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraft.world.WorldSavedData; +import com.cardinalstar.cubicchunks.CubicChunksConfig; +import com.cardinalstar.cubicchunks.worldgen.FillerInfo; +import com.cardinalstar.cubicchunks.worldgen.HeightInfo; +import com.gtnewhorizon.gtnhlib.util.data.BlockMeta; +import com.gtnewhorizon.gtnhlib.util.data.ImmutableBlockMeta; public class CubicChunksSavedData extends WorldSavedData { @@ -45,20 +45,16 @@ public CubicChunksSavedData(int dimensionId, World world) { this("cubicChunksData"); HeightInfo heightInfo = CubicChunksConfig.configuredDimensionalHeightMap.get(dimensionId); - if (heightInfo != null) - { + if (heightInfo != null) { this.minHeight = heightInfo.minHeight; this.maxHeight = heightInfo.maxHeight; - } - else - { + } else { this.minHeight = CubicChunksConfig.defaultMinHeight; this.maxHeight = CubicChunksConfig.defaultMaxHeight; } this.fillerInfo = CubicChunksConfig.configuredDimensionalFillerMap.get(dimensionId); - if (this.fillerInfo == null) - { + if (this.fillerInfo == null) { fillerInfo = new FillerInfo(); } } @@ -76,13 +72,11 @@ public static CubicChunksSavedData get(World world) { return data; } - public FillerInfo getFillerInfo() - { + public FillerInfo getFillerInfo() { return fillerInfo; } - public void setBottomFiller(ImmutableBlockMeta block) - { + public void setBottomFiller(ImmutableBlockMeta block) { fillerInfo.bottomFiller = block; this.markDirty(); @@ -90,8 +84,7 @@ public void setBottomFiller(ImmutableBlockMeta block) world.perWorldStorage.saveAllData(); } - public void setTopFiller(ImmutableBlockMeta block) - { + public void setTopFiller(ImmutableBlockMeta block) { fillerInfo.topFiller = block; this.markDirty(); @@ -100,28 +93,24 @@ public void setTopFiller(ImmutableBlockMeta block) } @Override - public void readFromNBT(NBTTagCompound nbt) - { + public void readFromNBT(NBTTagCompound nbt) { // set 4 least significant bits to zero to ensure they are always multiples of 16 minHeight = nbt.getInteger("minHeight") & ~0xF; maxHeight = nbt.getInteger("maxHeight") & ~0xF; - if (fillerInfo == null) - { + if (fillerInfo == null) { fillerInfo = new FillerInfo(); } NBTTagCompound fillerCompound = nbt.getCompoundTag("fillerBlocks"); - if (fillerCompound.hasKey("topId")) - { + if (fillerCompound.hasKey("topId")) { int topBlock = fillerCompound.getInteger("topId"); short topMeta = fillerCompound.getShort("topMeta"); fillerInfo.topFiller = new BlockMeta(Block.getBlockById(topBlock), topMeta); } - if (fillerCompound.hasKey("bottomId")) - { + if (fillerCompound.hasKey("bottomId")) { int bottomBlock = fillerCompound.getInteger("bottomId"); short bottomMeta = fillerCompound.getShort("bottomMeta"); fillerInfo.bottomFiller = new BlockMeta(Block.getBlockById(bottomBlock), bottomMeta); @@ -136,14 +125,12 @@ public void writeToNBT(NBTTagCompound compound) { NBTTagCompound filler = new NBTTagCompound(); - if (fillerInfo.bottomFiller != null) - { + if (fillerInfo.bottomFiller != null) { filler.setInteger("bottomId", Block.getIdFromBlock(fillerInfo.bottomFiller.getBlock())); filler.setShort("bottomMeta", (short) fillerInfo.bottomFiller.getBlockMeta()); } - if (fillerInfo.topFiller != null) - { + if (fillerInfo.topFiller != null) { filler.setInteger("topId", Block.getIdFromBlock(fillerInfo.topFiller.getBlock())); filler.setShort("topMeta", (short) fillerInfo.topFiller.getBlockMeta()); } diff --git a/src/main/java/com/cardinalstar/cubicchunks/world/cube/BoundaryCube.java b/src/main/java/com/cardinalstar/cubicchunks/world/cube/BoundaryCube.java index 707737aa..2669859e 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/world/cube/BoundaryCube.java +++ b/src/main/java/com/cardinalstar/cubicchunks/world/cube/BoundaryCube.java @@ -1,18 +1,17 @@ package com.cardinalstar.cubicchunks.world.cube; +import net.minecraft.world.chunk.Chunk; import com.cardinalstar.cubicchunks.server.chunkio.CubeInitLevel; -import net.minecraft.world.chunk.Chunk; -public class BoundaryCube extends Cube -{ +public class BoundaryCube extends Cube { + public BoundaryCube(Chunk column, int cubeY) { super(column, cubeY); } - /// Boundary cubes are always considered to be lit. - public CubeInitLevel getInitLevel() - { + /// Boundary cubes are always considered to be lit. + public CubeInitLevel getInitLevel() { return CubeInitLevel.Lit; } } diff --git a/src/main/java/com/cardinalstar/cubicchunks/worldgen/FillerInfo.java b/src/main/java/com/cardinalstar/cubicchunks/worldgen/FillerInfo.java index e52666b1..441bf34c 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/worldgen/FillerInfo.java +++ b/src/main/java/com/cardinalstar/cubicchunks/worldgen/FillerInfo.java @@ -4,12 +4,12 @@ import com.gtnewhorizon.gtnhlib.util.data.ImmutableBlockMeta; @Desugar -public class FillerInfo -{ +public class FillerInfo { + public ImmutableBlockMeta topFiller; public ImmutableBlockMeta bottomFiller; - public FillerInfo(ImmutableBlockMeta topFiller, ImmutableBlockMeta bottomFiller) - { + + public FillerInfo(ImmutableBlockMeta topFiller, ImmutableBlockMeta bottomFiller) { this.topFiller = topFiller; this.bottomFiller = bottomFiller; } diff --git a/src/main/java/com/cardinalstar/cubicchunks/worldgen/HeightInfo.java b/src/main/java/com/cardinalstar/cubicchunks/worldgen/HeightInfo.java index 8d780229..7f20f3fb 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/worldgen/HeightInfo.java +++ b/src/main/java/com/cardinalstar/cubicchunks/worldgen/HeightInfo.java @@ -1,7 +1,7 @@ package com.cardinalstar.cubicchunks.worldgen; -public class HeightInfo -{ +public class HeightInfo { + public Integer maxHeight; public Integer minHeight; } diff --git a/src/main/java/com/cardinalstar/cubicchunks/worldgen/VanillaWorldGenerator.java b/src/main/java/com/cardinalstar/cubicchunks/worldgen/VanillaWorldGenerator.java index 8c3e6295..773f2927 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/worldgen/VanillaWorldGenerator.java +++ b/src/main/java/com/cardinalstar/cubicchunks/worldgen/VanillaWorldGenerator.java @@ -30,7 +30,6 @@ import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; -import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; import net.minecraft.block.Block; import net.minecraft.entity.EnumCreatureType; import net.minecraft.init.Blocks; @@ -61,6 +60,7 @@ import com.cardinalstar.cubicchunks.util.CompatHandler; import com.cardinalstar.cubicchunks.util.Coords; import com.cardinalstar.cubicchunks.util.CubePos; +import com.cardinalstar.cubicchunks.world.CubicChunksSavedData; import com.cardinalstar.cubicchunks.world.ICubicWorld; import com.cardinalstar.cubicchunks.world.api.ICubeProviderServer.Requirement; import com.cardinalstar.cubicchunks.world.core.IColumnInternal; @@ -106,9 +106,9 @@ public class VanillaWorldGenerator implements IWorldGenerator, IPreloadFailureDe * @param vanilla The vanilla generator to mirror * @param world The world in which cubes are being generated */ - public VanillaWorldGenerator(IChunkProvider vanilla, World world, IWorldDecorator decorator) - { - this.fillerInfo = CubicChunksSavedData.get(world).getFillerInfo(); + public VanillaWorldGenerator(IChunkProvider vanilla, World world, IWorldDecorator decorator) { + this.fillerInfo = CubicChunksSavedData.get(world) + .getFillerInfo(); this.vanilla = vanilla; this.world = world; @@ -126,8 +126,7 @@ private CubeProviderServer getCubeProviderServer() { return ((ICubicWorldInternal.Server) world).getCubeCache(); } - private ImmutableBlockMeta getBottomFillerInfo() - { + private ImmutableBlockMeta getBottomFillerInfo() { if (fillerInfo.bottomFiller != null) return fillerInfo.bottomFiller; Chunk chunk = vanilla.provideChunk(0, 0); @@ -173,8 +172,7 @@ private ImmutableBlockMeta analyzeBottomFiller(IBlockView blockView) { .orElse(new BlockMeta(Blocks.air, 0)); } - private ImmutableBlockMeta getTopFillerInfo() - { + private ImmutableBlockMeta getTopFillerInfo() { if (fillerInfo.topFiller != null) return fillerInfo.topFiller; Chunk chunk = vanilla.provideChunk(0, 0); From 6e1e17bc2e7b7caf5b36c6330844a81a9d439118 Mon Sep 17 00:00:00 2001 From: rjnasers Date: Sun, 19 Apr 2026 22:24:02 +0200 Subject: [PATCH 5/5] Removing comments to prevent some nasty merge conflicts. --- .../cardinalstar/cubicchunks/visibility/CubeSelector.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java b/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java index 59bdc053..ba21d1af 100644 --- a/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java +++ b/src/main/java/com/cardinalstar/cubicchunks/visibility/CubeSelector.java @@ -32,18 +32,13 @@ @ParametersAreNonnullByDefault public abstract class CubeSelector { - /// For all cube positions visible from an input cubePos and view distances give it to a consumer public abstract void forAllVisibleFrom(CubePos cubePos, int horizontalViewDistance, int verticalViewDistance, Consumer consumer); - /// Find the difference in current position given view distances and the old position in terms of what cubes need to - /// be removed - /// or added public abstract void findChanged(CubePos oldAddress, CubePos newAddress, int horizontalViewDistance, int verticalViewDistance, Set cubesToRemove, Set cubesToLoad, Set columnsToRemove, Set columnsToLoad); - /// Find what cubes need to be removed given a view distance decrease public abstract void findAllUnloadedOnViewDistanceDecrease(CubePos playerAddress, int oldHorizontalViewDistance, int newHorizontalViewDistance, int oldVerticalViewDistance, int newVerticalViewDistance, Set cubesToUnload, Set columnsToUnload);