001/*
002 * PlotSquared, a land and world management plugin for Minecraft.
003 * Copyright (C) IntellectualSites <https://intellectualsites.com>
004 * Copyright (C) IntellectualSites team and contributors
005 *
006 * This program is free software: you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation, either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * This program is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
018 */
019package com.plotsquared.core.configuration;
020
021import com.plotsquared.core.configuration.file.YamlConfiguration;
022import net.kyori.adventure.text.event.ClickEvent;
023
024import java.io.File;
025import java.util.ArrayList;
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.List;
029import java.util.stream.Collectors;
030
031public class Settings extends Config {
032
033    /*
034    START OF CONFIGURATION SECTION:
035    NOTE: Fields are saved in declaration order, classes in reverse order
036     */
037
038    @Comment("This value is not configurable. It shows the platform you are using.") // This is a comment
039    @Final
040    public static String PLATFORM; // These values are set from PlotSquared before loading
041
042    @Comment({"Show additional information in console. It helps us at IntellectualSites to find out more about an issue.",
043            "Leave it off if you don't need it, it can spam your console."})
044    public static boolean DEBUG = true;
045
046    @Create // This value will be generated automatically
047    public static ConfigBlock<Auto_Clear> AUTO_CLEAR = null;
048    // A ConfigBlock is a section that can have multiple instances e.g. multiple expiry tasks
049
050    public static void save(File file) {
051        save(file, Settings.class);
052    }
053
054    public static void load(File file) {
055        load(file, Settings.class);
056    }
057
058    public static boolean convertLegacy(File file) {
059        if (!file.exists()) {
060            return false;
061        }
062        YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
063
064        // Protection
065        Redstone.DISABLE_OFFLINE = config.getBoolean("protection.redstone.disable-offline");
066        Redstone.DISABLE_UNOCCUPIED = config
067                .getBoolean("protection.redstone.disable-unoccupied", Redstone.DISABLE_UNOCCUPIED);
068
069        // UUID
070        UUID.OFFLINE = config.getBoolean("UUID.offline", UUID.OFFLINE);
071        UUID.FORCE_LOWERCASE = config.getBoolean("UUID.force-lowercase", UUID.FORCE_LOWERCASE);
072
073        // Mob stuff
074        Enabled_Components.KILL_ROAD_MOBS =
075                config.getBoolean("kill_road_mobs", Enabled_Components.KILL_ROAD_MOBS);
076        Enabled_Components.KILL_ROAD_VEHICLES =
077                config.getBoolean("kill_road_vehicles", Enabled_Components.KILL_ROAD_VEHICLES);
078
079        // Clearing + Expiry
080        //FAST_CLEAR = config.getBoolean("clear.fastmode");
081        Enabled_Components.PLOT_EXPIRY =
082                config.getBoolean("clear.auto.enabled", Enabled_Components.PLOT_EXPIRY);
083        if (Enabled_Components.PLOT_EXPIRY) {
084            Enabled_Components.BAN_DELETER = config.getBoolean("clear.on.ban");
085            AUTO_CLEAR = new ConfigBlock<>();
086            AUTO_CLEAR.put("task1", new Auto_Clear());
087            Auto_Clear task = AUTO_CLEAR.get("task1");
088            task.CALIBRATION = new Auto_Clear.CALIBRATION();
089
090            task.DAYS = config.getInt("clear.auto.days", task.DAYS);
091            task.THRESHOLD = config.getInt("clear.auto.threshold", task.THRESHOLD);
092            task.CONFIRMATION = config.getBoolean("clear.auto.confirmation", task.CONFIRMATION);
093            task.CALIBRATION.CHANGES =
094                    config.getInt("clear.auto.calibration.changes", task.CALIBRATION.CHANGES);
095            task.CALIBRATION.FACES =
096                    config.getInt("clear.auto.calibration.faces", task.CALIBRATION.FACES);
097            task.CALIBRATION.DATA =
098                    config.getInt("clear.auto.calibration.data", task.CALIBRATION.DATA);
099            task.CALIBRATION.AIR =
100                    config.getInt("clear.auto.calibration.air", task.CALIBRATION.AIR);
101            task.CALIBRATION.VARIETY =
102                    config.getInt("clear.auto.calibration.variety", task.CALIBRATION.VARIETY);
103            task.CALIBRATION.CHANGES_SD =
104                    config.getInt("clear.auto.calibration.changes_sd", task.CALIBRATION.CHANGES_SD);
105            task.CALIBRATION.FACES_SD =
106                    config.getInt("clear.auto.calibration.faces_sd", task.CALIBRATION.FACES_SD);
107            task.CALIBRATION.DATA_SD =
108                    config.getInt("clear.auto.calibration.data_sd", task.CALIBRATION.DATA_SD);
109            task.CALIBRATION.AIR_SD =
110                    config.getInt("clear.auto.calibration.air_sd", task.CALIBRATION.AIR_SD);
111            task.CALIBRATION.VARIETY_SD =
112                    config.getInt("clear.auto.calibration.variety_sd", task.CALIBRATION.VARIETY_SD);
113        }
114
115        // Done
116        Done.REQUIRED_FOR_RATINGS =
117                config.getBoolean("approval.ratings.check-done", Done.REQUIRED_FOR_RATINGS);
118        Done.COUNTS_TOWARDS_LIMIT =
119                config.getBoolean("approval.done.counts-towards-limit", Done.COUNTS_TOWARDS_LIMIT);
120        Done.RESTRICT_BUILDING =
121                config.getBoolean("approval.done.restrict-building", Done.RESTRICT_BUILDING);
122        Done.REQUIRED_FOR_DOWNLOAD =
123                config.getBoolean("approval.done.required-for-download", Done.REQUIRED_FOR_DOWNLOAD);
124
125        // Schematics
126        Paths.SCHEMATICS = config.getString("schematics.save_path", Paths.SCHEMATICS);
127
128        // Web
129        Web.URL = config.getString("web.url", Web.URL);
130
131        // Caching
132        Enabled_Components.RATING_CACHE =
133                config.getBoolean("cache.ratings", Enabled_Components.RATING_CACHE);
134
135        // Rating system
136        Ratings.CATEGORIES = config.contains("ratings.categories") ?
137                config.getStringList("ratings.categories") :
138                Ratings.CATEGORIES;
139
140        // Update Notifications
141        Enabled_Components.UPDATE_NOTIFICATIONS =
142                config.getBoolean("update-notifications", Enabled_Components.UPDATE_NOTIFICATIONS);
143
144        // Teleportation
145        Teleport.DELAY = config.getInt("teleport.delay", Teleport.DELAY);
146        Teleport.ON_LOGIN = config.getBoolean("teleport.on_login", Teleport.ON_LOGIN);
147        Teleport.ON_DEATH = config.getBoolean("teleport.on_death", Teleport.ON_DEATH);
148        Teleport.ON_CLEAR = config.getBoolean("teleport.on_clear", Teleport.ON_CLEAR);
149        Teleport.ON_DELETE = config.getBoolean("teleport.on_delete", Teleport.ON_DELETE);
150
151        // Chunk processor
152        Enabled_Components.CHUNK_PROCESSOR =
153                config.getBoolean("chunk-processor.enabled", Enabled_Components.CHUNK_PROCESSOR);
154        Chunk_Processor.AUTO_TRIM =
155                config.getBoolean("chunk-processor.auto-unload", Chunk_Processor.AUTO_TRIM);
156        Chunk_Processor.MAX_TILES =
157                config.getInt("chunk-processor.max-blockstates", Chunk_Processor.MAX_TILES);
158        Chunk_Processor.MAX_ENTITIES =
159                config.getInt("chunk-processor.max-entities", Chunk_Processor.MAX_ENTITIES);
160        Chunk_Processor.DISABLE_PHYSICS =
161                config.getBoolean("chunk-processor.disable-physics", Chunk_Processor.DISABLE_PHYSICS);
162
163        // Comments
164        Enabled_Components.COMMENT_NOTIFIER = config
165                .getBoolean("comments.notifications.enabled", Enabled_Components.COMMENT_NOTIFIER);
166
167        // Plot limits
168        Claim.MAX_AUTO_AREA = config.getInt("claim.max-auto-area", Claim.MAX_AUTO_AREA);
169        Limit.MAX_PLOTS = config.getInt("max_plots", Limit.MAX_PLOTS);
170        Limit.GLOBAL = config.getBoolean("global_limit", Limit.GLOBAL);
171
172        // Miscellaneous
173        DEBUG = config.getBoolean("debug", DEBUG);
174
175        Enabled_Components.DATABASE_PURGER =
176                config.getBoolean("auto-purge", Enabled_Components.DATABASE_PURGER);
177        return true;
178    }
179
180    @Comment("This is an auto clearing task called `task1`")
181    @BlockName("task1")
182    // The name for the default block
183    public static final class Auto_Clear extends ConfigBlock {
184
185        @Create // This value has to be generated since an instance isn't static
186        public CALIBRATION CALIBRATION = null;
187        public int THRESHOLD = -1;
188        public int REQUIRED_PLOTS = -1;
189        public boolean CONFIRMATION = true;
190        public int DAYS = 90;
191        public int SKIP_ACCOUNT_AGE_DAYS = -1;
192        @Comment("True, if a plot should be deleted if the plot owner is unknown to the server")
193        public boolean DELETE_IF_OWNER_IS_UNKNOWN = false;
194        public List<String> WORLDS = new ArrayList<>(Collections.singletonList("*"));
195
196
197        @Comment("See: https://intellectualsites.github.io/plotsquared-documentation/optimization/plot-analysis for a description of each value.")
198        public static final class CALIBRATION {
199
200            public int VARIETY = 0;
201            public int VARIETY_SD = 0;
202            public int CHANGES = 0;
203            public int CHANGES_SD = 1;
204            public int FACES = 0;
205            public int FACES_SD = 0;
206            public int DATA_SD = 0;
207            public int AIR = 0;
208            public int AIR_SD = 0;
209            public int DATA = 0;
210
211        }
212
213    }
214
215
216    @Comment({"Chunk processor related settings",
217            "See https://intellectualsites.github.io/plotsquared-documentation/optimization/chunk-processor for more information."})
218    public static class Chunk_Processor {
219
220        @Comment("Auto trim will not save chunks which aren't claimed")
221        public static boolean
222                AUTO_TRIM = false;
223        @Comment("Max tile entities per chunk")
224        public static int MAX_TILES = 4096;
225        @Comment("Max entities per chunk")
226        public static int MAX_ENTITIES = 512;
227        @Comment("Disable block physics")
228        public static boolean DISABLE_PHYSICS = false;
229
230    }
231
232
233    @Comment({"UUID settings",
234            "DO NOT EDIT them unless you know what you are doing."})
235    public static class UUID {
236
237        @Comment("Force using offline UUIDs (it usually detects the right mode)")
238        public static boolean OFFLINE = false;
239        @Comment("Force using lowercase UUIDs")
240        public static boolean FORCE_LOWERCASE = false;
241        @Comment("How many UUIDs that may be stored in the cache")
242        public static int UUID_CACHE_SIZE = 100000;
243        @Comment("Rate limit (per 10 minutes) for background UUID fetching from the Mojang API")
244        public static int BACKGROUND_LIMIT = 200;
245        @Comment("Whether the Mojang API service is enabled for impromptu api calls. If false only the Background task will use" +
246                " http requests to fill the UUID cache (requires restart)")
247        public static boolean IMPROMPTU_SERVICE_MOJANG_API = true;
248        @Comment("Rate limit (per 10 minutes) for random UUID fetching from the Mojang API")
249        public static int IMPROMPTU_LIMIT = 300;
250        @Comment("Timeout (in milliseconds) for non-blocking UUID requests (mostly commands)")
251        public static long NON_BLOCKING_TIMEOUT = 3000L;
252        @Comment("Timeout (in milliseconds) for blocking UUID requests (events)")
253        public static long BLOCKING_TIMEOUT = 10L;
254        @Comment("Whether or not PlotSquared should read from the legacy database")
255        public static boolean LEGACY_DATABASE_SUPPORT = true;
256        @Comment("Whether or not PlotSquared should return Unknown if it fails to fulfill a request")
257        public static boolean UNKNOWN_AS_DEFAULT = true;
258        @Comment("Whether or not automatic background caching should be enabled. It is HIGHLY recommended to keep this turned on."
259                + " This should only be disabled if the server has a very large number of plots (>100k)")
260        public static boolean BACKGROUND_CACHING_ENABLED = true;
261        @Comment("Whether the PaperMC service is enabled")
262        public static boolean SERVICE_PAPER = true;
263        @Comment("Whether the LuckPerms service is enabled")
264        public static boolean SERVICE_LUCKPERMS = true;
265        @Comment("Whether the Bukkit service is enabled")
266        public static boolean SERVICE_BUKKIT = true;
267        @Comment("Whether the EssentialsX service is enabled")
268        public static boolean SERVICE_ESSENTIALSX = true;
269
270    }
271
272
273    @Comment("General settings")
274    public static final class General {
275
276        @Comment("Display scientific numbers (4.2E8)")
277        public static boolean SCIENTIFIC = false;
278        @Comment("Replace wall when merging")
279        public static boolean MERGE_REPLACE_WALL = true;
280        @Comment("Always show explosion Particles, even if explosion flag is set to false")
281        public static boolean ALWAYS_SHOW_EXPLOSIONS = false;
282        @Comment({"Blocks that may not be used in plot components",
283                "Checkout the wiki article regarding plot components before modifying: https://intellectualsites.github.io/plotsquared-documentation/customization/plot-components"})
284        public static List<String>
285                INVALID_BLOCKS = Arrays.asList(
286                // Acacia Stuff
287                "acacia_button", "acacia_fence_gate", "acacia_door", "acacia_pressure_plate",
288                "acacia_trapdoor", "acacia_sapling", "acacia_sign", "acacia_wall_sign", "acacia_leaves",
289                // Birch Stuff
290                "birch_button", "birch_fence_gate", "birch_door", "birch_pressure_plate",
291                "birch_trapdoor", "birch_sapling", "birch_sign", "birch_wall_sign", "birch_leaves",
292                // Dark Oak Stuff
293                "dark_oak_button", "dark_oak_fence_gate", "dark_oak_door", "dark_oak_pressure_plate",
294                "dark_oak_trapdoor", "dark_oak_sapling", "dark_oak_sign", "dark_oak_wall_sign",
295                "dark_oak_leaves",
296                // Jungle Stuff
297                "jungle_button", "jungle_fence_gate", "jungle_door", "jungle_pressure_plate",
298                "jungle_trapdoor", "jungle_sapling", "jungle_sign", "jungle_wall_sign", "jungle_leaves",
299                // Oak Stuff
300                "oak_button", "oak_fence_gate", "oak_door", "oak_pressure_plate", "oak_trapdoor",
301                "oak_sapling", "oak_sign", "oak_wall_sign", "oak_leaves",
302                // Spruce Stuff
303                "spruce_button", "spruce_fence_gate", "spruce_door", "spruce_pressure_plate",
304                "spruce_trapdoor", "spruce_sapling", "spruce_sign", "spruce_wall_sign", "spruce_leaves",
305                // Rails
306                "activator_rail", "detector_rail", "rail",
307                // Flowers
308                "allium", "azure_bluet", "blue_orchid", "dandelion", "lilac", "orange_tulip",
309                "oxeye_daisy", "peony", "pink_tulip", "poppy", "potted_allium", "potted_azure_bluet",
310                "potted_birch_sapling", "potted_blue_orchid", "potted_brown_mushroom", "potted_cactus",
311                "potted_fern", "potted_jungle_sapling", "potted_oak_sapling", "potted_orange_tulip",
312                "potted_oxeye_daisy", "potted_pink_tulip", "potted_red_mushroom", "potted_red_tulip",
313                "red_mushroom", "red_tulip", "potted_spruce_sapling", "potted_white_tulip", "rose_bush",
314                "sunflower", "white_tulip", "cornflower", "wither_rose",
315                // Stems
316                "attached_melon_stem", "attached_pumpkin_stem", "melon_stem", "pumpkin_stem",
317                "mushroom_stem",
318                // Plants
319                "beetroots", "brown_mushroom", "cactus", "carrots", "chorus_flower", "chorus_plant",
320                "cocoa", "dead_bush", "fern", "kelp_plant", "large_fern", "lily_pad", "potatoes",
321                "sea_pickle", "seagrass", "sugar_cane", "tall_grass", "tall_seagrass", "vine", "wheat",
322                "bamboo",
323                // Misc
324                "anvil", "barrier", "beacon", "brewing_stand", "bubble_column", "cake", "cobweb",
325                "comparator", "creeper_head", "creeper_wall_header", "damaged_anvil",
326                "daylight_detector", "dragon_egg", "dragon_head", "dragon_wall_head",
327                "enchanting_table", "end_gateway", "end_portal", "end_rod", "ender_chest", "chest",
328                "flower_pot", "grass", "heavy_weighted_pressure_plate", "lever",
329                "light_weighted_pressure_plate", "player_head", "redstone_wire", "repeater",
330                "comparator", "redstone_torch", "torch", "redstone_wall_torch", "wall_torch", "sign",
331                "skeleton_skull", "skeleton_wall_skull", "snow", "stone_pressure_plate",
332                "trapped_chest", "tripwire", "tripwire_hook", "turtle_egg", "wall_sign", "zombie_head",
333                "zombie_wall_head", "bell",
334                // Black Stuff
335                "black_bed", "black_banner", "black_carpet", "black_concrete_powder",
336                "black_wall_banner",
337                // Blue Stuff
338                "blue_bed", "blue_banner", "blue_carpet", "blue_concrete_powder", "blue_wall_banner",
339                // Brown Stuff
340                "brown_bed", "brown_banner", "brown_carpet", "brown_concrete_powder",
341                "brown_wall_banner",
342                // Cyan Stuff
343                "cyan_bed", "cyan_banner", "cyan_concrete_powder", "cyan_carpet", "cyan_wall_banner",
344                // Gray Stuff
345                "gray_bed", "gray_banner", "gray_concrete_powder", "gray_carpet", "gray_wall_banner",
346                // Green Stuff
347                "green_bed", "green_banner", "green_concrete_powder", "green_carpet",
348                "green_wall_banner",
349                // Light blue Stuff
350                "light_blue_bed", "light_blue_banner", "light_blue_concrete_powder",
351                "light_blue_carpet", "light_blue_wall_banner",
352                // Light Gray Stuff
353                "light_gray_bed", "light_gray_banner", "light_gray_concrete_powder",
354                "light_gray_carpet", "light_gray_wall_banner",
355                // Lime Stuff
356                "lime_bed", "lime_banner", "lime_concrete_powder", "lime_carpet", "lime_wall_banner",
357                // Magenta Stuff
358                "magenta_bed", "magenta_banner", "magenta_concrete_powder", "magenta_carpet",
359                "magenta_wall_banner",
360                // Orange Stuff
361                "orange_bed", "orange_banner", "orange_concrete_powder", "orange_carpet",
362                "orange_wall_banner",
363                // Pink Stuff
364                "pink_bed", "pink_banner", "pink_concrete_powder", "pink_carpet", "pink_wall_banner",
365                // Purple Stuff
366                "purple_bed", "purple_banner", "purple_concrete_powder", "purple_carpet",
367                "purple_wall_banner",
368                // Red Stuff
369                "red_bed", "red_banner", "red_concrete_powder", "red_carpet", "red_wall_banner",
370                // White Stuff
371                "white_bed", "white_banner", "white_concrete_powder", "white_carpet",
372                "white_wall_banner",
373                // Yellow Stuff
374                "yellow_bed", "yellow_banner", "yellow_concrete_powder", "yellow_carpet",
375                "yellow_wall_banner",
376                // Corals
377                "brain_coral", "brain_coral_fan", "brain_coral_wall_fan", "bubble_coral",
378                "bubble_coral_block", "bubble_coral_fan", "bubble_coral_wall_fan", "dead_brain_coral",
379                "dead_brain_coral_block", "dead_brain_coral_fan", "dead_brain_coral_wall_fan",
380                "dead_bubble_coral", "dead_bubble_coral_fan", "dead_bubble_coral_wall_fan",
381                "dead_fire_coral", "dead_fire_coral_block", "dead_fire_coral_fan",
382                "dead_fire_coral_wall_fan", "dead_horn_coral", "dead_horn_coral_block",
383                "dead_horn_coral_fan", "dead_tube_coral", "dead_tube_coral_wall_fan",
384                "dried_kelp_block", "horn_coral", "horn_coral_block", "horn_coral_fan",
385                "horn_coral_wall_fan", "tube_coral", "tube_coral_block", "tube_coral_fan",
386                "tube_coral_wall_fan"
387        );
388
389    }
390
391
392    @Comment("Update checker settings")
393    public static final class UpdateChecker {
394
395        @Comment("How often to poll for updates (in minutes)")
396        public static int POLL_RATE = 360;
397        @Comment("Only notify console once after an update is found")
398        public static boolean
399                NOTIFY_ONCE = true;
400
401    }
402
403
404    @Comment({"Schematic Settings",
405            "See https://intellectualsites.github.io/plotsquared-documentation/schematics/schematic-on-claim for more information."})
406    public static final class Schematics {
407
408        @Comment(
409                "Whether schematic based generation should paste schematic on top of plots, or from Y=1")
410        public static boolean PASTE_ON_TOP = true;
411        @Comment(
412                "Whether schematic based road generation should paste schematic on top of roads, or from Y=1")
413        public static boolean PASTE_ROAD_ON_TOP = true;
414        @Comment({"If schematics that do not match a plot's size should be pasted anyway",
415                " - This will still only paste a schematic with a plot's bounds.",
416                " - If a schematic is too big, it will cut off, and if too small, will not full the plot."})
417        public static boolean PASTE_MISMATCHES = true;
418        @Comment({"If the wall height should be taken into account when calculating the road schematic paste height",
419                " - If true, will use the lower of wall and road height.",
420                " - If true, will ensure correct schematic behaviour (no parts are cut off).",
421                " - Set to false if you experience the road being set one block too low",
422                "   (only for road schematics created pre 6.1.4)."})
423        public static boolean USE_WALL_IN_ROAD_SCHEM_HEIGHT = true;
424
425    }
426
427
428    @Comment("Configure the paths that will be used")
429    public static final class Paths {
430
431        public static String SCHEMATICS = "schematics";
432        public static String TEMPLATES = "templates";
433
434    }
435
436
437    @Deprecated(forRemoval = true, since = "6.0.0")
438    @Comment("Schematic interface related settings")
439    public static class Web {
440
441        @Comment({"The web interface for schematics", " - All schematics are anonymous and private",
442                " - Downloads can be deleted by the user",
443                " - Supports plot uploads, downloads and saves",})
444        public static String URL =
445                "https://schem.intellectualsites.com/plots/";
446        @Comment({"Whether or not the legacy web interface will be used for /plot download and /plot save",
447                "Note that this will be removed in future versions. Updating to Arkitektonika is highly suggested"})
448        public static boolean LEGACY_WEBINTERFACE = false;
449
450    }
451
452    @Comment("Schematic web interface related settings")
453    public static class Arkitektonika {
454
455        @Comment("The url of the backend server (Arkitektonika)")
456        public static String BACKEND_URL = "https://api.schematic.cloud/";
457
458        @Comment({"The url used to generate a download link from.",
459                "{key} will be replaced with the generated key"})
460        public static String DOWNLOAD_URL = "https://api.schematic.cloud/download/{key}";
461
462        @Comment({"The url used to generate a deletion link from.",
463                "{key} will be replaced with the generated key"})
464        public static String DELETE_URL = "https://api.schematic.cloud/delete/{key}";
465
466    }
467
468    @Comment("Used to format the plot creation date placeholder. Modifying the format does not affect the storage time.")
469    public static class Timeformat {
470
471        @Comment("The date used formatted in ISO 8601")
472        public static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss z";
473
474        @Comment("The time zone used")
475        public static String TIME_ZONE = "GMT";
476
477    }
478
479
480    @Comment("Miscellaneous settings")
481    public static final class Done {
482
483        @Comment("Require a plot marked as done to download (/plot download)")
484        public static boolean
485                REQUIRED_FOR_DOWNLOAD = false;
486        @Comment("Only plots marked as done can be rated")
487        public static boolean
488                REQUIRED_FOR_RATINGS = false;
489        @Comment("Restrict building when a plot is marked as done")
490        public static boolean
491                RESTRICT_BUILDING = false;
492        @Comment("The limit being how many plots a player can claim")
493        public static boolean
494                COUNTS_TOWARDS_LIMIT = true;
495
496    }
497
498
499    @Comment("Chat related settings")
500    public static final class Chat {
501
502        @Comment("Should the plot chat be logged to console?")
503        public static boolean LOG_PLOTCHAT_TO_CONSOLE = true;
504
505        @Comment({"Whether an action bar message should be send over a chat message for notification purposes such for the ",
506                "notify-enter, notify-leave, greeting or farewell flag."})
507        public static boolean NOTIFICATION_AS_ACTIONBAR = false;
508
509        @Comment({"The click event actions that should be removed from user input in e.g. plot flags like 'greeting'.",
510                "Actions like 'RUN_COMMAND' may be used maliciously as players could trick staff into clicking on messages",
511                "triggering destructive commands."})
512        public static List<String> CLICK_EVENT_ACTIONS_TO_REMOVE = Arrays.stream(ClickEvent.Action.values())
513                .map(Enum::name)
514                .collect(Collectors.toList());
515
516    }
517
518
519    @Comment("Relating to how many plots someone can claim")
520    public static final class Limit {
521
522        @Comment("Should the limit be global (over multiple worlds)")
523        public static boolean GLOBAL =
524                false;
525        @Comment({"The max range of permissions to check for, e.g. plots.plot.127",
526                "The value covers the permission range to check, you need to assign the permission to players/groups still",
527                "Modifying the value does NOT change the amount of plots players can claim"})
528        public static int MAX_PLOTS = 127;
529
530    }
531
532
533    @Comment({"Backup related settings",
534            "See https://intellectualsites.github.io/plotsquared-documentation/plot-backups for more information."})
535    public static final class Backup {
536
537        @Comment("Automatically backup plots when destructive commands are performed, e.g. /plot clear")
538        public static boolean AUTOMATIC_BACKUPS = true;
539        @Comment("Maximum amount of backups associated with a plot")
540        public static int
541                BACKUP_LIMIT = 3;
542        @Comment("Whether or not backups should be deleted when the plot is unclaimed")
543        public static boolean DELETE_ON_UNCLAIM = true;
544
545    }
546
547
548    @Comment("Confirmation timeout related settings")
549    public static final class Confirmation {
550
551        @Comment("Timeout before a confirmation prompt expires")
552        public static int
553                CONFIRMATION_TIMEOUT_SECONDS = 20;
554
555    }
556
557
558    @Comment("Teleportation related settings")
559    public static final class Teleport {
560
561        @Comment("Teleport to your plot on death")
562        public static boolean ON_DEATH = false;
563        @Comment("Teleport to your plot on login")
564        public static boolean ON_LOGIN = false;
565        @Comment("Teleport to your plot on claim (/plot claim)")
566        public static boolean ON_CLAIM = true;
567        @Comment("Teleport to your plot on auto (/plot auto)")
568        public static boolean ON_AUTO = true;
569        @Comment({"Add a delay to all teleport commands (in seconds)",
570                "Assign `plots.teleport.delay.bypass` to bypass the cooldown"})
571        public static int DELAY = 0;
572        @Comment("Teleport outside of the plot before clearing")
573        public static boolean ON_CLEAR = false;
574        @Comment("Teleport outside of the plot before deleting")
575        public static boolean ON_DELETE = false;
576        @Comment("The visit command is ordered by world instead of globally")
577        public static boolean PER_WORLD_VISIT = false;
578        @Comment("Search merged plots for having multiple owners when using the visit command")
579        public static boolean VISIT_MERGED_OWNERS = true;
580
581    }
582
583
584    @Comment("Redstone related settings")
585    public static final class Redstone {
586
587        @Comment("Disable redstone in unoccupied plots")
588        public static boolean DISABLE_UNOCCUPIED =
589                false;
590        @Comment("Disable redstone when all owners/trusted/members are offline")
591        public static boolean DISABLE_OFFLINE = false;
592        @Comment(
593                "Detect and cancel invalid pistons on the edge of plots (e.g. placed with WorldEdit)")
594        public static boolean DETECT_INVALID_EDGE_PISTONS = false;
595
596    }
597
598
599    @Comment("Claim related settings")
600    public static final class Claim {
601
602        @Comment("The max plots claimed in a single `/plot auto <size>` command")
603        public static int
604                MAX_AUTO_AREA = 4;
605
606    }
607
608
609    @Comment("Rating related settings")
610    public static final class Ratings {
611
612        @Comment("Replace the rating system with a like system. Will add /plot like/dislike,"
613                + " and remove the rating command")
614        public static boolean USE_LIKES = false;
615        @Comment("Rating categories")
616        public static List<String> CATEGORIES = new ArrayList<>();
617        @Comment("The blocks to use for the rating GUI if categories are set above")
618        public static String BLOCK_0 = "brown_wool";
619        public static String BLOCK_1 = "red_wool";
620        public static String BLOCK_2 = "orange_wool";
621        public static String BLOCK_3 = "yellow_wool";
622        public static String BLOCK_4 = "lime_wool";
623        public static String BLOCK_5 = "cyan_wool";
624        public static String BLOCK_6 = "blue_wool";
625        public static String BLOCK_7 = "purple_wool";
626        public static String BLOCK_8 = "magenta_wool";
627
628    }
629
630    @Comment("Enable or disable all of or parts of the FastAsyncWorldEdit-PlotSquared hook")
631    public static final class FAWE_Components {
632
633        @Comment("Use FastAsyncWorldEdit for queue handling.")
634        public static boolean FAWE_HOOK = true;
635        public static boolean CUBOIDS = true;
636        public static boolean CLEAR = true;
637        public static boolean COPY_AND_SWAP = true;
638        public static boolean SET_BIOME = true;
639
640    }
641
642    @Comment("Enable or disable parts of the plugin specific to using Paper")
643    public static final class Paper_Components {
644
645        @Comment("Enable Paper's listeners.")
646        public static boolean PAPER_LISTENERS = true;
647        @Comment("Prevent entities from leaving plots")
648        public static boolean ENTITY_PATHING = true;
649        @Comment(
650                "Cancel entity spawns when the chunk is loaded if the PlotArea's mob spawning is off")
651        public static boolean CANCEL_CHUNK_SPAWN = true;
652        @Comment("Use paper's PlayerLaunchProjectileEvent to cancel projectiles")
653        public static boolean PLAYER_PROJECTILE = true;
654        @Comment("Cancel entity spawns from spawners before they happen (performance buff)")
655        public static boolean SPAWNER_SPAWN = true;
656        @Comment("Cancel entity spawns from tick spawn rates before they happen (performance buff)")
657        public static boolean CREATURE_SPAWN = true;
658        @Comment("Check the tile entity limit on block placement")
659        public static boolean TILE_ENTITY_CHECK = true;
660        @Comment("Use Paper's async tab completion")
661        public static boolean ASYNC_TAB_COMPLETION;
662
663    }
664
665    @Comment("Settings relating to PlotSquared's GlobalBlockQueue")
666    public static final class QUEUE {
667
668        @Comment({"Average time per tick spent completing chunk tasks in ms.",
669                "Queue will adjust the batch size to match this."})
670        public static int MAX_ITERATION_TIME = 30;
671        @Comment({"Initial number of chunks to process by the queue. This can be increased or",
672                "decreased by the queue based on the actual iteration time compared to above."})
673        public static int INITIAL_BATCH_SIZE = 5;
674        @Comment("Notify progress of the queue to the player or console.")
675        public static boolean NOTIFY_PROGRESS = true;
676        @Comment("Interval in ms to notify player or console of progress.")
677        public static int NOTIFY_INTERVAL = 5000;
678        @Comment({"Time to wait in ms before beginning to notify player or console of progress.",
679                "Prevent needless notification of progress for short queues."})
680        public static int NOTIFY_WAIT = 5000;
681        @Comment({"How lighting should be handled by the queue. Modes:",
682                "  - 0 - Do not do any lighting (fastest)",
683                "  - 1 - Only execute lighting where blocks with light values are placed",
684                "  - 2 - Only execute lighting where blocks with light values are placed or removed/replaced",
685                "  - 3 - Always execute lighting (slowest)"})
686        public static int LIGHTING_MODE = 1;
687        @Comment({"If blocks at the edges of queued operations should be set causing updates",
688                " - Slightly slower, but prevents issues such as fences left connected to nothing"})
689        public static boolean UPDATE_EDGES = true;
690
691    }
692
693    @Comment("Settings related to tab completion")
694    public static final class Tab_Completions {
695
696        @Comment({"The time in seconds how long tab completions should remain in cache.",
697                "0 will disable caching. Lower values may be less performant."})
698        public static int CACHE_EXPIRATION = 15;
699
700    }
701
702    @Comment("Settings related to plot titles")
703    public static final class Titles {
704
705        @Comment({"The big text that appears when you enter a plot.",
706                "For a single plot set `/plot flag set titles false` to disable it.", "For just you run `/plot toggle titles` to disable it.",
707                "For all plots: Add `titles: false` in the worlds.yml flags block to disable it."})
708        public static boolean DISPLAY_TITLES = true;
709        @Comment("Plot titles fading in (duration in ticks)")
710        public static int TITLES_FADE_IN = 10;
711        @Comment("Plot titles being shown (duration in ticks)")
712        public static int TITLES_STAY = 50;
713        @Comment("Plot titles fading out (duration in ticks)")
714        public static int TITLES_FADE_OUT = 20;
715        @Comment({"Changes the notification method on plot entry from Title + SubTitle -> ActionBar.",
716                "The message still sent to the player is pulled from the lang key \"titles.title_entered_plot\".",
717                "If you would like to still show the owner of the plot, append the contents of \"titles.title_entered_plot_sub\" onto the " +
718                        "former lang key."})
719        public static boolean TITLES_AS_ACTIONBAR = false;
720        @Comment({"If the default title should be displayed on plots with server-plot flag set.",
721                "Titles will still be sent if the plot-title flag is set."})
722        public static boolean DISPLAY_DEFAULT_ON_SERVER_PLOT = false;
723
724    }
725
726
727    @Comment({"Enable or disable parts of the plugin",
728            "Note: A cache will use some memory if enabled"})
729    public static final class Enabled_Components { // Group the following values into a new config section
730
731        @Comment("The database stores all the plots")
732        public static boolean DATABASE = true;
733        @Comment("Events are needed to track a lot of things")
734        public static boolean EVENTS = true;
735        @Comment("Commands are used to interact with the plugin")
736        public static boolean COMMANDS =
737                true;
738        @Comment("Whether we should notify you about updates or not.")
739        public static boolean
740                UPDATE_NOTIFICATIONS = true;
741        @Comment("Stores user metadata in a database")
742        public static boolean PERSISTENT_META = true;
743        @Comment("Getting a rating won't need the database")
744        public static boolean RATING_CACHE =
745                true;
746        @Comment("Allow WorldEdit to be restricted to plots")
747        public static boolean
748                WORLDEDIT_RESTRICTIONS = true;
749        @Comment("Allow economy to be used to sell, claim or buy plots.")
750        public static boolean ECONOMY = false;
751        @Comment("Expiry will clear old or simplistic plots")
752        public static boolean PLOT_EXPIRY =
753                false;
754        @Comment("Processes chunks (trimming, or entity/tile limits) ")
755        public static boolean
756                CHUNK_PROCESSOR = false;
757        @Comment("Kill mobs on roads (Chicken, Cow, etc.)")
758        public static boolean KILL_ROAD_MOBS = false;
759        @Comment("Also kill any road mobs that are being ridden, or are leashed")
760        public static boolean
761                KILL_OWNED_ROAD_MOBS = false;
762        @Comment("Also kill any road mobs that are named")
763        public static boolean KILL_NAMED_ROAD_MOBS = false;
764        @Comment("Kill items on roads (Stick, Paper, etc.)")
765        public static boolean KILL_ROAD_ITEMS = false;
766        @Comment("Kill vehicles on roads (Boat, Minecart, etc.)")
767        public static boolean KILL_ROAD_VEHICLES = false;
768        @Comment("Notify a player of any missed plot comments upon plot entry")
769        public static boolean
770                COMMENT_NOTIFIER = true;
771        @Comment("Let players claim entire worlds with PlotSquared")
772        public static boolean WORLDS =
773                false;
774        @Comment("Actively purge invalid database entries")
775        public static boolean DATABASE_PURGER =
776                false;
777        @Comment({"Delete plots when a player is banned.",
778                "Note: This only works with the /minecraft:ban command. Any punishment plugin is not supported."})
779        public static boolean BAN_DELETER = false;
780        @Comment("Allows PlaceholderAPI placeholders to be used in captions, flags, etc.")
781        public static boolean EXTERNAL_PLACEHOLDERS = true;
782        @Comment("Make road regeneration persistent across restarts")
783        public static boolean
784                PERSISTENT_ROAD_REGEN = true;
785        @Comment({"Enable the `/plot component` preset GUI",
786                "Read more about components here: https://intellectualsites.github.io/plotsquared-documentation/customization/plot-components"})
787        public static boolean COMPONENT_PRESETS = true;
788        @Comment("Enable per user locale")
789        public static boolean PER_USER_LOCALE = false;
790        @Comment({"The default locale. Before changing the language, make sure you downloaded the appropriate file and put it " +
791                "in the 'lang' folder.",
792                "You can find additional translations here: https://intellectualsites.crowdin.com/plotsquared"
793        })
794        public static String DEFAULT_LOCALE = "en";
795        @Comment("Use UUID cache to complete usernames")
796        public static boolean EXTENDED_USERNAME_COMPLETION = true;
797        @Comment("Command aliases that will be tab completed")
798        public static List<String> TAB_COMPLETED_ALIASES = Arrays.asList(
799                "plot",
800                "plots",
801                "p",
802                "plotsquared",
803                "plot2",
804                "p2",
805                "ps",
806                "2",
807                "plotme",
808                "plotz",
809                "ap"
810        );
811        @Comment("Whether PlotSquared should hook into MvDWPlaceholderAPI or not")
812        public static boolean USE_MVDWAPI = true;
813        @Comment("Prevent cross plot beacon effects")
814        public static boolean DISABLE_BEACON_EFFECT_OVERFLOW = true;
815
816    }
817
818}