package com.boydti.fawe.config; import com.boydti.fawe.Fawe; import com.boydti.fawe.configuration.MemorySection; import com.boydti.fawe.configuration.file.YamlConfiguration; import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.PseudoRandom; import com.boydti.fawe.object.RunnableVal3; import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.StringMan; import com.boydti.fawe.util.chat.Message; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; public enum BBC { /* * Things to note about this class: * Can use multiple arguments %s, %s1, %s2, %s3 etc */ PREFIX("&8(&4&lFAWE&8)&r&7", "Info"), FILE_DELETED("%s0 has been deleted.", "Info"), SCHEMATIC_PASTING("&7The schematic is pasting. This cannot be undone.", "Info"), LIGHTING_PROPOGATE_SELECTION("&7Lighting has been propogated in %s0 chunks. (Note: To remove light use //removelight)", "Info"), UPDATED_LIGHTING_SELECTION("&7Lighting has been updated in %s0 chunks. (It may take a second for the packets to send)", "Info"), SET_REGION("&7Selection set to your current allowed region", "Info"), WORLDEDIT_COMMAND_LIMIT("&7Please wait until your current action completes", "Info"), WORLDEDIT_DELAYED("&7Please wait while we process your FAWE action...", "Info"), WORLDEDIT_RUN("&7Apologies for the delay. Now executing: %s", "Info"), WORLDEDIT_COMPLETE("&7Edit completed.", "Info"), REQUIRE_SELECTION_IN_MASK("&7%s of your selection is not within your mask. You can only make edits within allowed regions.", "Info"), WORLDEDIT_VOLUME("&7You cannot select a volume of %current%. The maximum volume you can modify is %max%.", "Info"), WORLDEDIT_ITERATIONS("&7You cannot iterate %current% times. The maximum number of iterations allowed is %max%.", "Info"), WORLDEDIT_UNSAFE("&7Access to that command has been blocked", "Info"), WORLDEDIT_DANGEROUS_WORLDEDIT("&cProcessed unsafe edit at %s0 by %s1", "Info"), WORLDEDIT_EXTEND("&cYour edit may have extended outside your allowed region.", "Error"), WORLDEDIT_TOGGLE_TIPS_ON("&7Disabled FAWE tips.", "Info"), WORLDEDIT_TOGGLE_TIPS_OFF("&7Enabled FAWE tips.", "Info"), WORLDEDIT_BYPASSED("&7Currently bypassing FAWE restriction.", "Info"), WORLDEDIT_UNMASKED("&6Your FAWE edits are now unrestricted.", "Info"), WORLDEDIT_RESTRICTED("&6Your FAWE edits are now restricted.", "Info"), WORLDEDIT_OOM_ADMIN("&cPossible options:\n&8 - &7//fast\n&8 - &7Do smaller edits\n&8 - &7Allocate more memory\n&8 - &7Disable `max-memory-percent`", "Info"), COMPRESSED("History compressed. Saved ~ %s0b (%s1x smaller)", "Info"), WEB_UNAUTHORIZED("Only links from the configured web host is allowed: %s0", "Error"), ACTION_COMPLETE("Action completed in %s0 seconds", "Info"), GENERATING_LINK("Uploading %s, please wait...", "Web"), GENERATING_LINK_FAILED("&cFailed to generate download link!", "Web"), DOWNLOAD_LINK("%s", "Web"), MASK_DISABLED("Global mask disabled", "WorldEdit.General"), MASK("Global mask set", "WorldEdit.General"), TEXTURE_DISABLED("Texturing reset", "WorldEdit.General"), TEXTURE_SET("Set texturing to %s1", "WorldEdit.General"), SOURCE_MASK_DISABLED("Global source mask disabled", "WorldEdit.General"), SOURCE_MASK("Global source mask set", "WorldEdit.General"), TRANSFORM_DISABLED("Global transform disabled", "WorldEdit.General"), TRANSFORM("Global transform set", "WorldEdit.General"), COMMAND_COPY("%s0 blocks were copied.", "WorldEdit.Copy"), COMMAND_CUT_SLOW("%s0 blocks were cut.", "WorldEdit.Cut"), COMMAND_CUT_LAZY("%s0 blocks will be removed on paste", "WorldEdit.Cut"), COMMAND_PASTE("The clipboard has been pasted at %s0", "WorldEdit.Paste"), COMMAND_ROTATE("The clipboard has been rotated", "WorldEdit.Rotate"), COMMAND_FLIPPED("The clipboard has been flipped", "WorldEdit.Flip"), COMMAND_REGEN_0("Region regenerated.", "WorldEdit.Regen"), COMMAND_REGEN_1("Region regenerated.", "WorldEdit.Regen"), COMMAND_REGEN_2("Region regenerated.", "WorldEdit.Regen"), COMMAND_TREE("%s0 trees created.", "WorldEdit.Tree"), COMMAND_PUMPKIN("%s0 pumpkin patches created.", "WorldEdit.Tree"), COMMAND_FLORA("%s0 flora created.", "WorldEdit.Flora"), COMMAND_HISTORY_CLEAR("History cleared", "WorldEdit.History"), COMMAND_REDO_ERROR("Nothing left to redo. (See also `/inspect` and `/frb`)", "WorldEdit.History"), COMMAND_HISTORY_OTHER_ERROR("Unable to find session for %s0.", "WorldEdit.History"), COMMAND_REDO_SUCCESS("Redo successful%s0.", "WorldEdit.History"), COMMAND_UNDO_ERROR("Nothing left to undo. (See also `/inspect` and `/frb`)", "WorldEdit.History"), COMMAND_UNDO_SUCCESS("Undo successful%s0.", "WorldEdit.History"), OPERATION("Operation queued (%s0)", "WorldEdit.Operation"), SELECTION_WAND("Left click: select pos #1; Right click: select pos #2", "WorldEdit.Selection"), NAVIGATION_WAND_ERROR("&cNothing to pass through", "WorldEdit.Navigation"), SELECTION_WAND_DISABLE("Edit wand disabled.", "WorldEdit.Selection"), SELECTION_WAND_ENABLE("Edit wand enabled.", "WorldEdit.Selection"), SELECTION_CHUNK("Chunk selected (%s0)", "WorldEdit.Selection"), SELECTION_CHUNKS("Chunks selected (%s0) - (%s1)", "WorldEdit.Selection"), SELECTION_CONTRACT("Region contracted %s0 blocks.", "WorldEdit.Selection"), SELECTION_COUNT("Counted %s0 blocks.", "WorldEdit.Selection"), SELECTION_DISTR("# total blocks: %s0", "WorldEdit.Selection"), SELECTION_EXPAND("Region expanded %s0 blocks", "WorldEdit.Selection"), SELECTION_EXPAND_VERT("Region expanded %s0 blocks (top to bottom)", "WorldEdit.Selection"), SELECTION_INSET("Region inset", "WorldEdit.Selection"), SELECTION_OUTSET("Region outset", "WorldEdit.Selection"), SELECTION_SHIFT("Region shifted", "WorldEdit.Selection"), SELECTION_CLEARED("Selection cleared", "WorldEdit.Selection"), WORLD_IS_LOADED("The world shouldn't be in use when executing. Unload the world, or use use -f to override (save first)", "WorldEdit.Anvil"), BRUSH_RESET("Reset your brush. (SHIFT + Click)", "WorldEdit.Brush"), BRUSH_NONE("You aren't holding a brush!", "WorldEdit.Brush"), BRUSH_SCROLL_ACTION_SET("Set scroll action to %s0", "WorldEdit.Brush"), BRUSH_SCROLL_ACTION_UNSET("Removed scroll action", "WorldEdit.Brush"), BRUSH_VISUAL_MODE_SET("Set visual mode to %s0", "WorldEdit.Brush"), BRUSH_TARGET_MODE_SET("Set target mode to %s0", "WorldEdit.Brush"), BRUSH_TARGET_MASK_SET("Set target mask to %s0", "WorldEdit.Brush"), BRUSH_TARGET_OFFSET_SET("Set target offset to %s0", "WorldEdit.Brush"), BRUSH_EQUIPPED("Equipped brush %s0", "WorldEdit.Brush"), BRUSH_TRY_OTHER("&cThere are other more suitable brushes e.g.\n&8 - &7//br height [radius=5] [#clipboard|file=null] [rotation=0] [yscale=1.00]", "WorldEdit.Brush"), BRUSH_COPY("Left click the base of an object to copy, right click to paste. Increase the brush radius if necessary.", "WorldEdit.Brush"), BRUSH_HEIGHT_INVALID("Invalid height map file (%s0)", "WorldEdit.Brush"), BRUSH_SMOOTH("Note: Use the blend brush if you want to smooth overhangs or caves.", "WorldEdit.Brush"), BRUSH_SPLINE("Click to add a point, click the same spot to finish", "WorldEdit.Brush"), BRUSH_LINE_PRIMARY("Added point %s0, click another position to create the line", "WorldEdit.Brush"), BRUSH_CATENARY_DIRECTION("Added point %s0, click the direction you want to create the spline", "WorldEdit.Brush"), BRUSH_LINE_SECONDARY("Created spline", "WorldEdit.Brush"), BRUSH_SPLINE_PRIMARY_2("Added position, Click the same spot to join!", "WorldEdit.Brush"), BRUSH_SPLINE_SECONDARY_ERROR("Not enough positions set!", "WorldEdit.Brush"), BRUSH_SPLINE_SECONDARY("Created spline", "WorldEdit.Brush"), BRUSH_SIZE("Brush size set", "WorldEdit.Brush"), BRUSH_RANGE("Brush size set", "WorldEdit.Brush"), BRUSH_MASK_DISABLED("Brush mask disabled", "WorldEdit.Brush"), BRUSH_MASK("Brush mask set", "WorldEdit.Brush"), BRUSH_SOURCE_MASK_DISABLED("Brush source mask disabled", "WorldEdit.Brush"), BRUSH_SOURCE_MASK("Brush source mask set", "WorldEdit.Brush"), BRUSH_TRANSFORM_DISABLED("Brush transform disabled", "WorldEdit.Brush"), BRUSH_TRANSFORM("Brush transform set", "WorldEdit.Brush"), BRUSH_MATERIAL("Brush material set", "WorldEdit.Brush"), ROLLBACK_ELEMENT("Undoing %s0", "WorldEdit.Rollback"), TOOL_INSPECT("Inspect tool bound to %s0.", "WorldEdit.Tool"), TOOL_INSPECT_INFO("&7%s0 changed %s1 to %s2 %s3 ago", "WorldEdit.Tool"), TOOL_INSPECT_INFO_FOOTER("&6Total: &7%s0 changes", "WorldEdit.Tool"), TOOL_NONE("Tool unbound from your current item.", "WorldEdit.Tool"), TOOL_INFO("Info tool bound to %s0.", "WorldEdit.Tool"), TOOL_TREE("Tree tool bound to %s0.", "WorldEdit.Tool"), TOOL_TREE_ERROR("Tree type %s0 is unknown.", "WorldEdit.Tool"), TOOL_REPL("Block replacer tool bound to %s0.", "WorldEdit.Tool"), TOOL_CYCLER("Block data cycler tool bound to %s0.", "WorldEdit.Tool"), TOOL_FLOOD_FILL("Block flood fill tool bound to %s0.", "WorldEdit.Tool"), TOOL_RANGE_ERROR("Maximum range: %s0.", "WorldEdit.Tool"), TOOL_RADIUS_ERROR("Maximum allowed brush radius: %s0.", "WorldEdit.Tool"), TOOL_DELTREE("Floating tree remover tool bound to %s0.", "WorldEdit.Tool"), TOOL_FARWAND("Far wand tool bound to %s0.", "WorldEdit.Tool"), TOOL_LRBUILD_BOUND("Long-range building tool bound to %s0.", "WorldEdit.Tool"), TOOL_LRBUILD_INFO("Left-click set to %s0; right-click set to %s1.", "WorldEdit.Tool"), SUPERPICKAXE_ENABLED("Super Pickaxe enabled.", "WorldEdit.Tool"), SUPERPICKAXE_DISABLED("Super Pickaxe disabled.", "WorldEdit.Tool"), SUPERPICKAXE_AREA_ENABLED("Mode changed. Left click with a pickaxe. // to disable.", "WorldEdit.Tool"), SNAPSHOT_LOADED("Snapshot '%s0' loaded; now restoring...", "WorldEdit.Snapshot"), SNAPSHOT_SET("Snapshot set to: %s0", "WorldEdit.Snapshot"), SNAPSHOT_NEWEST("Now using newest snapshot.", "WorldEdit.Snapshot"), SNAPSHOT_LIST_HEADER("Snapshots for world (%s0):", "WorldEdit.Snapshot"), SNAPSHOT_LIST_FOOTER("Use /snap use [snapshot] or /snap use latest.", "WorldEdit.Snapshot"), BIOME_LIST_HEADER("Biomes (page %s0/%s1):", "WorldEdit.Biome"), BIOME_CHANGED("Biomes were changed in %s0 columns.", "WorldEdit.Biome"), FAST_ENABLED("Fast mode enabled. History and edit restrictions will be bypassed.", "WorldEdit.General"), FAST_DISABLED("Fast mode disabled", "WorldEdit.General"), PLACE_ENABLED("Now placing at pos #1.", "WorldEdit.General"), PLACE_DISABLED("Now placing at the block you stand in.", "WorldEdit.General"), KILL_SUCCESS("Killed %s0 entities in a radius of %s1.", "WorldEdit.Utility"), NOTHING_CONFIRMED("You have no actions pending confirmation.", "WorldEdit.Utility"), SCHEMATIC_PROMPT_CLEAR("&7You may want to use &c%s0 &7to clear your current clipboard first", "Worldedit.Schematic"), SCHEMATIC_SHOW("&7Displaying &a%s0&7 schematics from &a%s1&7:\n" + "&8 - &aLeft click &7a structure to set your clipboard\n" + "&8 - &aRight click &7to add a structure to your multi-clipboard\n" + "&8 - &7Use &a%s2&7 to go back to the world", "Worldedit.Schematic"), SCHEMATIC_FORMAT("Available formats (Name: Lookup names)", "Worldedit.Schematic"), SCHEMATIC_MOVE_EXISTS("&c%s0 already exists", "Worldedit.Schematic"), SCHEMATIC_MOVE_SUCCESS("&a%s0 -> %s1", "Worldedit.Schematic"), SCHEMATIC_MOVE_FAILED("&a%s0 no moved: %s1", "Worldedit.Schematic"), SCHEMATIC_LOADED("%s0 loaded. Paste it with //paste", "Worldedit.Schematic"), SCHEMATIC_SAVED("%s0 saved.", "Worldedit.Schematic"), SCHEMATIC_PAGE("Page must be %s", "WorldEdit.Schematic"), SCHEMATIC_NONE("No files found.", "WorldEdit.Schematic"), SCHEMATIC_LIST("Available files (Filename: Format) [%s0/%s1]:", "Worldedit.Schematic"), SCHEMATIC_LIST_ELEM("&8 - &a%s0 &8- &7%s1", "Worldedit.Schematic"), CLIPBOARD_URI_NOT_FOUND("You do not have %s0 loaded", "WorldEdit.Clipboard"), CLIPBOARD_CLEARED("Clipboard cleared", "WorldEdit.Clipboard"), CLIPBOARD_INVALID_FORMAT("Unknown clipboard format: %s0", "WorldEdit.Clipboard"), VISITOR_BLOCK("%s0 blocks affected", "WorldEdit.Visitor"), VISITOR_ENTITY("%s0 entities affected", "WorldEdit.Visitor"), VISITOR_FLAT("%s0 columns affected", "WorldEdit.Visitor"), SELECTOR_FUZZY_POS1("Region set and expanded from %s0 %s1.", "WorldEdit.Selector"), SELECTOR_FUZZY_POS2("Added expansion of %s0 %s1.", "WorldEdit.Selector"), SELECTOR_POS("pos%s0 set to %s1 (%s2).", "WorldEdit.Selector"), SELECTOR_CENTER("Center set to %s0 (%s1).", "WorldEdit.Selector"), SELECTOR_RADIUS("Radius set to %s0 (%s1).", "WorldEdit.Selector"), SELECTOR_EXPANDED("Expanded region to %s0 (%s1)", "WorldEdit.Selector"), SELECTOR_INVALID_COORDINATES("Invalid coordinates %s0", "WorldEdit.Selector"), SELECTOR_ALREADY_SET("Position already set.", "WorldEdit.Selector"), SELECTOR_SET_DEFAULT("Your default region selector is now %s0.", "WorldEdit.Selector"), TIMEZONE_SET("Timezone set for this session to: %s0", "WorldEdit.Timezone"), TIMEZONE_DISPLAY("The current time in that timezone is: %s0", "WorldEdit.Timezone"), COMMAND_INVALID_SYNTAX("The command was not used properly (no more help available).", "WorldEdit.Command"), COMMAND_CLARIFYING_BRACKET("&7Added clarifying bracket for &c%s0", "WorldEdit.Help"), HELP_SUGGEST("&7Couldn't find %s0. Maybe try one of &c%s1 &7?", "WorldEdit.Help"), HELP_HEADER_CATEGORIES("Command Types", "WorldEdit.Help"), HELP_HEADER_SUBCOMMANDS("Subcommands", "WorldEdit.Help"), HELP_HEADER_COMMAND("&cHelp for: &7%s0", "WorldEdit.Help"), HELP_ITEM_ALLOWED("&a%s0&8 - &7%s1", "WorldEdit.Help"), HELP_ITEM_DENIED("&c%s0&8 - &7%s1", "WorldEdit.Help"), HELP_HEADER("Help: page %s0/%s1", "WorldEdit.Help"), HELP_FOOTER("&7Wiki: https://git.io/vSKE5", "WorldEdit.Help"), PAGE_FOOTER("Use %s0 to go to the next page", "WorldEdit.Utility"), PROGRESS_MESSAGE("%s1/%s0 (%s2%) @%s3cps %s4s left", "Progress"), PROGRESS_FINISHED("[ Done! ]", "Progress"), COMMAND_SYNTAX("&cUsage: &7%s0", "Error"), NO_PERM("&cYou are lacking the permission node: %s0", "Error"), SETTING_DISABLE("&cLacking setting: %s0", "Error"), BRUSH_NOT_FOUND("&cAvailable brushes: %s0", "Error"), BRUSH_INCOMPATIBLE("&cBrush not compatible with this version", "Error"), SCHEMATIC_NOT_FOUND("&cSchematic not found: &7%s0", "Error"), NO_REGION("&cYou have no current allowed region", "Error"), NO_MASK("&cYou have no current mask set", "Error"), NOT_PLAYER("&cYou must be a player to perform this action!", "Error"), PLAYER_NOT_FOUND("&cPlayer not found:&7 %s0", "Error"), OOM( "&8[&cCritical&8] &cDetected low memory i.e. < 1%. We will take the following actions:\n&8 - &7Terminate WE block placement\n&8 - &7Clear WE history\n&8 - &7Unload non essential chunks\n&8 - &7Kill entities\n&8 - &7Garbage collect\n&cIgnore this if trying to crash server.\n&7Note: Low memory is likely (but not necessarily) caused by WE", "Error"), WORLDEDIT_SOME_FAILS("&c%s0 blocks weren't placed because they were outside your allowed region.", "Error"), WORLDEDIT_SOME_FAILS_BLOCKBAG("&cMissing blocks: %s0", "Error"), WORLDEDIT_CANCEL_COUNT("&cCancelled %s0 edits.", "Cancel"), WORLDEDIT_CANCEL_REASON_CONFIRM("&7Your selection is large (&c%s0 &7-> &c%s1&7, containing &c%s3&7 blocks). Use &c//confirm &7to execute &c%s2", "Cancel"), WORLDEDIT_CANCEL_REASON("&cYour WorldEdit action was cancelled:&7 %s0&c.", "Cancel"), WORLDEDIT_CANCEL_REASON_MANUAL("Manual cancellation", "Cancel"), WORLDEDIT_CANCEL_REASON_LOW_MEMORY("Low memory", "Cancel"), WORLDEDIT_CANCEL_REASON_MAX_CHANGES("Too many blocks changed", "Cancel"), WORLDEDIT_CANCEL_REASON_MAX_CHECKS("Too many block checks", "Cancel"), WORLDEDIT_CANCEL_REASON_MAX_TILES("Too many blockstates", "Cancel"), WORLDEDIT_CANCEL_REASON_MAX_ENTITIES("Too many entities", "Cancel"), WORLDEDIT_CANCEL_REASON_MAX_ITERATIONS("Max iterations", "Cancel"), WORLDEDIT_CANCEL_REASON_OUTSIDE_LEVEL("Outside world", "Cancel"), WORLDEDIT_CANCEL_REASON_OUTSIDE_REGION("Outside allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)", "Cancel"), WORLDEDIT_CANCEL_REASON_NO_REGION("No allowed region (bypass with /wea, or disable `region-restrictions` in config.yml)", "Cancel"), WORLDEDIT_FAILED_LOAD_CHUNK("&cSkipped loading chunk: &7%s0;%s1&c. Try increasing chunk-wait.", "Cancel"), ASCEND_FAIL("No free spot above you found.", "Navigation"), ASCENDED_PLURAL("Ascended %s0 levels.", "Navigation"), ASCENDED_SINGULAR("Ascended a level.", "Navigation"), UNSTUCK("There you go!", "Navigation"), DESCEND_FAIL("No free spot below you found.", "Navigation"), DESCEND_PLURAL("Descended %s0 levels.", "Navigation"), DESCEND_SINGULAR("Descended a level.", "Navigation"), WHOOSH("Whoosh!", "Navigation"), POOF("Poof!", "Navigation"), THRU_FAIL("No free spot ahead of you found.", "Navigation"), NO_BLOCK("No block in sight! (or too far)", "Navigation"), UP_FAIL("You would hit something above you.", "Navigation"), SEL_CUBOID("Cuboid: left click for point 1, right click for point 2", "Selection"), SEL_CUBOID_EXTEND("Cuboid: left click for a starting point, right click to extend", "Selection"), SEL_2D_POLYGON("2D polygon selector: Left/right click to add a point.", "Selection"), SEL_ELLIPSIOD("Ellipsoid selector: left click=center, right click to extend", "Selection"), SEL_SPHERE("Sphere selector: left click=center, right click to set radius", "Selection"), SEL_CYLINDRICAL("Cylindrical selector: Left click=center, right click to extend.", "Selection"), SEL_MAX("%s0 points maximum.", "Selection"), SEL_FUZZY("Fuzzy selector: Left click to select all contingent blocks, right click to add. To select an air cavity, use //pos1.", "Selection"), SEL_CONVEX_POLYHEDRAL("Convex polyhedral selector: Left click=First vertex, right click to add more.", "Selection"), SEL_LIST("For a list of selection types use:&c //sel list", "Selection"), SEL_MODES("Select one of the modes below:", "Selection"), TIP_SEL_LIST("Tip: See the different selection modes with &c//sel list", "Tips"), TIP_SELECT_CONNECTED("Tip: Select all connected blocks with //sel fuzzy", "Tips"), TIP_SET_POS1("Tip: Use pos1 as a pattern with &c//set pos1", "Tips"), TIP_FARWAND("Tip: Select distant points with &c//farwand", "Tips"), // cut TIP_LAZYCUT("&7Tip: It is safer to use &c//lazycut", "Tips"), // set TIP_FAST("&7Tip: Set fast and without undo using &c//fast", "Tips"), TIP_CANCEL("&7Tip: You can &c//cancel &7an edit in progress", "Tips"), TIP_MASK("&7Tip: Set a global destination mask with &c/gmask", "Tips"), TIP_MASK_ANGLE("Tip: Replace upward slopes of 3-20 blocks using&c //replace /[-20][-3] bedrock", "Tips"), TIP_SET_LINEAR("&7Tip: Set blocks linearly with&c //set #l3d[wood,bedrock]", "Tips"), TIP_SURFACE_SPREAD("&7Tip: Spread a flat surface with&c //set #surfacespread[5][0][5][#existing]", "Tips"), TIP_SET_HAND("&7Tip: Use your current hand with &c//set hand", "Tips"), // replace TIP_REPLACE_ID("&7Tip: Replace only the block id:&c //replace woodenstair #id[cobblestair]", "Tips"), TIP_REPLACE_LIGHT("Tip: Remove light sources with&c //replace #brightness[1][15] 0", "Tips"), TIP_TAB_COMPLETE("Tip: The replace command supports tab completion", "Tips"), // clipboard TIP_FLIP("Tip: Mirror with &c//flip", "Tips"), TIP_DEFORM("Tip: Reshape with &c//deform", "Tips"), TIP_TRANSFORM("Tip: Set a transform with &c//gtransform", "Tips"), TIP_COPYPASTE("Tip: Paste on click with &c//br copypaste", "Tips"), TIP_SOURCE_MASK("Tip: Set a source mask with &c/gsmask &7", "Tips"), TIP_REPLACE_MARKER("Tip: Replace a block with your full clipboard using &c//replace wool #fullcopy", "Tips"), TIP_PASTE("Tip: Place with &c//paste", "Tips"), TIP_LAZYCOPY("Tip: lazycopy is faster", "Tips"), TIP_DOWNLOAD("Tip: Try out &c//download", "Tips"), TIP_ROTATE("Tip: Orientate with &c//rotate", "Tips"), TIP_COPY_PATTERN("Tip: To use as a pattern try &c#copy", "Tips"), // regen TIP_REGEN_0("Tip: Use a biome with /regen [biome]", "Tips"), TIP_REGEN_1("Tip: Use a seed with /regen [biome] [seed]", "Tips"), TIP_BIOME_PATTERN("Tip: The &c#biome[forest]&7 pattern can be used in any command", "Tips"), TIP_BIOME_MASK("Tip: Restrict to a biome with the `$jungle` mask", "Tips"),; private static final HashMap replacements = new HashMap<>(); static { for (final char letter : "1234567890abcdefklmnor".toCharArray()) { replacements.put("&" + letter, "\u00a7" + letter); } replacements.put("\\\\n", "\n"); replacements.put("\\n", "\n"); replacements.put("&-", "\n"); } /** * Translated */ private String s; /** * Default */ private String d; /** * What locale category should this translation fall under */ private String cat; /** * Should the string be prefixed? */ private boolean prefix; /** * Constructor for custom strings. */ BBC() { /* * use setCustomString(); */ } /** * Constructor * * @param d default * @param prefix use prefix */ BBC(final String d, final boolean prefix, final String cat) { this.d = d; if (this.s == null) { this.s = d; } this.prefix = prefix; this.cat = cat.toLowerCase(); } /** * Constructor * * @param d default */ BBC(final String d, final String cat) { this(d, true, cat.toLowerCase()); } public String f(final Object... args) { return format(args); } public String format(final Object... args) { String m = this.s; for (int i = args.length - 1; i >= 0; i--) { if (args[i] == null) { continue; } m = m.replace("%s" + i, args[i].toString()); } if (args.length > 0) { m = m.replace("%s", args[0].toString()); } return m; } public static void load(final File file) { try { if (!file.exists()) { file.getParentFile().mkdirs(); file.createNewFile(); } final YamlConfiguration yml = YamlConfiguration.loadConfiguration(file); final Set keys = yml.getKeys(true); final EnumSet all = EnumSet.allOf(BBC.class); final HashSet allNames = new HashSet<>(); final HashSet allCats = new HashSet<>(); final HashSet toRemove = new HashSet<>(); for (final BBC c : all) { allNames.add(c.name()); allCats.add(c.cat.toLowerCase()); } final HashSet captions = new HashSet<>(); boolean changed = false; for (final String key : keys) { final Object value = yml.get(key); if (value instanceof MemorySection) { continue; } final String[] split = key.split("\\."); final String node = split[split.length - 1].toUpperCase(); final BBC caption = allNames.contains(node) ? valueOf(node) : null; if (caption != null) { if (!split[0].equalsIgnoreCase(caption.cat)) { changed = true; yml.set(key, null); yml.set(caption.cat + "." + caption.name().toLowerCase(), value); } captions.add(caption); caption.s = (String) value; } else { toRemove.add(key); } } for (final String remove : toRemove) { changed = true; yml.set(remove, null); } for (final BBC caption : all) { if (!captions.contains(caption)) { changed = true; yml.set(caption.cat + "." + caption.name().toLowerCase(), caption.d); } caption.s = StringMan.replaceFromMap(caption.s, replacements); } if (changed) { yml.save(file); } } catch (final Exception e) { MainUtil.handleError(e); } } @Override public String toString() { return s(); } public boolean isEmpty() { return length() == 0; } public int length() { return toString().length(); } public static String color(String string) { return StringMan.replaceFromMap(string, replacements); } public static String stripColor(String string) { return StringMan.removeFromSet(string, replacements.keySet()); } public String s() { return this.s; } public Message m(Object... args) { return new Message(this, args); } public String original() { return d; } public boolean usePrefix() { return this.prefix; } public String getCat() { return this.cat; } public BBC or(BBC... others) { int index = PseudoRandom.random.nextInt(others.length + 1); return index == 0 ? this : others[index - 1]; } public void send(Object actor, final Object... args) { if (isEmpty()) { return; } if (actor == null) { Fawe.debug(this.format(args)); } else { try { Method method = actor.getClass().getMethod("print", String.class); method.setAccessible(true); method.invoke(actor, (PREFIX.isEmpty() ? "" : PREFIX.s() + " ") + this.format(args)); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } } public static String getPrefix() { return (PREFIX.isEmpty() ? "" : PREFIX.s() + " "); } public void send(final FawePlayer player, final Object... args) { if (isEmpty()) { return; } if (player == null) { Fawe.debug(this.format(args)); } else { player.sendMessage((PREFIX.isEmpty() ? "" : PREFIX.s() + " ") + this.format(args)); } } public static char getCode(String name) { switch (name) { case "BLACK": return '0'; case "DARK_BLUE": return '1'; case "DARK_GREEN": return '2'; case "DARK_AQUA": return '3'; case "DARK_RED": return '4'; case "DARK_PURPLE": return '5'; case "GOLD": return '6'; case "GRAY": return '7'; case "DARK_GRAY": return '8'; case "BLUE": return '9'; case "GREEN": return 'a'; case "AQUA": return 'b'; case "RED": return 'c'; case "LIGHT_PURPLE": return 'd'; case "YELLOW": return 'e'; case "WHITE": return 'f'; case "OBFUSCATED": return 'k'; case "BOLD": return 'l'; case "STRIKETHROUGH": return 'm'; case "UNDERLINE": return 'n'; case "ITALIC": return 'o'; default: case "RESET": return 'r'; } } public static String getColorName(char code) { switch (code) { case '0': return "BLACK"; case '1': return "DARK_BLUE"; case '2': return "DARK_GREEN"; case '3': return "DARK_AQUA"; case '4': return "DARK_RED"; case '5': return "DARK_PURPLE"; case '6': return "GOLD"; default: case '7': return "GRAY"; case '8': return "DARK_GRAY"; case '9': return "BLUE"; case 'a': return "GREEN"; case 'b': return "AQUA"; case 'c': return "RED"; case 'd': return "LIGHT_PURPLE"; case 'e': return "YELLOW"; case 'f': return "WHITE"; case 'k': return "OBFUSCATED"; case 'l': return "BOLD"; case 'm': return "STRIKETHROUGH"; case 'n': return "UNDERLINE"; case 'o': return "ITALIC"; case 'r': return "RESET"; } } private static Object[] append(StringBuilder builder, Map obj, String color, Map properties) { Object[] style = new Object[] { color, properties }; for (Map.Entry entry : obj.entrySet()) { switch (entry.getKey()) { case "text": String text = (String) entry.getValue(); String newColor = (String) obj.get("color"); String newBold = (String) obj.get("bold"); int index = builder.length(); if (!Objects.equals(color, newColor)) { style[0] = newColor; char code = BBC.getCode(newColor.toUpperCase()); builder.append('\u00A7').append(code); } for (Map.Entry entry2 : obj.entrySet()) { if (StringMan.isEqualIgnoreCaseToAny(entry2.getKey(), "bold", "italic", "underlined", "strikethrough", "obfuscated")) { boolean newValue = Boolean.valueOf((String) entry2.getValue()); if (properties.put(entry2.getKey(), newValue) != newValue) { if (newValue) { char code = BBC.getCode(entry2.getKey().toUpperCase()); builder.append('\u00A7').append(code); } else { builder.insert(index, '\u00A7').append('r'); if (Objects.equals(color, newColor) && newColor != null) { builder.append('\u00A7').append(BBC.getCode(newColor.toUpperCase())); } } } } } builder.append(text); break; case "extra": List> list = (List>) entry.getValue(); for (Map elem : list) { elem.putIfAbsent("color", obj.get("color")); for (Map.Entry entry2 : obj.entrySet()) { if (StringMan.isEqualIgnoreCaseToAny(entry2.getKey(), "bold", "italic", "underlined", "strikethrough", "obfuscated")) { elem.putIfAbsent(entry2.getKey(), entry2.getValue()); } } style = append(builder, elem, (String) style[0], (Map) style[1]); } } } return style; } public static String jsonToString(String text) { Gson gson = new Gson(); StringBuilder builder = new StringBuilder(); Map obj = gson.fromJson(text, new TypeToken>() {}.getType()); HashMap properties = new HashMap<>(); properties.put("bold", false); properties.put("italic", false); properties.put("underlined", false); properties.put("strikethrough", false); properties.put("obfuscated", false); append(builder, obj, null, properties); return builder.toString(); } /** * @param m * @param runPart Part, Color, NewLine */ public static void splitMessage(String m, RunnableVal3 runPart) { m = color(m); String color = "GRAY"; boolean newline = false; for (String line : m.split("\n")) { boolean hasColor = line.charAt(0) == '\u00A7'; String[] splitColor = line.split("\u00A7"); for (String part : splitColor) { if (hasColor) { color = getColorName(part.charAt(0)); part = part.substring(1); } runPart.run(part, color, newline); hasColor = true; } newline = true; } } }