A message describing what happened
*/ public static void debug(String route, String message) { - if (stargateConfig == null || stargateConfig.isDebuggingEnabled()) { + if (stargateConfig == null || stargateConfig.isNotLoaded() || stargateConfig.isDebuggingEnabled()) { logger.info("[Stargate::" + route + "] " + message); } else { logger.log(Level.FINEST, "[Stargate::" + route + "] " + message); @@ -219,7 +220,7 @@ public class Stargate extends JavaPlugin { * @param messageThe message to log
*/ public static void logInfo(String message) { - logger.info(getBackupString("prefix") + message); + log(Level.INFO, message); } /** @@ -247,7 +248,10 @@ public class Stargate extends JavaPlugin { * @param messageThe message to log
*/ private static void log(Level severity, String message) { - logger.log(severity, getBackupString("prefix") + message); + if (logger == null) { + logger = Bukkit.getLogger(); + } + logger.log(severity, message); } /** @@ -349,9 +353,9 @@ public class Stargate extends JavaPlugin { super.reloadConfig(); this.configuration = new StargateYamlConfiguration(); try { - configuration.load(configFile); + this.configuration.load(new File(getDataFolder(), CONFIG_FILE_NAME)); } catch (IOException | InvalidConfigurationException e) { - Stargate.logSevere(e.getMessage()); + logSevere("Unable to load the configuration! Message: " + e.getMessage()); } } @@ -359,9 +363,9 @@ public class Stargate extends JavaPlugin { public void saveConfig() { super.saveConfig(); try { - configuration.save(configFile); + this.configuration.save(new File(getDataFolder(), CONFIG_FILE_NAME)); } catch (IOException e) { - logSevere(e.getMessage()); + logSevere("Unable to save the configuration! Message: " + e.getMessage()); } } @@ -369,30 +373,41 @@ public class Stargate extends JavaPlugin { public void onDisable() { PortalHandler.closeAllPortals(); PortalRegistry.clearPortals(); - stargateConfig.clearManagedWorlds(); + if (stargateConfig != null) { + stargateConfig.clearManagedWorlds(); + } getServer().getScheduler().cancelTasks(this); } @Override public void onEnable() { - configFile = new File(this.getDataFolder(), "config.yml"); + Stargate.stargate = this; + Stargate.logger = getLogger(); + this.saveDefaultConfig(); + this.getConfig(); PluginDescriptionFile pluginDescriptionFile = this.getDescription(); pluginManager = getServer().getPluginManager(); - configuration = new StargateYamlConfiguration(); + this.configuration = new StargateYamlConfiguration(); try { - configuration.load(configFile); + this.configuration.load(new File(getDataFolder(), CONFIG_FILE_NAME)); } catch (IOException | InvalidConfigurationException e) { - Stargate.logSevere(e.getMessage()); + getLogger().log(Level.SEVERE, e.getMessage()); } - this.saveDefaultConfig(); - configuration.options().copyDefaults(true); + this.configuration.options().copyDefaults(true); - logger = Logger.getLogger("Minecraft"); Server server = getServer(); - stargate = this; - stargateConfig = new StargateConfig(logger); - stargateConfig.finishSetup(); + try { + stargateConfig = new StargateConfig(logger); + stargateConfig.finishSetup(); + } catch (NoClassDefFoundError exception) { + logSevere("Could not properly load. Class not found: " + + exception.getMessage() + "\nThis is probably because you are using CraftBukkit, or other outdated" + + "Minecraft server software. Minecraft server software based on Spigot or Paper is required. Paper" + + " is recommended, and can be downloaded at: https://papermc.io/downloads/paper"); + this.onDisable(); + return; + } pluginVersion = pluginDescriptionFile.getVersion(); diff --git a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java index 0383794..bd8a335 100644 --- a/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java +++ b/src/main/java/net/knarcraft/stargate/config/LanguageLoader.java @@ -45,7 +45,7 @@ public final class LanguageLoader { loadedBackupStrings = load("en", inputStream); } else { loadedBackupStrings = null; - Stargate.getConsoleLogger().severe("[stargate] Error loading backup language. " + + Stargate.logSevere("Error loading backup language. " + "There may be missing text in-game"); } } @@ -120,8 +120,8 @@ public final class LanguageLoader { try { readChangedLanguageStrings(inputStream, language, currentLanguageValues); - } catch (IOException ex) { - ex.printStackTrace(); + } catch (IOException exception) { + Stargate.logSevere("Unable to read language strings! Message: " + exception.getMessage()); } } @@ -226,7 +226,7 @@ public final class LanguageLoader { strings = FileHelper.readKeyValuePairs(bufferedReader, "=", ColorConversion.NORMAL); } catch (Exception e) { if (Stargate.getStargateConfig().isDebuggingEnabled()) { - Stargate.getConsoleLogger().info("[Stargate] Unable to load language " + lang); + Stargate.logInfo("Unable to load language " + lang); } return null; } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java index ea8598d..5569e4d 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateConfig.java @@ -14,7 +14,9 @@ import net.knarcraft.stargate.utility.PortalFileHelper; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.command.CommandSender; +import org.bukkit.configuration.MemorySection; import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.messaging.Messenger; import org.dynmap.DynmapAPI; @@ -47,6 +49,7 @@ public final class StargateConfig { private String gateFolder; private String portalFolder; private String languageName = "en"; + private boolean isLoaded = false; private final MapTrue if not fully loaded
+ */ + public boolean isNotLoaded() { + return !this.isLoaded; } /** @@ -364,10 +378,11 @@ public final class StargateConfig { FileConfiguration newConfig = Stargate.getInstance().getConfiguration(); boolean isMigrating = false; - if (newConfig.getString("lang") != null || newConfig.getString("economy.freeGatesGreen") != null || - newConfig.getString("economy.taxAccount") == null) { + if (newConfig.getString("lang") != null || newConfig.getString("economy.taxAccount") == null) { migrateConfig(newConfig); isMigrating = true; + Stargate.getInstance().reloadConfig(); + newConfig = Stargate.getInstance().getConfiguration(); } //Copy missing default values if any values are missing @@ -398,10 +413,17 @@ public final class StargateConfig { //Get important folders from the config portalFolder = (String) configOptions.get(ConfigOption.PORTAL_FOLDER); + if (portalFolder.isEmpty()) { + portalFolder = dataFolderPath + "/portals/"; + } gateFolder = (String) configOptions.get(ConfigOption.GATE_FOLDER); + if (gateFolder.isEmpty()) { + gateFolder = dataFolderPath + "/gates/"; + } //If users have an outdated config, assume they also need to update their default gates if (isMigrating) { + this.createMissingFolders(); GateHandler.writeDefaultGatesToFolder(gateFolder); } @@ -434,18 +456,26 @@ public final class StargateConfig { /** * Changes all configuration values from the old name to the new name * - * @param newConfigThe config to read from and write to
+ * @param currentConfigurationThe current config to back up
*/ - private void migrateConfig(FileConfiguration newConfig) { + private void migrateConfig(FileConfiguration currentConfiguration) { + String debugPath = "StargateConfig::migrateConfig"; + //Save the old config just in case something goes wrong try { - newConfig.save(dataFolderPath + "/config.yml.old"); + currentConfiguration.save(new File(dataFolderPath, "config.yml.old")); } catch (IOException e) { - Stargate.debug("Stargate::migrateConfig", "Unable to save old backup and do migration"); - e.printStackTrace(); + Stargate.debug(debugPath, "Unable to save old backup and do migration"); return; } + //Load old and new configuration + Stargate.getInstance().reloadConfig(); + FileConfiguration oldConfiguration = Stargate.getInstance().getConfig(); + YamlConfiguration newConfiguration = StargateYamlConfiguration.loadConfiguration( + FileHelper.getBufferedReaderFromInputStream( + FileHelper.getInputStreamForInternalFile("/config.yml"))); + //Read all available config migrations MapThe folder to create
+ * @param errorMessageThe error message to display if unable to create the folder
+ */ + private void createMissingFolder(File folder, String errorMessage) { + if (!folder.exists() && !folder.mkdirs()) { + logger.severe(errorMessage); } } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java index f1dc7ca..f97cd16 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateGateConfig.java @@ -313,14 +313,16 @@ public final class StargateGateConfig { try { PortalSignDrawer.setMainColor(ChatColor.of(mainSignColor.toUpperCase())); } catch (IllegalArgumentException | NullPointerException exception) { - Stargate.logWarning("You have specified an invalid main sign color in your config.yml. Defaulting to BLACK"); + Stargate.logWarning("You have specified an invalid main sign color in your config.yml (" + mainSignColor + + "). Defaulting to BLACK"); PortalSignDrawer.setMainColor(ChatColor.BLACK); } try { PortalSignDrawer.setHighlightColor(ChatColor.of(highlightSignColor.toUpperCase())); } catch (IllegalArgumentException | NullPointerException exception) { - Stargate.logWarning("You have specified an invalid highlighting sign color in your config.yml. Defaulting to WHITE"); + Stargate.logWarning("You have specified an invalid highlighting sign color in your config.yml (" + + highlightSignColor + "). Defaulting to WHITE"); PortalSignDrawer.setHighlightColor(ChatColor.WHITE); } } diff --git a/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java b/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java index 2b5f751..085c3b2 100644 --- a/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java +++ b/src/main/java/net/knarcraft/stargate/config/StargateYamlConfiguration.java @@ -10,22 +10,35 @@ import java.util.ArrayList; import java.util.List; /** - * A YAML configuration which keeps all comments + * A YAML configuration which retains all comments + * + *This configuration converts all comments to YAML values when loaded, which all start with comment_. When saved, + * those YAML values are converted to normal text comments. This ensures that the comments aren't removed by the + * YamlConfiguration during its parsing.
* * @author Thorin */ public class StargateYamlConfiguration extends YamlConfiguration { + public static final String START_OF_COMMENT_LINE = "[HASHTAG]"; static public final String END_OF_COMMENT = "_endOfComment_"; static public final String START_OF_COMMENT = "comment_"; + @Override + @SuppressWarnings("deprecation") + protected @NotNull String buildHeader() { + return ""; + } + @Override public @NotNull String saveToString() { + // Convert YAML comments to normal comments return this.convertYAMLMappingsToComments(super.saveToString()); } @Override public void loadFromString(@NotNull String contents) throws InvalidConfigurationException { + // Convert normal comments to YAML comments to prevent them from disappearing super.loadFromString(this.convertCommentsToYAMLMappings(contents)); } @@ -41,27 +54,64 @@ public class StargateYamlConfiguration extends YamlConfiguration { StringBuilder yamlBuilder = new StringBuilder(); ListThe string builder used for building YAML
+ * @param currentCommentThe comment to add as a YAML string
+ * @param lineThe current line
+ * @param previousIndentationThe indentation of the current block comment
+ * @param commentIdThe id of the comment
+ */ + private void addYamlString(StringBuilder yamlBuilder, ListThe list to add to
+ * @param commentThe comment to add
+ */ + private void addComment(ListThe string builder to write to
+ * @param linesThe lines to read from
+ * @param startIndexThe index to start reading from
+ * @param commentIndentationThe indentation of the read comment
+ * @returnThe index containing the next non-comment line
+ */ + private int readComment(StringBuilder builder, String[] lines, int startIndex, int commentIndentation) { + for (int currentIndex = startIndex; currentIndex < lines.length; currentIndex++) { + String line = lines[currentIndex]; + String possibleComment = line.trim(); + if (!line.contains(END_OF_COMMENT)) { + possibleComment = possibleComment.replace(START_OF_COMMENT_LINE, ""); + builder.append(addIndentation(commentIndentation)).append("# ").append(possibleComment).append("\n"); + } else { + return currentIndex; + } + } + + return startIndex; + } + /** * Gets a string containing the given indentation * diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java index 563a93f..d488ca2 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/Gate.java @@ -7,6 +7,7 @@ import org.bukkit.Material; import org.bukkit.Tag; import java.io.BufferedWriter; +import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; @@ -290,7 +291,7 @@ public class Gate { */ public void save(String gateFolder) { try { - BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(gateFolder + filename)); + BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File(gateFolder, filename))); //Save main material names writeConfig(bufferedWriter, "portal-open", portalOpenBlock.name()); @@ -309,8 +310,8 @@ public class Gate { layout.saveLayout(bufferedWriter); bufferedWriter.close(); - } catch (IOException ex) { - Stargate.logSevere(String.format("Could not save Gate %s - %s", filename, ex.getMessage())); + } catch (IOException exception) { + Stargate.logSevere(String.format("Could not save Gate %s - %s", filename, exception.getMessage())); } } diff --git a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java index aca723a..197fe6b 100644 --- a/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java +++ b/src/main/java/net/knarcraft/stargate/portal/property/gate/GateHandler.java @@ -152,7 +152,7 @@ public class GateHandler { } //Update gate file in case the format has changed between versions - gate.save(parentFolder + "/"); + gate.save(parentFolder); return gate; } diff --git a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java index 677e80f..b59bde2 100644 --- a/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/BungeeHelper.java @@ -82,8 +82,7 @@ public final class BungeeHelper { //Send the plugin message player.sendPluginMessage(Stargate.getInstance(), bungeeChannel, byteArrayOutputStream.toByteArray()); } catch (IOException ex) { - Stargate.logSevere("Error sending BungeeCord teleport packet"); - ex.printStackTrace(); + Stargate.logSevere("Error sending BungeeCord teleport packet! Message: " + ex.getMessage()); return false; } return true; @@ -107,9 +106,8 @@ public final class BungeeHelper { //Send the plugin message player.sendPluginMessage(Stargate.getInstance(), bungeeChannel, byteArrayOutputStream.toByteArray()); - } catch (IOException ex) { - Stargate.logSevere("Error sending BungeeCord connect packet"); - ex.printStackTrace(); + } catch (IOException exception) { + Stargate.logSevere("Error sending BungeeCord connect packet! Message: " + exception.getMessage()); return false; } return true; @@ -137,9 +135,8 @@ public final class BungeeHelper { data = new byte[dataLength]; //Read the message to the prepared array dataInputStream.readFully(data); - } catch (IOException ex) { - Stargate.logSevere("Error receiving BungeeCord message"); - ex.printStackTrace(); + } catch (IOException exception) { + Stargate.logSevere("Error receiving BungeeCord message. Message: " + exception.getMessage()); return null; } return new String(data); diff --git a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java index 74741fc..6ba84e7 100644 --- a/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java +++ b/src/main/java/net/knarcraft/stargate/utility/PortalFileHelper.java @@ -170,10 +170,9 @@ public final class PortalFileHelper { "Starting post loading tasks", world)); doPostLoadTasks(world, needsToSaveDatabase); return true; - } catch (Exception e) { - Stargate.logSevere(String.format("Exception while reading stargates from %s: %d", database.getName(), - lineIndex)); - e.printStackTrace(); + } catch (Exception exception) { + Stargate.logSevere(String.format("Exception while reading stargates from %s: %d! Message: %s", + database.getName(), lineIndex, exception.getMessage())); } return false; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index caeac8f..008f456 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,4 +1,4 @@ -# Version: ${project.version} +# Version: ${project.version} # +--------------▄▄▄-- ‚——. -▄--▄-▄--▄-▄-▄▄▄▄▄---------------------------------------------------+ # # | █▄▄▀ (“‡‡”) █▄▄▀ █▄▄▀ █ █ Support available at: sgrewritten.org/discord | # # | █▄▄█ \__/ █ █ █ █ █ █ ‚-. | # @@ -107,6 +107,33 @@ gates: # This is more resource intensive, and should really only be used if verifyPortals is true. # Or if using an easily destroyable open/closed material. protectEntrance: false + + cosmetic: + # Will the destination a networked portal last connected to be listed first in its scroll menu? + rememberDestination: false + + # For networked gates, are destinations listed alphabetically instead of chronologically? + # (This applies to all non-fixed and non-random gates). + sortNetworkDestinations: false + + # What color will StarGate use for the text on gate signs? + # Note that players can override this with DYE and/or GLOW_INK_SAC + mainSignColor: BLACK + + # What color will StarGate use to accent the above text? + highlightSignColor: WHITE + + # Text and highlight colors can be modified on a per-sign basis (below). + # Format: 'SIGN_TYPE:mainSignColor,highlightSignColor' + perSignColors: + - 'ACACIA:default,default' + - 'BIRCH:default,default' + - 'CRIMSON:inverted,inverted' + - 'DARK_OAK:inverted,inverted' + - 'JUNGLE:default,default' + - 'OAK:default,default' + - 'SPRUCE:inverted,inverted' + - 'WARPED:inverted,inverted' # +----------------------------------------------------------------------------------------------+ # # | Economy | # @@ -149,32 +176,12 @@ economy: # https://hub.spigotmc.org/javadocs/spigot/org/bukkit/ChatColor.html freeGatesColor: DARK_GREEN - cosmetic: - # Will the destination a networked portal last connected to be listed first in its scroll menu? - rememberDestination: false - - # For networked gates, are destinations listed alphabetically instead of chronologically? - # (This applies to all non-fixed and non-random gates). - sortNetworkDestinations: false - - # What color will StarGate use for the text on gate signs? - # Note that players can override this with DYE and/or GLOW_INK_SAC - mainSignColor: BLACK - - # What color will StarGate use to accent the above text? - highlightSignColor: WHITE - - # Text and highlight colors can be modified on a per-sign basis (below). - # Format: 'SIGN_TYPE:mainSignColor,highlightSignColor' - perSignColors: - - 'ACACIA:default,default' - - 'BIRCH:default,default' - - 'CRIMSON:inverted,inverted' - - 'DARK_OAK:inverted,inverted' - - 'JUNGLE:default,default' - - 'OAK:default,default' - - 'SPRUCE:inverted,inverted' - - 'WARPED:inverted,inverted' + # Does your server have a tax account (closed economy)? + # If so, please provide the name of your tax account (collected money will be sent to it). + # If not, leave this section blank (collected money will be deleted). + # + # Note that useCost money is excluded from this system when toOwner is true. + taxAccount: '' # +----------------------------------------------------------------------------------------------+ # # | Technical | #