diff --git a/README.md b/README.md index 85614794..13e8a191 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,469 @@ # Fabric Carpet Cause all carpets are made of fabric? + +# Carpet Settings + +## antiCheatSpeed +Prevents players from rubberbanding when moving too fast +Puts more trust in clients positioning +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `CREATIVE`, `SURVIVAL` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## calmNetherFires +Permanent fires don't schedule random updates +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `OPTIMIZATION` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## carpets +Placing carpets may issue carpet commands for non-op players +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `SURVIVAL` + +## combineXPOrbs +XP orbs combine with other into bigger orbs +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `FEATURE` + +## commandCameramode +Enables /c and /s commands to quickly switch between camera and survival modes +/c and /s commands are available to all players regardless of their permission levels +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * It has an accompanying command + +## commandDistance +Enables /distance command to measure in game distance between points +Also enables brown carpet placement action if 'carpets' rule is turned on as well +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * It has an accompanying command + +## commandDraw +Enables /draw commands +... allows for drawing simple shapes +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * It has an accompanying command + +## commandInfo +Enables /info command for blocks +Also enables gray carpet placement action +if 'carpets' rule is turned on as well +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * It has an accompanying command + +## commandLog +Enables /log command to monitor events in the game via chat and overlays +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * It has an accompanying command + +## commandPerimeterInfo +Enables /perimeterinfo command +... that scans the area around the block for potential spawnable spots +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * It has an accompanying command + +## commandPlayer +Enables /player command to control/spawn players +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * Its not yet fully implemented - we are working on it + * It has an accompanying command + +## commandScript +Enables /script command +An in-game scripting API for Scarpet programming language +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * It has an accompanying command + +## commandSpawn +Enables /spawn command for spawn tracking +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * It has an accompanying command + +## commandTick +Enables /tick command to control game clocks +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `COMMAND` +* Additional notes: + * It has an accompanying command + +## ctrlQCraftingFix +Dropping entire stacks works also from on the crafting UI result slot +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `BUGFIX`, `SURVIVAL` + +## customMOTD +Sets a different motd message on client trying to connect to the server +use '_' to use the startup setting from server.properties +* Type: `String` +* Default value: `_` +* Suggested options: `_` +* Categories: `CREATIVE` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## desertShrubs +Saplings turn into dead shrubs in hot climates and no water access +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `FEATURE` + +## disableSpawnChunks +Allows spawn chunks to unload +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `CREATIVE` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## explosionNoBlockDamage +Explosions won't destroy blocks +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `CREATIVE` + +## fastRedstoneDust +Lag optimizations for redstone dust +by Theosib +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `EXPERIMENTAL`, `OPTIMIZATION` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## fillLimit +Customizable fill/clone volume limit +* Type: `int` +* Default value: `32768` +* Suggested options: `32768`, `250000`, `1000000` +* Categories: `CREATIVE` +* Additional notes: + * You must choose a value from 1 to 20M + +## fillUpdates +fill/clone/setblock and structure blocks cause block updates +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `CREATIVE` + +## flippinCactus +Players can flip and rotate blocks when holding cactus +Doesn't cause block updates when rotated/flipped +Applies to pistons, observers, droppers, repeaters, stairs, glazed terracotta etc... +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `CREATIVE`, `SURVIVAL`, `FEATURE` + +## hopperCounters +hoppers pointing to wool will count items passing through them +Enables /counter command, and actions while placing red and green carpets on wool blocks +Use /counter reset to reset the counter, and /counter to query +In survival, place green carpet on same color wool to query, red to reset the counters +Counters are global and shared between players, 16 channels available +Items counted are destroyed, count up to one stack per tick per hopper +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `COMMAND`, `CREATIVE`, `FEATURE` +* Additional notes: + * It has an accompanying command + +## huskSpawningInTemples +Only husks spawn in desert temples +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `FEATURE` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## kelpGenerationGrowthLimit +limits growth limit of newly naturally generated kelp to this amount of blocks +* Type: `int` +* Default value: `25` +* Suggested options: `0`, `2`, `25` +* Categories: `FEATURE` +* Additional notes: + * You must choose a value from 0 to 25. 25 and all natural kelp can grow 25 blocks, choose 0 to make all generated kelp not to grow + +## lagFreeSpawning +Spawning requires much less CPU and Memory +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `OPTIMIZATION` + +## leadFix +Fixes leads breaking/becoming invisible in unloaded chunks +You may still get visibly broken leash links on the client side, but server side the link is still there. +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `BUGFIX` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## maxEntityCollisions +Customizable maximal entity collision limits, 0 for no limits +* Type: `int` +* Default value: `0` +* Suggested options: `0`, `1`, `20` +* Categories: `OPTIMIZATION` +* Additional notes: + * Must be a positive number + +## missingTools +Pistons, Glass and Sponge can be broken faster with their appropriate tools +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `SURVIVAL` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## movableTileEntities +Pistons can push tile entities, like hoppers, chests etc. +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `EXPERIMENTAL`, `FEATURE` + +## onePlayerSleeping +One player is required on the server to cause night to pass +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `SURVIVAL` + +## persistentParrots +Parrots don't get of your shoulders until you receive damage +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `SURVIVAL`, `FEATURE` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## placementRotationFix +fixes block placement rotation issue when player rotates quickly while placing blocks +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `BUGFIX` + +## portalCaching +Alternative, persistent caching strategy for nether portals +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `SURVIVAL`, `CREATIVE` + +## portalCreativeDelay +Portals won't let a creative player go through instantly +Holding obsidian in either hand won't let you through at all +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `CREATIVE` + +## portalSuffocationFix +Nether portals correctly place entities going through +Entities shouldn't suffocate in obsidian +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `BUGFIX` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## pushLimit +Customizable piston push limit +* Type: `int` +* Default value: `12` +* Suggested options: `10`, `12`, `14`, `100` +* Categories: `CREATIVE` +* Additional notes: + * You must choose a value from 1 to 1024 + +## quasiConnectivity +Pistons, droppers and dispensers react if block above them is powered +* Type: `boolean` +* Default value: `true` +* Required options: `true`, `false` +* Categories: `CREATIVE` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## railPowerLimit +Customizable powered rail power range +* Type: `int` +* Default value: `9` +* Suggested options: `9`, `15`, `30` +* Categories: `CREATIVE` +* Additional notes: + * You must choose a value from 1 to 1024 + +## renewableCoral +Coral structures will grow with bonemeal from coral plants +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `FEATURE` + +## renewableSponges +Guardians turn into Elder Guardian when struck by lightning +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `FEATURE` + +## rotatorBlock +Cactus in dispensers rotates blocks. +Rotates block anti-clockwise if possible +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `FEATURE` + +## shulkerSpawningInEndCities +Shulkers will respawn in end cities +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `FEATURE` + +## silverFishDropGravel +Silverfish drop a gravel item when breaking out of a block +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `FEATURE` + +## stackableShulkerBoxes +Empty shulker boxes can stack to 64 when dropped on the ground +To move them around between inventories, use shift click to move entire stacks +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `SURVIVAL`, `FEATURE` + +## summonNaturalLightning +summoning a lightning bolt has all the side effects of natural lightning +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `CREATIVE` + +## superSecretSetting +Gbhs sgnf sadsgras fhskdpri! +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `EXPERIMENTAL` + +## tntDoNotUpdate +TNT doesn't update when placed against a power source +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `CREATIVE` + +## tntPrimerMomentumRemoved +Removes random TNT momentum when primed +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `CREATIVE` + +## unloadedEntityFix +Entities pushed or moved into unloaded chunks no longer disappear +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `EXPERIMENTAL`, `BUGFIX` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## viewDistance +Changes the view distance of the server. +Set to 0 to not override the value in server settings. +* Type: `int` +* Default value: `0` +* Suggested options: `0`, `12`, `16`, `32` +* Categories: `CREATIVE` +* Additional notes: + * You must choose a value from 0 (use server settings) to 32 + +## watchdogCrashFix +Fixes server crashing supposedly on falling behind 60s in ONE tick, yeah bs. +Fixed 1.12 watchdog crash in 1.13 pre-releases, reintroduced with 1.13, GG. +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `BUGFIX` +* Additional notes: + * Its not yet fully implemented - we are working on it + +## xpNoCooldown +Players absorb XP instantly, without delay +* Type: `boolean` +* Default value: `false` +* Required options: `true`, `false` +* Categories: `CREATIVE` + diff --git a/src/main/java/carpet/CarpetServer.java b/src/main/java/carpet/CarpetServer.java index 4c5e64e1..6a378d10 100644 --- a/src/main/java/carpet/CarpetServer.java +++ b/src/main/java/carpet/CarpetServer.java @@ -14,6 +14,7 @@ import carpet.commands.PerimeterInfoCommand; import carpet.commands.PlayerCommand; import carpet.commands.ScriptCommand; import carpet.commands.SpawnCommand; +import carpet.commands.TestCommand; import carpet.commands.TickCommand; import carpet.helpers.TickSpeed; import carpet.logging.LoggerRegistry; @@ -31,7 +32,8 @@ public class CarpetServer // static for now - easier to handle all around the co public static MinecraftServer minecraft_server; public static CarpetScriptServer scriptServer; public static SettingsManager settingsManager; - static { + static + { SettingsManager.parseSettingsClass(CarpetSettings.class); //... } @@ -45,7 +47,8 @@ public class CarpetServer // static for now - easier to handle all around the co scriptServer = new CarpetScriptServer(); } // Separate from onServerLoaded, because a server can be loaded multiple times in singleplayer - public static void onGameStarted() { + public static void onGameStarted() + { LoggerRegistry.initLoggers(); } @@ -72,7 +75,6 @@ public class CarpetServer // static for now - easier to handle all around the co DrawCommand.register(dispatcher); ScriptCommand.register(dispatcher); CarpetCommand.register(dispatcher); - //TestCommand.register(dispatcher); } } diff --git a/src/main/java/carpet/commands/CarpetCommand.java b/src/main/java/carpet/commands/CarpetCommand.java index 4e1eb9c7..ab64394a 100644 --- a/src/main/java/carpet/commands/CarpetCommand.java +++ b/src/main/java/carpet/commands/CarpetCommand.java @@ -149,16 +149,16 @@ public class CarpetCommand return Messenger.c(args.toArray(new Object[0])); } - private static BaseText makeSetRuleButton(ParsedRule rule, String option, boolean brackets) { + private static BaseText makeSetRuleButton(ParsedRule rule, String option, boolean brackets) + { String style = rule.isDefault()?"g":(option.equalsIgnoreCase(rule.defaultAsString)?"y":"e"); if (option.equalsIgnoreCase(rule.defaultAsString)) style = style+"b"; else if (option.equalsIgnoreCase(rule.getAsString())) style = style+"u"; String baseText = style + (brackets ? " [" : " ") + option + (brackets ? "]" : ""); - if (CarpetServer.settingsManager.locked) { + if (CarpetServer.settingsManager.locked) return Messenger.c(baseText, "^g Settings are locked"); - } if (option.equalsIgnoreCase(rule.getAsString())) return Messenger.c(baseText); return Messenger.c(baseText, "^g Switch to " + option, "?/carpet " + rule.name + " " + option); @@ -200,9 +200,7 @@ public class CarpetCommand tags.remove(tags.size() - 1); Messenger.m(player, tags.toArray(new Object[0])); } - catch (CommandSyntaxException e) - { - } + catch (CommandSyntaxException ignored) { } return 1; } } diff --git a/src/main/java/carpet/commands/TestCommand.java b/src/main/java/carpet/commands/TestCommand.java index 2cbcb7a5..469c8e5a 100644 --- a/src/main/java/carpet/commands/TestCommand.java +++ b/src/main/java/carpet/commands/TestCommand.java @@ -1,5 +1,6 @@ package carpet.commands; +import carpet.CarpetServer; import carpet.utils.Messenger; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.context.CommandContext; @@ -15,6 +16,7 @@ public class TestCommand public static void register(CommandDispatcher dispatcher) { dispatcher.register(literal("test"). + then(literal("dump").executes((c) -> CarpetServer.settingsManager.printAllRulesToLog())). then(argument("first",word()). executes( (c)-> test(c, getString(c, "first")+" 1"))). then(argument("second", word()). diff --git a/src/main/java/carpet/mixins/HopperBlockEntityMixin.java b/src/main/java/carpet/mixins/HopperBlockEntityMixin.java index a82b65c8..e2bfb957 100644 --- a/src/main/java/carpet/mixins/HopperBlockEntityMixin.java +++ b/src/main/java/carpet/mixins/HopperBlockEntityMixin.java @@ -45,9 +45,12 @@ public abstract class HopperBlockEntityMixin extends LootableContainerBlockEntit DyeColor wool_color = WoolTool.getWoolColorAtPosition( getWorld(), new BlockPos(getHopperX(), getHopperY(), getHopperZ()).offset(this.getCachedState().get(HopperBlock.FACING))); - if (wool_color != null) { - for (int i = 0; i < this.getInvSize(); ++i) { - if (!this.getInvStack(i).isEmpty()) { + if (wool_color != null) + { + for (int i = 0; i < this.getInvSize(); ++i) + { + if (!this.getInvStack(i).isEmpty()) + { ItemStack itemstack = this.getInvStack(i);//.copy(); HopperCounter.COUNTERS.get(wool_color).add(this.getWorld().getServer(), itemstack); this.setInvStack(i, ItemStack.EMPTY); diff --git a/src/main/java/carpet/mixins/TntBlockMixin.java b/src/main/java/carpet/mixins/TntBlockMixin.java index 608f3c2f..a220f9a9 100644 --- a/src/main/java/carpet/mixins/TntBlockMixin.java +++ b/src/main/java/carpet/mixins/TntBlockMixin.java @@ -11,11 +11,11 @@ import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(TntBlock.class) public abstract class TntBlockMixin { - // Add carpet rule check for TNTDoNotUpdate to an if statement. + // Add carpet rule check for tntDoNotUpdate to an if statement. @Redirect(method = "onBlockAdded", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;isReceivingRedstonePower(Lnet/minecraft/util/math/BlockPos;)Z")) private boolean isTNTDoNotUpdate(World world, BlockPos blockPos) { - return !CarpetSettings.TNTDoNotUpdate && world.isReceivingRedstonePower(blockPos); + return !CarpetSettings.tntDoNotUpdate && world.isReceivingRedstonePower(blockPos); } } diff --git a/src/main/java/carpet/settings/CarpetSettings.java b/src/main/java/carpet/settings/CarpetSettings.java index 552d01f8..2a36bbd2 100644 --- a/src/main/java/carpet/settings/CarpetSettings.java +++ b/src/main/java/carpet/settings/CarpetSettings.java @@ -10,11 +10,11 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import static carpet.settings.RuleCategory.BUGFIX; -import static carpet.settings.RuleCategory.COMMANDS; +import static carpet.settings.RuleCategory.COMMAND; import static carpet.settings.RuleCategory.CREATIVE; import static carpet.settings.RuleCategory.EXPERIMENTAL; import static carpet.settings.RuleCategory.FEATURE; -import static carpet.settings.RuleCategory.OPTIMIZATIONS; +import static carpet.settings.RuleCategory.OPTIMIZATION; import static carpet.settings.RuleCategory.SURVIVAL; public class CarpetSettings @@ -98,7 +98,7 @@ public class CarpetSettings @Rule( desc = "Lag optimizations for redstone dust", extra = "by Theosib", - category = {EXPERIMENTAL, OPTIMIZATIONS}, + category = {EXPERIMENTAL, OPTIMIZATION}, validate = Validator.WIP.class ) public static boolean fastRedstoneDust = false; @@ -113,7 +113,7 @@ public class CarpetSettings public static boolean unloadedEntityFix = false; @Rule( desc = "TNT doesn't update when placed against a power source", category = CREATIVE ) - public static boolean TNTDoNotUpdate = false; + public static boolean tntDoNotUpdate = false; @Rule( desc = "Prevents players from rubberbanding when moving too fast", @@ -145,7 +145,7 @@ public class CarpetSettings "Counters are global and shared between players, 16 channels available", "Items counted are destroyed, count up to one stack per tick per hopper" }, - category = {COMMANDS, CREATIVE, FEATURE} + category = {COMMAND, CREATIVE, FEATURE} ) public static boolean hopperCounters = false; @@ -164,19 +164,19 @@ public class CarpetSettings @Rule( desc = "summoning a lightning bolt has all the side effects of natural lightning", category = CREATIVE ) public static boolean summonNaturalLightning = false; - @Rule(desc = "Enables /spawn command for spawn tracking", category = COMMANDS) + @Rule(desc = "Enables /spawn command for spawn tracking", category = COMMAND) public static boolean commandSpawn = true; - @Rule(desc = "Enables /tick command to control game clocks", category = COMMANDS) + @Rule(desc = "Enables /tick command to control game clocks", category = COMMAND) public static boolean commandTick = true; - @Rule(desc = "Enables /log command to monitor events in the game via chat and overlays", category = COMMANDS) + @Rule(desc = "Enables /log command to monitor events in the game via chat and overlays", category = COMMAND) public static boolean commandLog = true; @Rule( desc = "Enables /distance command to measure in game distance between points", extra = "Also enables brown carpet placement action if 'carpets' rule is turned on as well", - category = COMMANDS + category = COMMAND ) public static boolean commandDistance = true; @@ -186,31 +186,31 @@ public class CarpetSettings "Also enables gray carpet placement action", "if 'carpets' rule is turned on as well" }, - category = COMMANDS + category = COMMAND ) public static boolean commandInfo = true; @Rule( desc = "Enables /c and /s commands to quickly switch between camera and survival modes", extra = "/c and /s commands are available to all players regardless of their permission levels", - category = COMMANDS + category = COMMAND ) public static boolean commandCameramode = true; @Rule( desc = "Enables /perimeterinfo command", extra = "... that scans the area around the block for potential spawnable spots", - category = COMMANDS + category = COMMAND ) public static boolean commandPerimeterInfo = true; - @Rule(desc = "Enables /draw commands", extra = "... allows for drawing simple shapes", category = COMMANDS) + @Rule(desc = "Enables /draw commands", extra = "... allows for drawing simple shapes", category = COMMAND) public static boolean commandDraw = true; - @Rule(desc = "Enables /script command", extra = "an in-game scripting API", category = COMMANDS) + @Rule(desc = "Enables /script command", extra = "An in-game scripting API for Scarpet programming language", category = COMMAND) public static boolean commandScript = true; - @Rule(desc = "Enables /player command to control/spawn players", category = COMMANDS, validate = Validator.WIP.class) + @Rule(desc = "Enables /player command to control/spawn players", category = COMMAND, validate = Validator.WIP.class) public static boolean commandPlayer = true; @Rule(desc = "Placing carpets may issue carpet commands for non-op players", category = SURVIVAL) @@ -226,16 +226,18 @@ public class CarpetSettings @Rule(desc = "Alternative, persistent caching strategy for nether portals", category = {SURVIVAL, CREATIVE}) public static boolean portalCaching = false; - @Rule(desc = "Permanent fires don't schedule random updates", category = OPTIMIZATIONS, validate = Validator.WIP.class) + @Rule(desc = "Permanent fires don't schedule random updates", category = OPTIMIZATION, validate = Validator.WIP.class) public static boolean calmNetherFires = false; @Rule(desc = "fill/clone/setblock and structure blocks cause block updates", category = CREATIVE) public static boolean fillUpdates = true; private static class PushLimitLimits extends Validator { - @Override Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) { - return (newValue>0 && newValue < 1024) ? newValue : null; + @Override public Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) { + return (newValue>0 && newValue <= 1024) ? newValue : null; } + @Override + public String description() { return "You must choose a value from 1 to 1024";} } @Rule( desc = "Customizable piston push limit", @@ -254,9 +256,11 @@ public class CarpetSettings public static int railPowerLimit = 9; private static class FillLimitLimits extends Validator { - @Override Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) { + @Override public Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) { return (newValue>0 && newValue < 20000000) ? newValue : null; } + @Override + public String description() { return "You must choose a value from 1 to 20M";} } @Rule( desc = "Customizable fill/clone volume limit", @@ -269,7 +273,7 @@ public class CarpetSettings @Rule( desc = "Customizable maximal entity collision limits, 0 for no limits", options = {"0", "1", "20"}, - category = OPTIMIZATIONS, + category = OPTIMIZATION, validate = Validator.NONNEGATIVE_NUMBER.class ) public static int maxEntityCollisions = 0; @@ -278,7 +282,7 @@ public class CarpetSettings public static boolean onePlayerSleeping = false; private static class SetMotd extends Validator { - @Override String validate(ServerCommandSource source, ParsedRule currentRule, String newValue, String string) { + @Override public String validate(ServerCommandSource source, ParsedRule currentRule, String newValue, String string) { customMOTD = newValue; // accelerate a smidge ((MinecraftServer_motdInterface) CarpetServer.minecraft_server).checkMOTD(); return newValue; @@ -298,7 +302,7 @@ public class CarpetSettings private static class ViewDistanceValidator extends Validator { - @Override Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) + @Override public Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) { if (newValue < 0 || newValue > 32) { @@ -320,6 +324,8 @@ public class CarpetSettings return 0; } } + @Override + public String description() { return "You must choose a value from 0 (use server settings) to 32";} } @Rule( desc = "Changes the view distance of the server.", @@ -331,7 +337,7 @@ public class CarpetSettings public static int viewDistance = 0; private static class DisableSpawnChunksValidator extends Validator { - @Override Boolean validate(ServerCommandSource source, ParsedRule currentRule, Boolean newValue, String string) { + @Override public Boolean validate(ServerCommandSource source, ParsedRule currentRule, Boolean newValue, String string) { if (!newValue) Messenger.m(source, "w Spawn chunks re-enabled. Visit spawn to load them?"); return newValue; @@ -344,10 +350,13 @@ public class CarpetSettings ) public static boolean disableSpawnChunks = false; - private static class KelpLimit extends Validator { - @Override Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) { + private static class KelpLimit extends Validator + { + @Override public Integer validate(ServerCommandSource source, ParsedRule currentRule, Integer newValue, String string) { return (newValue>=0 && newValue <=25)?newValue:null; } + @Override + public String description() { return "You must choose a value from 0 to 25. 25 and all natural kelp can grow 25 blocks, choose 0 to make all generated kelp not to grow";} } @Rule( desc = "limits growth limit of newly naturally generated kelp to this amount of blocks", @@ -371,7 +380,6 @@ public class CarpetSettings ) public static boolean leadFix = false; - @Rule(desc = "Spawning requires much less CPU and Memory", category = OPTIMIZATIONS) + @Rule(desc = "Spawning requires much less CPU and Memory", category = OPTIMIZATION) public static boolean lagFreeSpawning = false; - } diff --git a/src/main/java/carpet/settings/ParsedRule.java b/src/main/java/carpet/settings/ParsedRule.java index 859d9270..3cc1b974 100644 --- a/src/main/java/carpet/settings/ParsedRule.java +++ b/src/main/java/carpet/settings/ParsedRule.java @@ -25,17 +25,22 @@ public final class ParsedRule implements Comparable { public final T defaultValue; public final String defaultAsString; - public static T callConstructor(Class cls) { - try { + public static T callConstructor(Class cls) + { + try + { Constructor constr = cls.getDeclaredConstructor(); constr.setAccessible(true); return constr.newInstance(); - } catch (ReflectiveOperationException e) { + } + catch (ReflectiveOperationException e) + { throw new RuntimeException(e); } } - ParsedRule(Field field, Rule rule) { + ParsedRule(Field field, Rule rule) + { this.field = field; this.name = rule.name().isEmpty() ? field.getName() : rule.name(); this.type = (Class) field.getType(); @@ -45,10 +50,8 @@ public final class ParsedRule implements Comparable { this.categories = ImmutableList.copyOf(rule.category()); this.validators = new ArrayList<>(); for (Class v : rule.validate()) - { this.validators.add((Validator) callConstructor(v)); - } - if (categories.contains(RuleCategory.COMMANDS)) + if (categories.contains(RuleCategory.COMMAND)) this.validators.add(callConstructor(Validator._COMMAND.class)); this.defaultValue = get(); this.defaultAsString = convertToString(this.defaultValue); diff --git a/src/main/java/carpet/settings/Rule.java b/src/main/java/carpet/settings/Rule.java index 62a54bab..b4c5b316 100644 --- a/src/main/java/carpet/settings/Rule.java +++ b/src/main/java/carpet/settings/Rule.java @@ -17,7 +17,8 @@ import java.lang.annotation.Target; */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) -@interface Rule { +@interface Rule +{ /** * The rule name, by default the same as the field name */ diff --git a/src/main/java/carpet/settings/RuleCategory.java b/src/main/java/carpet/settings/RuleCategory.java index fbb952bc..c5da5add 100644 --- a/src/main/java/carpet/settings/RuleCategory.java +++ b/src/main/java/carpet/settings/RuleCategory.java @@ -1,12 +1,13 @@ package carpet.settings; -public class RuleCategory { +public class RuleCategory +{ public static final String BUGFIX = "bugfix"; public static final String SURVIVAL = "survival"; public static final String CREATIVE = "creative"; public static final String EXPERIMENTAL = "experimental"; - public static final String OPTIMIZATIONS = "optimizations"; + public static final String OPTIMIZATION = "optimization"; public static final String FEATURE = "feature"; - public static final String COMMANDS = "commands"; + public static final String COMMAND = "command"; } diff --git a/src/main/java/carpet/settings/SettingsManager.java b/src/main/java/carpet/settings/SettingsManager.java index 435f7b47..80225f2d 100644 --- a/src/main/java/carpet/settings/SettingsManager.java +++ b/src/main/java/carpet/settings/SettingsManager.java @@ -11,10 +11,10 @@ import org.apache.logging.log4j.Logger; import java.io.*; import java.lang.reflect.Field; import java.util.*; -import java.util.function.Predicate; import java.util.stream.Collectors; -public class SettingsManager { +public class SettingsManager +{ private static final Logger LOG = LogManager.getLogger(); private static Map> rules = new HashMap<>(); public boolean locked; @@ -46,11 +46,13 @@ public class SettingsManager { } - public ParsedRule getRule(String name) { + public ParsedRule getRule(String name) + { return rules.get(name); } - public static Collection> getRules() { + public static Collection> getRules() + { CarpetSettings.LOG.error("grabbing rules"); List> r = rules.values().stream().sorted().collect(Collectors.toList()); CarpetSettings.LOG.error("Got: "+r.size()+" rules"); @@ -65,17 +67,22 @@ public class SettingsManager { } - public Collection> getNonDefault() { + public Collection> getNonDefault() + { return rules.values().stream().filter(r -> !r.isDefault()).sorted().collect(Collectors.toList()); } - private File getFile() { + private File getFile() + { return server.getLevelStorage().resolveFile(server.getLevelName(), "carpet.conf"); } - public void disableBooleanFromCategory(String category) { - for (ParsedRule rule : rules.values()) { - if (rule.type != boolean.class || !rule.categories.contains(category)) continue; + public void disableBooleanFromCategory(String category) + { + for (ParsedRule rule : rules.values()) + { + if (rule.type != boolean.class || !rule.categories.contains(category)) + continue; ((ParsedRule) rule).set(server.getCommandSource(), false, "false"); } } @@ -84,7 +91,8 @@ public class SettingsManager { private void writeSettingsToConf(Map values) { - if (locked) return; + if (locked) + return; try { FileWriter fw = new FileWriter(getFile()); @@ -122,7 +130,7 @@ public class SettingsManager { if (conf.getRight()) { LOG.info("[CM]: Carpet Mod is locked by the administrator"); - disableBooleanFromCategory(RuleCategory.COMMANDS); + disableBooleanFromCategory(RuleCategory.COMMAND); } for (String key: conf.getLeft().keySet()) { @@ -158,8 +166,6 @@ public class SettingsManager { } ParsedRule rule = rules.get(fields[0]); - - if (!(rule.options.contains(fields[1])) && rule.isStrict) { LOG.error("[CM]: The value of " + fields[1] + " for " + fields[0] + " is not valid - ignoring..."); @@ -213,16 +219,48 @@ public class SettingsManager { return false; } - public Collection> getRulesMatching(Predicate> predicate) { - return rules.values().stream().filter(predicate).collect(ImmutableList.toImmutableList()); - } - public Collection> getRulesMatching(String search) { String lcSearch = search.toLowerCase(Locale.ROOT); - return getRulesMatching(rule -> { + return rules.values().stream().filter(rule -> + { if (rule.name.toLowerCase(Locale.ROOT).contains(lcSearch)) return true; for (String c : rule.categories) if (c.toLowerCase(Locale.ROOT).equals(search)) return true; return false; - }); + }).collect(ImmutableList.toImmutableList()); } + + public int printAllRulesToLog() + { + PrintStream ps = System.out; + ps.println("# Carpet Settings"); + for (Map.Entry> e : new TreeMap<>(rules).entrySet()) + { + ParsedRule rule = e.getValue(); + ps.println("## " + rule.name); + ps.println(rule.description+" "); + for (String extra : rule.extraInfo) + ps.println(extra + " "); + ps.println("* Type: `" + rule.type.getSimpleName() + "` "); + ps.println("* Default value: `" + rule.defaultAsString + "` "); + String optionString = rule.options.stream().map(s -> "`" + s + "`").collect(Collectors.joining(", ")); + ps.println((rule.isStrict?"* Required":"* Suggested")+" options: " + optionString + " "); + ps.println("* Categories: " + rule.categories.stream().map(s -> "`" + s.toUpperCase(Locale.ROOT) + "`").collect(Collectors.joining(", ")) + " "); + boolean preamble = false; + for (Validator validator : rule.validators) + { + if(validator.description() != null) + { + if (!preamble) + { + ps.println("* Additional notes: "); + preamble = true; + } + ps.println(" * "+validator.description()+" "); + } + } + ps.println(" "); + } + return 1; + } + } diff --git a/src/main/java/carpet/settings/Validator.java b/src/main/java/carpet/settings/Validator.java index dc924a3e..98d6f084 100644 --- a/src/main/java/carpet/settings/Validator.java +++ b/src/main/java/carpet/settings/Validator.java @@ -6,35 +6,44 @@ import net.minecraft.server.command.ServerCommandSource; import java.util.Locale; -public abstract class Validator { +public abstract class Validator +{ /** * Validate the new value of a rule * @return true if valid, false if new rule invalid. */ - abstract T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string); + public abstract T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string); + public String description() {return null;} - - public static class POSITIVE_NUMBER extends Validator { + public static class POSITIVE_NUMBER extends Validator + { @Override - public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) { + public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) + { return newValue.doubleValue() > 0 ? newValue : null; } + @Override + public String description() { return "Must be a positive number"; } } - - - public static class _COMMAND extends Validator { + public static class _COMMAND extends Validator + { @Override - public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) { + public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) + { if (CarpetServer.settingsManager != null) CarpetServer.settingsManager.notifyPlayersCommandsChanged(); return newValue; } + @Override + public String description() { return "It has an accompanying command";} } - public static class WIP extends Validator { + public static class WIP extends Validator + { @Override - public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) { + public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) + { if (source != null) try { @@ -43,10 +52,14 @@ public abstract class Validator { catch (NullPointerException ignored) { } return newValue; } - } - public static class _STRICT extends Validator { @Override - public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) { + public String description() { return "Its not yet fully implemented - we are working on it";} + } + public static class _STRICT extends Validator + { + @Override + public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) + { if (!currentRule.options.contains(string.toLowerCase(Locale.ROOT))) { if (source != null) @@ -63,10 +76,14 @@ public abstract class Validator { } } - public static class NONNEGATIVE_NUMBER extends Validator { + public static class NONNEGATIVE_NUMBER extends Validator + { @Override - public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) { + public T validate(ServerCommandSource source, ParsedRule currentRule, T newValue, String string) + { return newValue.doubleValue() >= 0 ? newValue : null; } + @Override + public String description() { return "Must be a positive number";} } }