Browse Source

new config pt 9

nossr50 6 years ago
parent
commit
9731b9cffb
100 changed files with 2951 additions and 2301 deletions
  1. 3 3
      src/main/java/com/gmail/nossr50/api/ExperienceAPI.java
  2. 2 2
      src/main/java/com/gmail/nossr50/api/PartyAPI.java
  3. 2 2
      src/main/java/com/gmail/nossr50/chat/AdminChatManager.java
  4. 2 2
      src/main/java/com/gmail/nossr50/chat/PartyChatManager.java
  5. 3 3
      src/main/java/com/gmail/nossr50/commands/MHDCommand.java
  6. 2 2
      src/main/java/com/gmail/nossr50/commands/McmmoCommand.java
  7. 2 2
      src/main/java/com/gmail/nossr50/commands/McscoreboardCommand.java
  8. 0 2
      src/main/java/com/gmail/nossr50/commands/XprateCommand.java
  9. 2 2
      src/main/java/com/gmail/nossr50/commands/chat/ChatCommand.java
  10. 2 2
      src/main/java/com/gmail/nossr50/commands/chat/PartyChatCommand.java
  11. 2 2
      src/main/java/com/gmail/nossr50/commands/database/McpurgeCommand.java
  12. 2 2
      src/main/java/com/gmail/nossr50/commands/database/MmoshowdbCommand.java
  13. 2 2
      src/main/java/com/gmail/nossr50/commands/hardcore/HardcoreCommand.java
  14. 2 2
      src/main/java/com/gmail/nossr50/commands/hardcore/VampirismCommand.java
  15. 2 2
      src/main/java/com/gmail/nossr50/commands/party/PartyInfoCommand.java
  16. 2 2
      src/main/java/com/gmail/nossr50/commands/party/PartyInviteCommand.java
  17. 2 2
      src/main/java/com/gmail/nossr50/commands/party/PartyItemShareCommand.java
  18. 2 2
      src/main/java/com/gmail/nossr50/commands/party/PartyXpShareCommand.java
  19. 3 3
      src/main/java/com/gmail/nossr50/commands/party/alliance/PartyAllianceCommand.java
  20. 3 3
      src/main/java/com/gmail/nossr50/commands/party/teleport/PtpAcceptCommand.java
  21. 6 6
      src/main/java/com/gmail/nossr50/commands/party/teleport/PtpCommand.java
  22. 5 5
      src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java
  23. 3 3
      src/main/java/com/gmail/nossr50/commands/player/MccooldownCommand.java
  24. 4 4
      src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java
  25. 4 4
      src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java
  26. 4 4
      src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java
  27. 7 9
      src/main/java/com/gmail/nossr50/commands/skills/FishingCommand.java
  28. 3 4
      src/main/java/com/gmail/nossr50/commands/skills/SkillCommand.java
  29. 0 1
      src/main/java/com/gmail/nossr50/commands/skills/SwordsCommand.java
  30. 295 183
      src/main/java/com/gmail/nossr50/config/AdvancedConfig.java
  31. 0 135
      src/main/java/com/gmail/nossr50/config/AutoUpdateConfigLoader.java
  32. 59 0
      src/main/java/com/gmail/nossr50/config/ChildConfig.java
  33. 38 0
      src/main/java/com/gmail/nossr50/config/ChunkConversionOptions.java
  34. 259 497
      src/main/java/com/gmail/nossr50/config/Config.java
  35. 7 0
      src/main/java/com/gmail/nossr50/config/ConfigCollection.java
  36. 19 0
      src/main/java/com/gmail/nossr50/config/ConfigCollections.java
  37. 0 89
      src/main/java/com/gmail/nossr50/config/ConfigLoader.java
  38. 0 312
      src/main/java/com/gmail/nossr50/config/ConfigLoaderConfigurable.java
  39. 43 0
      src/main/java/com/gmail/nossr50/config/ConfigValidated.java
  40. 0 35
      src/main/java/com/gmail/nossr50/config/ConfigurableTest.java
  41. 24 21
      src/main/java/com/gmail/nossr50/config/CoreSkillsConfig.java
  42. 3 0
      src/main/java/com/gmail/nossr50/config/DefaultKeys.java
  43. 0 68
      src/main/java/com/gmail/nossr50/config/HiddenConfig.java
  44. 1045 0
      src/main/java/com/gmail/nossr50/config/MainConfig.java
  45. 42 37
      src/main/java/com/gmail/nossr50/config/RankConfig.java
  46. 11 0
      src/main/java/com/gmail/nossr50/config/RegistersKeys.java
  47. 47 39
      src/main/java/com/gmail/nossr50/config/SoundConfig.java
  48. 8 0
      src/main/java/com/gmail/nossr50/config/Unload.java
  49. 12 0
      src/main/java/com/gmail/nossr50/config/VersionedConfig.java
  50. 23 28
      src/main/java/com/gmail/nossr50/config/WorldBlacklist.java
  51. 6 0
      src/main/java/com/gmail/nossr50/config/collectionconfigs/CollectionClassType.java
  52. 119 0
      src/main/java/com/gmail/nossr50/config/collectionconfigs/MultiConfigManager.java
  53. 185 0
      src/main/java/com/gmail/nossr50/config/collectionconfigs/RepairConfig.java
  54. 48 43
      src/main/java/com/gmail/nossr50/config/collectionconfigs/SalvageConfig.java
  55. 258 139
      src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java
  56. 4 3
      src/main/java/com/gmail/nossr50/config/mods/ArmorConfigManager.java
  57. 3 2
      src/main/java/com/gmail/nossr50/config/mods/BlockConfigManager.java
  58. 29 21
      src/main/java/com/gmail/nossr50/config/mods/CustomArmorConfig.java
  59. 20 22
      src/main/java/com/gmail/nossr50/config/mods/CustomBlockConfig.java
  60. 15 15
      src/main/java/com/gmail/nossr50/config/mods/CustomEntityConfig.java
  61. 22 23
      src/main/java/com/gmail/nossr50/config/mods/CustomToolConfig.java
  62. 1 0
      src/main/java/com/gmail/nossr50/config/mods/EntityConfigManager.java
  63. 1 0
      src/main/java/com/gmail/nossr50/config/mods/ToolConfigManager.java
  64. 9 6
      src/main/java/com/gmail/nossr50/config/party/ItemWeightConfig.java
  65. 17 25
      src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java
  66. 0 166
      src/main/java/com/gmail/nossr50/config/skills/repair/RepairConfig.java
  67. 0 42
      src/main/java/com/gmail/nossr50/config/skills/repair/RepairConfigManager.java
  68. 0 42
      src/main/java/com/gmail/nossr50/config/skills/salvage/SalvageConfigManager.java
  69. 32 33
      src/main/java/com/gmail/nossr50/config/treasure/TreasureConfig.java
  70. 2 2
      src/main/java/com/gmail/nossr50/database/DatabaseManager.java
  71. 3 3
      src/main/java/com/gmail/nossr50/database/DatabaseManagerFactory.java
  72. 12 13
      src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java
  73. 30 31
      src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java
  74. 0 1
      src/main/java/com/gmail/nossr50/datatypes/experience/SkillXpGain.java
  75. 5 6
      src/main/java/com/gmail/nossr50/datatypes/party/Party.java
  76. 2 2
      src/main/java/com/gmail/nossr50/datatypes/party/PartyFeature.java
  77. 2 2
      src/main/java/com/gmail/nossr50/datatypes/party/PartyTeleportRecord.java
  78. 9 11
      src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java
  79. 2 4
      src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java
  80. 11 12
      src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java
  81. 3 3
      src/main/java/com/gmail/nossr50/datatypes/skills/SuperAbilityType.java
  82. 1 2
      src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java
  83. 1 2
      src/main/java/com/gmail/nossr50/datatypes/skills/subskills/AbstractSubSkill.java
  84. 3 3
      src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java
  85. 2 2
      src/main/java/com/gmail/nossr50/datatypes/treasure/Treasure.java
  86. 3 5
      src/main/java/com/gmail/nossr50/listeners/BlockListener.java
  87. 3 5
      src/main/java/com/gmail/nossr50/listeners/EntityListener.java
  88. 4 4
      src/main/java/com/gmail/nossr50/listeners/InventoryListener.java
  89. 13 14
      src/main/java/com/gmail/nossr50/listeners/PlayerListener.java
  90. 6 7
      src/main/java/com/gmail/nossr50/listeners/SelfListener.java
  91. 2 2
      src/main/java/com/gmail/nossr50/locale/LocaleLoader.java
  92. 27 29
      src/main/java/com/gmail/nossr50/mcMMO.java
  93. 7 7
      src/main/java/com/gmail/nossr50/party/PartyManager.java
  94. 3 4
      src/main/java/com/gmail/nossr50/party/ShareHandler.java
  95. 4 4
      src/main/java/com/gmail/nossr50/runnables/backups/CleanBackupsTask.java
  96. 2 2
      src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandDisplayTask.java
  97. 2 2
      src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java
  98. 0 1
      src/main/java/com/gmail/nossr50/runnables/database/FormulaConversionTask.java
  99. 3 4
      src/main/java/com/gmail/nossr50/runnables/database/UUIDUpdateAsyncTask.java
  100. 2 2
      src/main/java/com/gmail/nossr50/runnables/database/UserPurgeTask.java

+ 3 - 3
src/main/java/com/gmail/nossr50/api/ExperienceAPI.java

@@ -1,7 +1,7 @@
 package com.gmail.nossr50.api;
 package com.gmail.nossr50.api;
 
 
 import com.gmail.nossr50.api.exceptions.*;
 import com.gmail.nossr50.api.exceptions.*;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
@@ -753,7 +753,7 @@ public final class ExperienceAPI {
      * @throws InvalidSkillException if the given skill is not valid
      * @throws InvalidSkillException if the given skill is not valid
      */
      */
     public static int getLevelCap(String skillType) {
     public static int getLevelCap(String skillType) {
-        return Config.getInstance().getLevelCap(getSkillType(skillType));
+        return MainConfig.getInstance().getLevelCap(getSkillType(skillType));
     }
     }
 
 
     /**
     /**
@@ -764,7 +764,7 @@ public final class ExperienceAPI {
      * @return the overall power level cap
      * @return the overall power level cap
      */
      */
     public static int getPowerLevelCap() {
     public static int getPowerLevelCap() {
-        return Config.getInstance().getPowerLevelCap();
+        return MainConfig.getInstance().getPowerLevelCap();
     }
     }
 
 
     /**
     /**

+ 2 - 2
src/main/java/com/gmail/nossr50/api/PartyAPI.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.api;
 package com.gmail.nossr50.api;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.interactions.NotificationType;
 import com.gmail.nossr50.datatypes.interactions.NotificationType;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.PartyLeader;
 import com.gmail.nossr50.datatypes.party.PartyLeader;
@@ -101,7 +101,7 @@ public final class PartyAPI {
      */
      */
     public static int getMaxPartySize()
     public static int getMaxPartySize()
     {
     {
-        return Config.getInstance().getPartyMaxSize();
+        return MainConfig.getInstance().getPartyMaxSize();
     }
     }
 
 
     /**
     /**

+ 2 - 2
src/main/java/com/gmail/nossr50/chat/AdminChatManager.java

@@ -1,12 +1,12 @@
 package com.gmail.nossr50.chat;
 package com.gmail.nossr50.chat;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.events.chat.McMMOAdminChatEvent;
 import com.gmail.nossr50.events.chat.McMMOAdminChatEvent;
 import org.bukkit.plugin.Plugin;
 import org.bukkit.plugin.Plugin;
 
 
 public class AdminChatManager extends ChatManager {
 public class AdminChatManager extends ChatManager {
     protected AdminChatManager(Plugin plugin) {
     protected AdminChatManager(Plugin plugin) {
-        super(plugin, Config.getInstance().getAdminDisplayNames(), Config.getInstance().getAdminChatPrefix());
+        super(plugin, MainConfig.getInstance().getAdminDisplayNames(), MainConfig.getInstance().getAdminChatPrefix());
     }
     }
 
 
     @Override
     @Override

+ 2 - 2
src/main/java/com/gmail/nossr50/chat/PartyChatManager.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.chat;
 package com.gmail.nossr50.chat;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.events.chat.McMMOPartyChatEvent;
 import com.gmail.nossr50.events.chat.McMMOPartyChatEvent;
 import com.gmail.nossr50.runnables.party.PartyChatTask;
 import com.gmail.nossr50.runnables.party.PartyChatTask;
@@ -10,7 +10,7 @@ public class PartyChatManager extends ChatManager {
     private Party party;
     private Party party;
 
 
     protected PartyChatManager(Plugin plugin) {
     protected PartyChatManager(Plugin plugin) {
-        super(plugin, Config.getInstance().getPartyDisplayNames(), Config.getInstance().getPartyChatPrefix());
+        super(plugin, MainConfig.getInstance().getPartyDisplayNames(), MainConfig.getInstance().getPartyChatPrefix());
     }
     }
 
 
     public void setParty(Party party) {
     public void setParty(Party party) {

+ 3 - 3
src/main/java/com/gmail/nossr50/commands/MHDCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.database.FlatfileDatabaseManager;
 import com.gmail.nossr50.database.FlatfileDatabaseManager;
 import com.gmail.nossr50.database.SQLDatabaseManager;
 import com.gmail.nossr50.database.SQLDatabaseManager;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -21,7 +21,7 @@ public class MHDCommand implements TabExecutor {
             SQLDatabaseManager m = (SQLDatabaseManager) mcMMO.getDatabaseManager();
             SQLDatabaseManager m = (SQLDatabaseManager) mcMMO.getDatabaseManager();
             m.resetMobHealthSettings();
             m.resetMobHealthSettings();
             for (McMMOPlayer player : UserManager.getPlayers()) {
             for (McMMOPlayer player : UserManager.getPlayers()) {
-                player.getProfile().setMobHealthbarType(Config.getInstance().getMobHealthbarDefault());
+                player.getProfile().setMobHealthbarType(MainConfig.getInstance().getMobHealthbarDefault());
             }
             }
             sender.sendMessage("Mob health reset");
             sender.sendMessage("Mob health reset");
             return true;
             return true;
@@ -30,7 +30,7 @@ public class MHDCommand implements TabExecutor {
             FlatfileDatabaseManager m = (FlatfileDatabaseManager) mcMMO.getDatabaseManager();
             FlatfileDatabaseManager m = (FlatfileDatabaseManager) mcMMO.getDatabaseManager();
             m.resetMobHealthSettings();
             m.resetMobHealthSettings();
             for (McMMOPlayer player : UserManager.getPlayers()) {
             for (McMMOPlayer player : UserManager.getPlayers()) {
-                player.getProfile().setMobHealthbarType(Config.getInstance().getMobHealthbarDefault());
+                player.getProfile().setMobHealthbarType(MainConfig.getInstance().getMobHealthbarDefault());
             }
             }
             sender.sendMessage("Mob health reset");
             sender.sendMessage("Mob health reset");
             return true;
             return true;

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/McmmoCommand.java

@@ -1,7 +1,7 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
 import com.gmail.nossr50.commands.party.PartySubcommandType;
 import com.gmail.nossr50.commands.party.PartySubcommandType;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
@@ -24,7 +24,7 @@ public class McmmoCommand implements CommandExecutor {
                 String[] mcSplit = description.split(",");
                 String[] mcSplit = description.split(",");
                 sender.sendMessage(mcSplit);
                 sender.sendMessage(mcSplit);
 
 
-                if (Config.getInstance().getDonateMessageEnabled()) {
+                if (MainConfig.getInstance().getDonateMessageEnabled()) {
                     sender.sendMessage(LocaleLoader.getString("MOTD.Donate"));
                     sender.sendMessage(LocaleLoader.getString("MOTD.Donate"));
                     sender.sendMessage(ChatColor.GOLD + " - " + ChatColor.GREEN + "nossr50@gmail.com" + ChatColor.GOLD + " Paypal");
                     sender.sendMessage(ChatColor.GOLD + " - " + ChatColor.GREEN + "nossr50@gmail.com" + ChatColor.GOLD + " Paypal");
                 }
                 }

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/McscoreboardCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
 import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
@@ -31,7 +31,7 @@ public class McscoreboardCommand implements TabExecutor {
                 }
                 }
 
 
                 if (args[0].equalsIgnoreCase("keep")) {
                 if (args[0].equalsIgnoreCase("keep")) {
-                    if (!Config.getInstance().getAllowKeepBoard() || !Config.getInstance().getScoreboardsEnabled()) {
+                    if (!MainConfig.getInstance().getAllowKeepBoard() || !MainConfig.getInstance().getScoreboardsEnabled()) {
                         sender.sendMessage(LocaleLoader.getString("Commands.Disabled"));
                         sender.sendMessage(LocaleLoader.getString("Commands.Disabled"));
                         return true;
                         return true;
                     }
                     }

+ 0 - 2
src/main/java/com/gmail/nossr50/commands/XprateCommand.java

@@ -1,7 +1,5 @@
 package com.gmail.nossr50.commands;
 package com.gmail.nossr50.commands;
 
 
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/chat/ChatCommand.java

@@ -2,7 +2,7 @@ package com.gmail.nossr50.commands.chat;
 
 
 import com.gmail.nossr50.chat.ChatManager;
 import com.gmail.nossr50.chat.ChatManager;
 import com.gmail.nossr50.chat.ChatManagerFactory;
 import com.gmail.nossr50.chat.ChatManagerFactory;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -119,7 +119,7 @@ public abstract class ChatCommand implements TabExecutor {
             return;
             return;
         }
         }
 
 
-        if (chatMode == ChatMode.PARTY && (mcMMOPlayer.getParty().getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.CHAT))) {
+        if (chatMode == ChatMode.PARTY && (mcMMOPlayer.getParty().getLevel() < MainConfig.getInstance().getPartyFeatureUnlockLevel(PartyFeature.CHAT))) {
             sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.1"));
             sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.1"));
             return;
             return;
         }
         }

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/chat/PartyChatCommand.java

@@ -1,7 +1,7 @@
 package com.gmail.nossr50.commands.chat;
 package com.gmail.nossr50.commands.chat;
 
 
 import com.gmail.nossr50.chat.PartyChatManager;
 import com.gmail.nossr50.chat.PartyChatManager;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
@@ -29,7 +29,7 @@ public class PartyChatCommand extends ChatCommand {
                 return;
                 return;
             }
             }
 
 
-            if (party.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.CHAT)) {
+            if (party.getLevel() < MainConfig.getInstance().getPartyFeatureUnlockLevel(PartyFeature.CHAT)) {
                 sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.1"));
                 sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.1"));
                 return;
                 return;
             }
             }

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/database/McpurgeCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.database;
 package com.gmail.nossr50.commands.database;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableList;
@@ -17,7 +17,7 @@ public class McpurgeCommand implements TabExecutor {
             case 0:
             case 0:
                 mcMMO.getDatabaseManager().purgePowerlessUsers();
                 mcMMO.getDatabaseManager().purgePowerlessUsers();
 
 
-                if (Config.getInstance().getOldUsersCutoff() != -1) {
+                if (MainConfig.getInstance().getOldUsersCutoff() != -1) {
                     mcMMO.getDatabaseManager().purgeOldUsers();
                     mcMMO.getDatabaseManager().purgeOldUsers();
                 }
                 }
 
 

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/database/MmoshowdbCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.database;
 package com.gmail.nossr50.commands.database;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.database.DatabaseManagerFactory;
 import com.gmail.nossr50.database.DatabaseManagerFactory;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableList;
@@ -22,7 +22,7 @@ public class MmoshowdbCommand implements TabExecutor {
                     return true;
                     return true;
                 }
                 }
 
 
-                sender.sendMessage(LocaleLoader.getString("Commands.mmoshowdb", (Config.getInstance().getUseMySQL() ? "sql" : "flatfile")));
+                sender.sendMessage(LocaleLoader.getString("Commands.mmoshowdb", (MainConfig.getInstance().getUseMySQL() ? "sql" : "flatfile")));
                 return true;
                 return true;
 
 
             default:
             default:

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/hardcore/HardcoreCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.hardcore;
 package com.gmail.nossr50.commands.hardcore;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -45,7 +45,7 @@ public class HardcoreCommand extends HardcoreModeCommand {
 
 
     @Override
     @Override
     protected void modify(CommandSender sender, double newPercentage) {
     protected void modify(CommandSender sender, double newPercentage) {
-        Config.getInstance().setHardcoreDeathStatPenaltyPercentage(newPercentage);
+        MainConfig.getInstance().setHardcoreDeathStatPenaltyPercentage(newPercentage);
         sender.sendMessage(LocaleLoader.getString("Hardcore.DeathStatLoss.PercentageChanged", percent.format(newPercentage / 100.0D)));
         sender.sendMessage(LocaleLoader.getString("Hardcore.DeathStatLoss.PercentageChanged", percent.format(newPercentage / 100.0D)));
     }
     }
 
 

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/hardcore/VampirismCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.hardcore;
 package com.gmail.nossr50.commands.hardcore;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -45,7 +45,7 @@ public class VampirismCommand extends HardcoreModeCommand {
 
 
     @Override
     @Override
     protected void modify(CommandSender sender, double newPercentage) {
     protected void modify(CommandSender sender, double newPercentage) {
-        Config.getInstance().setHardcoreVampirismStatLeechPercentage(newPercentage);
+        MainConfig.getInstance().setHardcoreVampirismStatLeechPercentage(newPercentage);
         sender.sendMessage(LocaleLoader.getString("Hardcore.Vampirism.PercentageChanged", percent.format(newPercentage / 100.0D)));
         sender.sendMessage(LocaleLoader.getString("Hardcore.Vampirism.PercentageChanged", percent.format(newPercentage / 100.0D)));
     }
     }
 
 

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/party/PartyInfoCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.party;
 package com.gmail.nossr50.commands.party;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.ShareMode;
 import com.gmail.nossr50.datatypes.party.ShareMode;
@@ -79,7 +79,7 @@ public class PartyInfoCommand implements CommandExecutor {
     }
     }
 
 
     private boolean isUnlockedFeature(Party party, PartyFeature partyFeature) {
     private boolean isUnlockedFeature(Party party, PartyFeature partyFeature) {
-        return party.getLevel() >= Config.getInstance().getPartyFeatureUnlockLevel(partyFeature);
+        return party.getLevel() >= MainConfig.getInstance().getPartyFeatureUnlockLevel(partyFeature);
     }
     }
 
 
     private void displayShareModeInfo(Player player, Party party) {
     private void displayShareModeInfo(Player player, Party party) {

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/party/PartyInviteCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.party;
 package com.gmail.nossr50.commands.party;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
@@ -48,7 +48,7 @@ public class PartyInviteCommand implements CommandExecutor {
 
 
                 if(PartyManager.isPartyFull(target, playerParty))
                 if(PartyManager.isPartyFull(target, playerParty))
                 {
                 {
-                    player.sendMessage(LocaleLoader.getString("Commands.Party.PartyFull.Invite", target.getName(), playerParty.toString(), Config.getInstance().getPartyMaxSize()));
+                    player.sendMessage(LocaleLoader.getString("Commands.Party.PartyFull.Invite", target.getName(), playerParty.toString(), MainConfig.getInstance().getPartyMaxSize()));
                     return true;
                     return true;
                 }
                 }
 
 

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/party/PartyItemShareCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.party;
 package com.gmail.nossr50.commands.party;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.party.ItemShareType;
 import com.gmail.nossr50.datatypes.party.ItemShareType;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
@@ -19,7 +19,7 @@ public class PartyItemShareCommand implements CommandExecutor {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         Party party = UserManager.getPlayer((Player) sender).getParty();
         Party party = UserManager.getPlayer((Player) sender).getParty();
 
 
-        if (party.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ITEM_SHARE)) {
+        if (party.getLevel() < MainConfig.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ITEM_SHARE)) {
             sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.4"));
             sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.4"));
             return true;
             return true;
         }
         }

+ 2 - 2
src/main/java/com/gmail/nossr50/commands/party/PartyXpShareCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.party;
 package com.gmail.nossr50.commands.party;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.ShareMode;
 import com.gmail.nossr50.datatypes.party.ShareMode;
@@ -18,7 +18,7 @@ public class PartyXpShareCommand implements CommandExecutor {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
     public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
         Party party = UserManager.getPlayer((Player) sender).getParty();
         Party party = UserManager.getPlayer((Player) sender).getParty();
 
 
-        if (party.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.XP_SHARE)) {
+        if (party.getLevel() < MainConfig.getInstance().getPartyFeatureUnlockLevel(PartyFeature.XP_SHARE)) {
             sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.5"));
             sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.5"));
             return true;
             return true;
         }
         }

+ 3 - 3
src/main/java/com/gmail/nossr50/commands/party/alliance/PartyAllianceCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.party.alliance;
 package com.gmail.nossr50.commands.party.alliance;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -44,7 +44,7 @@ public class PartyAllianceCommand implements TabExecutor {
 
 
         switch (args.length) {
         switch (args.length) {
             case 1:
             case 1:
-                if (playerParty.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ALLIANCE)) {
+                if (playerParty.getLevel() < MainConfig.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ALLIANCE)) {
                     sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.3"));
                     sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.3"));
                     return true;
                     return true;
                 }
                 }
@@ -62,7 +62,7 @@ public class PartyAllianceCommand implements TabExecutor {
 
 
             case 2:
             case 2:
             case 3:
             case 3:
-                if (playerParty.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ALLIANCE)) {
+                if (playerParty.getLevel() < MainConfig.getInstance().getPartyFeatureUnlockLevel(PartyFeature.ALLIANCE)) {
                     sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.3"));
                     sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.3"));
                     return true;
                     return true;
                 }
                 }

+ 3 - 3
src/main/java/com/gmail/nossr50/commands/party/teleport/PtpAcceptCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.party.teleport;
 package com.gmail.nossr50.commands.party.teleport;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.party.PartyTeleportRecord;
 import com.gmail.nossr50.datatypes.party.PartyTeleportRecord;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
@@ -28,7 +28,7 @@ public class PtpAcceptCommand implements CommandExecutor {
             return true;
             return true;
         }
         }
 
 
-        if (SkillUtils.cooldownExpired(ptpRecord.getTimeout(), Config.getInstance().getPTPCommandTimeout())) {
+        if (SkillUtils.cooldownExpired(ptpRecord.getTimeout(), MainConfig.getInstance().getPTPCommandTimeout())) {
             ptpRecord.removeRequest();
             ptpRecord.removeRequest();
             player.sendMessage(LocaleLoader.getString("Commands.ptp.RequestExpired"));
             player.sendMessage(LocaleLoader.getString("Commands.ptp.RequestExpired"));
             return true;
             return true;
@@ -41,7 +41,7 @@ public class PtpAcceptCommand implements CommandExecutor {
             return true;
             return true;
         }
         }
 
 
-        if (Config.getInstance().getPTPCommandWorldPermissions()) {
+        if (MainConfig.getInstance().getPTPCommandWorldPermissions()) {
             World targetWorld = target.getWorld();
             World targetWorld = target.getWorld();
             World playerWorld = player.getWorld();
             World playerWorld = player.getWorld();
 
 

+ 6 - 6
src/main/java/com/gmail/nossr50/commands/party/teleport/PtpCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.party.teleport;
 package com.gmail.nossr50.commands.party.teleport;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
 import com.gmail.nossr50.datatypes.party.PartyFeature;
@@ -68,7 +68,7 @@ public class PtpCommand implements TabExecutor {
 
 
         Party party = mcMMOPlayer.getParty();
         Party party = mcMMOPlayer.getParty();
 
 
-        if (party.getLevel() < Config.getInstance().getPartyFeatureUnlockLevel(PartyFeature.TELEPORT)) {
+        if (party.getLevel() < MainConfig.getInstance().getPartyFeatureUnlockLevel(PartyFeature.TELEPORT)) {
             sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.2"));
             sender.sendMessage(LocaleLoader.getString("Party.Feature.Disabled.2"));
             return true;
             return true;
         }
         }
@@ -84,7 +84,7 @@ public class PtpCommand implements TabExecutor {
                 }
                 }
 
 
                 long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
                 long recentlyHurt = mcMMOPlayer.getRecentlyHurt();
-                int hurtCooldown = Config.getInstance().getPTPCommandRecentlyHurtCooldown();
+                int hurtCooldown = MainConfig.getInstance().getPTPCommandRecentlyHurtCooldown();
 
 
                 if (hurtCooldown > 0) {
                 if (hurtCooldown > 0) {
                     int timeRemaining = SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, hurtCooldown, player);
                     int timeRemaining = SkillUtils.calculateTimeLeft(recentlyHurt * Misc.TIME_CONVERSION_FACTOR, hurtCooldown, player);
@@ -104,7 +104,7 @@ public class PtpCommand implements TabExecutor {
                     return true;
                     return true;
                 }
                 }
 
 
-                int ptpCooldown = Config.getInstance().getPTPCommandCooldown();
+                int ptpCooldown = MainConfig.getInstance().getPTPCommandCooldown();
                 long ptpLastUse = mcMMOPlayer.getPartyTeleportRecord().getLastUse();
                 long ptpLastUse = mcMMOPlayer.getPartyTeleportRecord().getLastUse();
 
 
                 if (ptpCooldown > 0) {
                 if (ptpCooldown > 0) {
@@ -169,7 +169,7 @@ public class PtpCommand implements TabExecutor {
         player.sendMessage(LocaleLoader.getString("Commands.Invite.Success"));
         player.sendMessage(LocaleLoader.getString("Commands.Invite.Success"));
 
 
         target.sendMessage(LocaleLoader.getString("Commands.ptp.Request1", player.getName()));
         target.sendMessage(LocaleLoader.getString("Commands.ptp.Request1", player.getName()));
-        target.sendMessage(LocaleLoader.getString("Commands.ptp.Request2", Config.getInstance().getPTPCommandTimeout()));
+        target.sendMessage(LocaleLoader.getString("Commands.ptp.Request2", MainConfig.getInstance().getPTPCommandTimeout()));
     }
     }
 
 
     protected static boolean canTeleport(CommandSender sender, Player player, String targetName) {
     protected static boolean canTeleport(CommandSender sender, Player player, String targetName) {
@@ -208,7 +208,7 @@ public class PtpCommand implements TabExecutor {
         McMMOPlayer mcMMOPlayer = UserManager.getPlayer(teleportingPlayer);
         McMMOPlayer mcMMOPlayer = UserManager.getPlayer(teleportingPlayer);
         McMMOPlayer mcMMOTarget = UserManager.getPlayer(targetPlayer);
         McMMOPlayer mcMMOTarget = UserManager.getPlayer(targetPlayer);
 
 
-        long warmup = Config.getInstance().getPTPCommandWarmup();
+        long warmup = MainConfig.getInstance().getPTPCommandWarmup();
 
 
         mcMMOPlayer.actualizeTeleportCommenceLocation(teleportingPlayer);
         mcMMOPlayer.actualizeTeleportCommenceLocation(teleportingPlayer);
 
 

+ 5 - 5
src/main/java/com/gmail/nossr50/commands/player/InspectCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.player;
 package com.gmail.nossr50.commands.player;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -40,10 +40,10 @@ public class InspectCommand implements TabExecutor {
                         return true;
                         return true;
                     }
                     }
 
 
-                    if (Config.getInstance().getScoreboardsEnabled() && sender instanceof Player && Config.getInstance().getInspectUseBoard()) {
+                    if (MainConfig.getInstance().getScoreboardsEnabled() && sender instanceof Player && MainConfig.getInstance().getInspectUseBoard()) {
                         ScoreboardManager.enablePlayerInspectScoreboard((Player) sender, profile);
                         ScoreboardManager.enablePlayerInspectScoreboard((Player) sender, profile);
 
 
-                        if (!Config.getInstance().getInspectUseChat()) {
+                        if (!MainConfig.getInstance().getInspectUseChat()) {
                             return true;
                             return true;
                         }
                         }
                     }
                     }
@@ -79,10 +79,10 @@ public class InspectCommand implements TabExecutor {
                         return true;
                         return true;
                     }
                     }
 
 
-                    if (Config.getInstance().getScoreboardsEnabled() && sender instanceof Player && Config.getInstance().getInspectUseBoard()) {
+                    if (MainConfig.getInstance().getScoreboardsEnabled() && sender instanceof Player && MainConfig.getInstance().getInspectUseBoard()) {
                         ScoreboardManager.enablePlayerInspectScoreboard((Player) sender, mcMMOPlayer.getProfile());
                         ScoreboardManager.enablePlayerInspectScoreboard((Player) sender, mcMMOPlayer.getProfile());
 
 
-                        if (!Config.getInstance().getInspectUseChat()) {
+                        if (!MainConfig.getInstance().getInspectUseChat()) {
                             return true;
                             return true;
                         }
                         }
                     }
                     }

+ 3 - 3
src/main/java/com/gmail/nossr50/commands/player/MccooldownCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.player;
 package com.gmail.nossr50.commands.player;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
 import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
@@ -30,10 +30,10 @@ public class MccooldownCommand implements TabExecutor {
             case 0:
             case 0:
                 Player player = (Player) sender;
                 Player player = (Player) sender;
 
 
-                if (Config.getInstance().getScoreboardsEnabled() && Config.getInstance().getCooldownUseBoard()) {
+                if (MainConfig.getInstance().getScoreboardsEnabled() && MainConfig.getInstance().getCooldownUseBoard()) {
                     ScoreboardManager.enablePlayerCooldownScoreboard(player);
                     ScoreboardManager.enablePlayerCooldownScoreboard(player);
 
 
-                    if (!Config.getInstance().getCooldownUseChat()) {
+                    if (!MainConfig.getInstance().getCooldownUseChat()) {
                         return true;
                         return true;
                     }
                     }
                 }
                 }

+ 4 - 4
src/main/java/com/gmail/nossr50/commands/player/McrankCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.player;
 package com.gmail.nossr50.commands.player;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -88,7 +88,7 @@ public class McrankCommand implements TabExecutor {
     private void display(CommandSender sender, String playerName) {
     private void display(CommandSender sender, String playerName) {
         if (sender instanceof Player) {
         if (sender instanceof Player) {
             McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
             McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
-            long cooldownMillis = Math.max(Config.getInstance().getDatabasePlayerCooldown(), 1750);
+            long cooldownMillis = Math.max(MainConfig.getInstance().getDatabasePlayerCooldown(), 1750);
 
 
             if (mcMMOPlayer.getDatabaseATS() + cooldownMillis > System.currentTimeMillis()) {
             if (mcMMOPlayer.getDatabaseATS() + cooldownMillis > System.currentTimeMillis()) {
                 sender.sendMessage(LocaleLoader.getString("Commands.Database.Cooldown"));
                 sender.sendMessage(LocaleLoader.getString("Commands.Database.Cooldown"));
@@ -105,8 +105,8 @@ public class McrankCommand implements TabExecutor {
             mcMMOPlayer.actualizeDatabaseATS();
             mcMMOPlayer.actualizeDatabaseATS();
         }
         }
 
 
-        boolean useBoard = Config.getInstance().getScoreboardsEnabled() && (sender instanceof Player) && (Config.getInstance().getRankUseBoard());
-        boolean useChat = !useBoard || Config.getInstance().getRankUseChat();
+        boolean useBoard = MainConfig.getInstance().getScoreboardsEnabled() && (sender instanceof Player) && (MainConfig.getInstance().getRankUseBoard());
+        boolean useChat = !useBoard || MainConfig.getInstance().getRankUseChat();
 
 
         new McrankCommandAsyncTask(playerName, sender, useBoard, useChat).runTaskAsynchronously(mcMMO.p);
         new McrankCommandAsyncTask(playerName, sender, useBoard, useChat).runTaskAsynchronously(mcMMO.p);
     }
     }

+ 4 - 4
src/main/java/com/gmail/nossr50/commands/player/McstatsCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.player;
 package com.gmail.nossr50.commands.player;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.commands.CommandUtils;
 import com.gmail.nossr50.util.player.UserManager;
 import com.gmail.nossr50.util.player.UserManager;
@@ -28,10 +28,10 @@ public class McstatsCommand implements TabExecutor {
             case 0:
             case 0:
                 Player player = (Player) sender;
                 Player player = (Player) sender;
 
 
-                if (Config.getInstance().getStatsUseBoard() && Config.getInstance().getScoreboardsEnabled()) {
+                if (MainConfig.getInstance().getStatsUseBoard() && MainConfig.getInstance().getScoreboardsEnabled()) {
                     ScoreboardManager.enablePlayerStatsScoreboard(player);
                     ScoreboardManager.enablePlayerStatsScoreboard(player);
 
 
-                    if (!Config.getInstance().getStatsUseChat()) {
+                    if (!MainConfig.getInstance().getStatsUseChat()) {
                         return true;
                         return true;
                     }
                     }
                 }
                 }
@@ -43,7 +43,7 @@ public class McstatsCommand implements TabExecutor {
                 CommandUtils.printCombatSkills(player);
                 CommandUtils.printCombatSkills(player);
                 CommandUtils.printMiscSkills(player);
                 CommandUtils.printMiscSkills(player);
 
 
-                int powerLevelCap = Config.getInstance().getPowerLevelCap();
+                int powerLevelCap = MainConfig.getInstance().getPowerLevelCap();
 
 
                 if (powerLevelCap != Integer.MAX_VALUE) {
                 if (powerLevelCap != Integer.MAX_VALUE) {
                     player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", UserManager.getPlayer(player).getPowerLevel(), powerLevelCap));
                     player.sendMessage(LocaleLoader.getString("Commands.PowerLevel.Capped", UserManager.getPlayer(player).getPowerLevel(), powerLevelCap));

+ 4 - 4
src/main/java/com/gmail/nossr50/commands/player/MctopCommand.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.commands.player;
 package com.gmail.nossr50.commands.player;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
@@ -87,7 +87,7 @@ public class MctopCommand implements TabExecutor {
             }
             }
 
 
             McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
             McMMOPlayer mcMMOPlayer = UserManager.getPlayer(sender.getName());
-            long cooldownMillis = Math.max(Config.getInstance().getDatabasePlayerCooldown(), 1750);
+            long cooldownMillis = Math.max(MainConfig.getInstance().getDatabasePlayerCooldown(), 1750);
 
 
             if (mcMMOPlayer.getDatabaseATS() + cooldownMillis > System.currentTimeMillis()) {
             if (mcMMOPlayer.getDatabaseATS() + cooldownMillis > System.currentTimeMillis()) {
                 double seconds = ((mcMMOPlayer.getDatabaseATS() + cooldownMillis) - System.currentTimeMillis()) / 1000;
                 double seconds = ((mcMMOPlayer.getDatabaseATS() + cooldownMillis) - System.currentTimeMillis()) / 1000;
@@ -113,8 +113,8 @@ public class MctopCommand implements TabExecutor {
     }
     }
 
 
     private void display(int page, PrimarySkillType skill, CommandSender sender) {
     private void display(int page, PrimarySkillType skill, CommandSender sender) {
-        boolean useBoard = (sender instanceof Player) && (Config.getInstance().getTopUseBoard());
-        boolean useChat = !useBoard || Config.getInstance().getTopUseChat();
+        boolean useBoard = (sender instanceof Player) && (MainConfig.getInstance().getTopUseBoard());
+        boolean useChat = !useBoard || MainConfig.getInstance().getTopUseChat();
 
 
         new MctopCommandAsyncTask(page, skill, sender, useBoard, useChat).runTaskAsynchronously(mcMMO.p);
         new MctopCommandAsyncTask(page, skill, sender, useBoard, useChat).runTaskAsynchronously(mcMMO.p);
     }
     }

+ 7 - 9
src/main/java/com/gmail/nossr50/commands/skills/FishingCommand.java

@@ -1,7 +1,5 @@
 package com.gmail.nossr50.commands.skills;
 package com.gmail.nossr50.commands.skills;
 
 
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.treasure.TreasureConfig;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.treasure.Rarity;
 import com.gmail.nossr50.datatypes.treasure.Rarity;
@@ -58,19 +56,19 @@ public class FishingCommand extends SkillCommand {
             lootTier = fishingManager.getLootTier();
             lootTier = fishingManager.getLootTier();
 
 
             // Item drop rates
             // Item drop rates
-            commonTreasure = percent.format(TreasureConfig.getInstance().getItemDropRate(lootTier, Rarity.COMMON) / 100.0);
-            uncommonTreasure = percent.format(TreasureConfig.getInstance().getItemDropRate(lootTier, Rarity.UNCOMMON) / 100.0);
-            rareTreasure = percent.format(TreasureConfig.getInstance().getItemDropRate(lootTier, Rarity.RARE) / 100.0);
-            epicTreasure = percent.format(TreasureConfig.getInstance().getItemDropRate(lootTier, Rarity.EPIC) / 100.0);
-            legendaryTreasure = percent.format(TreasureConfig.getInstance().getItemDropRate(lootTier, Rarity.LEGENDARY) / 100.0);
-            recordTreasure = percent.format(TreasureConfig.getInstance().getItemDropRate(lootTier, Rarity.RECORD) / 100.0);
+            commonTreasure = percent.format(TreasureMainConfig.getInstance().getItemDropRate(lootTier, Rarity.COMMON) / 100.0);
+            uncommonTreasure = percent.format(TreasureMainConfig.getInstance().getItemDropRate(lootTier, Rarity.UNCOMMON) / 100.0);
+            rareTreasure = percent.format(TreasureMainConfig.getInstance().getItemDropRate(lootTier, Rarity.RARE) / 100.0);
+            epicTreasure = percent.format(TreasureMainConfig.getInstance().getItemDropRate(lootTier, Rarity.EPIC) / 100.0);
+            legendaryTreasure = percent.format(TreasureMainConfig.getInstance().getItemDropRate(lootTier, Rarity.LEGENDARY) / 100.0);
+            recordTreasure = percent.format(TreasureMainConfig.getInstance().getItemDropRate(lootTier, Rarity.RECORD) / 100.0);
 
 
             // Magic hunter drop rates
             // Magic hunter drop rates
             double totalEnchantChance = 0;
             double totalEnchantChance = 0;
 
 
             for (Rarity rarity : Rarity.values()) {
             for (Rarity rarity : Rarity.values()) {
                 if (rarity != Rarity.RECORD) {
                 if (rarity != Rarity.RECORD) {
-                    totalEnchantChance += TreasureConfig.getInstance().getEnchantmentDropRate(lootTier, rarity);
+                    totalEnchantChance += TreasureMainConfig.getInstance().getEnchantmentDropRate(lootTier, rarity);
                 }
                 }
             }
             }
 
 

+ 3 - 4
src/main/java/com/gmail/nossr50/commands/skills/SkillCommand.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.commands.skills;
 package com.gmail.nossr50.commands.skills;
 
 
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
@@ -99,14 +98,14 @@ public abstract class SkillCommand implements TabExecutor {
 
 
 
 
                 //Link Header
                 //Link Header
-                if(Config.getInstance().getUrlLinksEnabled())
+                if(MainConfig.getInstance().getUrlLinksEnabled())
                 {
                 {
                     player.sendMessage(LocaleLoader.getString("Overhaul.mcMMO.Header"));
                     player.sendMessage(LocaleLoader.getString("Overhaul.mcMMO.Header"));
                     TextComponentFactory.sendPlayerUrlHeader(player);
                     TextComponentFactory.sendPlayerUrlHeader(player);
                 }
                 }
 
 
 
 
-                if (Config.getInstance().getScoreboardsEnabled() && Config.getInstance().getSkillUseBoard()) {
+                if (MainConfig.getInstance().getScoreboardsEnabled() && MainConfig.getInstance().getSkillUseBoard()) {
                     ScoreboardManager.enablePlayerSkillScoreboard(player, skill);
                     ScoreboardManager.enablePlayerSkillScoreboard(player, skill);
                 }
                 }
 
 

+ 0 - 1
src/main/java/com/gmail/nossr50/commands/skills/SwordsCommand.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.commands.skills;
 package com.gmail.nossr50.commands.skills;
 
 
-import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;

+ 295 - 183
src/main/java/com/gmail/nossr50/config/AdvancedConfig.java

@@ -4,19 +4,129 @@ import com.gmail.nossr50.datatypes.interactions.NotificationType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
 import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
-import net.md_5.bungee.api.ChatColor;
-import ninja.leaping.configurate.objectmapping.Setting;
-import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
+import org.bukkit.ChatColor;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 
 
-@ConfigSerializable
-public class AdvancedConfig extends ConfigLoaderConfigurable {
+public class AdvancedConfig extends ConfigValidated {
+
+    public static final String SKILLS = "Skills";
+    public static final String GENERAL = "General";
+    public static final String ABILITY = "Ability";
+    public static final String LENGTH = "Length";
+    public static final String INCREASE_LEVEL = "IncreaseLevel";
+    public static final String ENCHANT_BUFF = "EnchantBuff";
+    public static final String ACROBATICS = "Acrobatics";
+    public static final String DODGE = "Dodge";
+    public static final String CHANCE = "Chance";
+    public static final String CHANCE_MAX = CHANCE + "Max";
+    public static final String BONUS = "Bonus";
+    public static final String MAX_BONUS_LEVEL = "Max" + BONUS + "Level";
+    public static final String MODIFIER = "Modifier";
+    public static final String DAMAGE_MODIFIER = "Damage" + MODIFIER;
+    public static final String DAMAGE_THRESHOLD = "DamageThreshold";
+    public static final String ALCHEMY = "Alchemy";
+    public static final String CATALYSIS = "Catalysis";
+    public static final String MIN_SPEED = "MinSpeed";
+    public static final String MAX_SPEED = "MaxSpeed";
+    public static final String ARCHERY = "Archery";
+    public static final String SKILL_SHOT = "SkillShot";
+    public static final String MULTIPLIER = "Multiplier";
+    public static final String RANK_DAMAGE_MULTIPLIER = "RankDamage" + MULTIPLIER;
+    public static final String BONUS_DAMAGE = BONUS + "Damage";
+    public static final String FORCE_MULTIPLIER = "Force" + MULTIPLIER;
+    public static final String AXES = "Axes";
+    public static final String STANDARD = "Standard";
+    public static final String RETRO_MODE = "RetroMode";
+    public static final String CAP_LEVEL = "CapLevel";
+    public static final String KNOCKBACK_MODIFIER = "Knockback" + MODIFIER;
+    public static final String PVP_MODIFIER = "PVP_" + MODIFIER;
+    public static final String PVE_MODIFIER = "PVE_" + MODIFIER;
+    public static final String FISHING = "Fishing";
+    public static final String MASTER_ANGLER = "MasterAngler";
+    public static final String BOAT_MODIFIER = "Boat" + MODIFIER;
+    public static final String BIOME_MODIFIER = "Biome" + MODIFIER;
+    public static final String XP = "XP";
+    public static final String VANILLA_XPMULTIPLIER = "Vanilla" + XP + MULTIPLIER;
+    public static final String RANK = "Rank_";
+    public static final String TAMING = "Taming";
+    public static final String CALL_OF_THE_WILD = "CallOfTheWild";
+    public static final String MIN_HORSE_JUMP_STRENGTH = "MinHorseJumpStrength";
+    public static final String MAX_HORSE_JUMP_STRENGTH = "MaxHorseJumpStrength";
+    public static final String SHOCK_PROOF = "ShockProof";
+    public static final String UNARMED = "Unarmed";
+    public static final String STARTING_LEVEL = "StartingLevel";
+    public static final String AXE_MASTERY = "AxeMastery";
+    public static final String CRITICAL_STRIKES = "CriticalStrikes";
+    public static final String GREATER_IMPACT = "GreaterImpact";
+    public static final String ARMOR_IMPACT = "ArmorImpact";
+    public static final String SKULL_SPLITTER = "SkullSplitter.";
+    public static final String MAX_PERCENTAGE_DURABILITY_DAMAGE = "MaxPercentageDurabilityDamage";
+    public static final String SHAKE = "Shake";
+    public static final String MINING = "Mining";
+    public static final String BLAST_MINING = "BlastMining";
+    public static final String LEVELS = "Levels";
+    public static final String BLAST_DAMAGE_DECREASE = "BlastDamageDecrease";
+    public static final String ORE_BONUS = "Ore" + BONUS;
+    public static final String DEBRIS_REDUCTION = "DebrisReduction";
+    public static final String DROP_MULTIPLIER = "Drop" + MULTIPLIER;
+    public static final String BLAST_RADIUS = "BlastRadius";
+    public static final String REPAIR = "Repair";
+    public static final String REPAIR_MASTERY = "RepairMastery";
+    public static final String MAX_BONUS_PERCENTAGE = "Max" + BONUS + "Percentage";
+    public static final String ARCANE_FORGING = "ArcaneForging";
+    public static final String MAY_LOSE_ENCHANTS = "May_Lose_Enchants";
+    public static final String KEEP_ENCHANTS = "Keep_Enchants_";
+    public static final String DOWNGRADES = "Downgrades_";
+    public static final String ENABLED = "Enabled";
+    public static final String DOWNGRADES_ENABLED = DOWNGRADES + ENABLED;
+    public static final String SALVAGE = "Salvage";
+    public static final String ARCANE_SALVAGE = "ArcaneSalvage";
+    public static final String ENCHANT_DOWNGRADE_ENABLED = "EnchantDowngrade" + ENABLED;
+    public static final String ENCHANT_LOSS_ENABLED = "EnchantLoss" + ENABLED;
+    public static final String EXTRACT_FULL_ENCHANT = "ExtractFullEnchant";
+    public static final String EXTRACT_PARTIAL_ENCHANT = "ExtractPartialEnchant";
+    public static final String SMELTING = "Smelting";
+    public static final String FUEL_EFFICIENCY = "FuelEfficiency";
+    public static final String FLUX = "Flux";
+    public static final String SWORDS = "Swords";
+    public static final String RUPTURE = "Rupture";
+    public static final String DAMAGE_PLAYER = "DamagePlayer";
+    public static final String DAMAGE_MOBS = "DamageMobs";
+    public static final String MAX_TICKS = "MaxTicks";
+    public static final String BASE_TICKS = "BaseTicks";
+    public static final String COUNTER_ATTACK = "CounterAttack";
+    public static final String SERRATED_STRIKES = "SerratedStrikes";
+    public static final String TICKS = "Ticks";
+    public static final String GORE = "Gore";
+    public static final String FAST_FOOD = "FastFood";
+    public static final String FAST_FOOD_SERVICE = FAST_FOOD + "Service";
+    public static final String PUMMEL = "Pummel";
+    public static final String THICK_FUR = "ThickFur";
+    public static final String SHARPENED_CLAWS = "SharpenedClaws";
+    public static final String DISARM = "Disarm";
+    public static final String ANTI_THEFT = "AntiTheft";
+    public static final String DAZE = "Daze";
+    public static final String MAX_DAMAGE = "MaxDamage";
+    public static final String ROLL = "Roll";
+    public static final String GRACEFUL_ROLL = "Graceful" + ROLL;
+    public static final String ARROW_DEFLECT = "ArrowDeflect";
+    public static final String IRON_GRIP = "IronGrip";
+    public static final String WOODCUTTING = "Woodcutting";
+    public static final String HARVEST_LUMBER = "HarvestLumber";
+    public static final String FEEDBACK = "Feedback";
+    public static final String SKILL_COMMAND = "SkillCommand";
+    public static final String BLANK_LINES_ABOVE_HEADER = "BlankLinesAboveHeader";
+    public static final String ACTION_BAR_NOTIFICATIONS = "ActionBarNotifications";
+    public static final String SEND_COPY_OF_MESSAGE_TO_CHAT = "SendCopyOfMessageToChat";
+    public static final String EVENTS = "Events";
+    public static final String SEND_TITLES = "SendTitles";
     private static AdvancedConfig instance;
     private static AdvancedConfig instance;
 
 
     private AdvancedConfig() {
     private AdvancedConfig() {
-        super(mcMMO.p.getDataFolder().getAbsoluteFile(), "advanced.yml");
+        //super(McmmoCore.getDataFolderPath().getAbsoluteFile(), "advanced.yml", true);
+        super(mcMMO.p.getDataFolder().getAbsoluteFile(), "advanced.yml", true);
     }
     }
 
 
     public static AdvancedConfig getInstance() {
     public static AdvancedConfig getInstance() {
@@ -27,8 +137,15 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
         return instance;
         return instance;
     }
     }
 
 
-    @Setting(value = "Skills.General.StartingLevel", comment = "The starting level for players on your server.\nHistorically this has been 0.\nRecently is has changed to 1.")
-    private int startingLevel = 1;
+    /**
+     * The version of this config
+     *
+     * @return
+     */
+    @Override
+    public double getConfigVersion() {
+        return 1;
+    }
 
 
     @Override
     @Override
     public List<String> validateKeys() {
     public List<String> validateKeys() {
@@ -37,324 +154,324 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
 
 
         /* GENERAL */
         /* GENERAL */
         if (getAbilityLength() < 1) {
         if (getAbilityLength() < 1) {
-            reason.add("Skills.General.Ability.Length.<mode>.IncreaseLevel should be at least 1!");
+            reason.add(SKILLS + "." + GENERAL + "." + ABILITY + "." + LENGTH + ".<mode>." + INCREASE_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getEnchantBuff() < 1) {
         if (getEnchantBuff() < 1) {
-            reason.add("Skills.General.Ability.EnchantBuff should be at least 1!");
+            reason.add(SKILLS + "." + GENERAL + "." + ABILITY + "." + ENCHANT_BUFF + " should be at least 1!");
         }
         }
 
 
         /* ACROBATICS */
         /* ACROBATICS */
         if (getMaximumProbability(SubSkillType.ACROBATICS_DODGE) < 1) {
         if (getMaximumProbability(SubSkillType.ACROBATICS_DODGE) < 1) {
-            reason.add("Skills.Acrobatics.Dodge.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + ACROBATICS + "." + DODGE + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.ACROBATICS_DODGE) < 1) {
         if (getMaxBonusLevel(SubSkillType.ACROBATICS_DODGE) < 1) {
-            reason.add("Skills.Acrobatics.Dodge.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + ACROBATICS + "." + DODGE + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getDodgeDamageModifier() <= 1) {
         if (getDodgeDamageModifier() <= 1) {
-            reason.add("Skills.Acrobatics.Dodge.DamageModifier should be greater than 1!");
+            reason.add(SKILLS + "." + ACROBATICS + "." + DODGE + "." + DAMAGE_MODIFIER + " should be greater than 1!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.ACROBATICS_ROLL) < 1) {
         if (getMaximumProbability(SubSkillType.ACROBATICS_ROLL) < 1) {
-            reason.add("Skills.Acrobatics.Roll.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + ACROBATICS + "." + ROLL + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.ACROBATICS_ROLL) < 1) {
         if (getMaxBonusLevel(SubSkillType.ACROBATICS_ROLL) < 1) {
-            reason.add("Skills.Acrobatics.Roll.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + ACROBATICS + "." + ROLL + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getRollDamageThreshold() < 0) {
         if (getRollDamageThreshold() < 0) {
-            reason.add("Skills.Acrobatics.Roll.DamageThreshold should be at least 0!");
+            reason.add(SKILLS + "." + ACROBATICS + "." + ROLL + "." + DAMAGE_THRESHOLD + " should be at least 0!");
         }
         }
 
 
         if (getGracefulRollDamageThreshold() < 0) {
         if (getGracefulRollDamageThreshold() < 0) {
-            reason.add("Skills.Acrobatics.GracefulRoll.DamageThreshold should be at least 0!");
+            reason.add(SKILLS + "." + ACROBATICS + "." + GRACEFUL_ROLL + "." + DAMAGE_THRESHOLD + " should be at least 0!");
         }
         }
 
 
         if (getCatalysisMinSpeed() <= 0) {
         if (getCatalysisMinSpeed() <= 0) {
-            reason.add("Skills.Alchemy.Catalysis.MinSpeed must be greater than 0!");
+            reason.add(SKILLS + "." + ALCHEMY + "." + CATALYSIS + "." + MIN_SPEED + " must be greater than 0!");
         }
         }
 
 
         if (getCatalysisMaxSpeed() < getCatalysisMinSpeed()) {
         if (getCatalysisMaxSpeed() < getCatalysisMinSpeed()) {
-            reason.add("Skills.Alchemy.Catalysis.MaxSpeed should be at least Skills.Alchemy.Catalysis.MinSpeed!");
+            reason.add(SKILLS + "." + ALCHEMY + "." + CATALYSIS + "." + MAX_SPEED + " should be at least Skills.Alchemy.Catalysis." + MIN_SPEED + "!");
         }
         }
 
 
         /* ARCHERY */
         /* ARCHERY */
 
 
         if (getSkillShotRankDamageMultiplier() <= 0) {
         if (getSkillShotRankDamageMultiplier() <= 0) {
-            reason.add("Skills.Archery.SkillShot.RankDamageMultiplier should be greater than 0!");
+            reason.add(SKILLS + "." + ARCHERY + "." + SKILL_SHOT + "." + RANK_DAMAGE_MULTIPLIER + " should be greater than 0!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.ARCHERY_DAZE) < 1) {
         if (getMaximumProbability(SubSkillType.ARCHERY_DAZE) < 1) {
-            reason.add("Skills.Archery.Daze.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + ARCHERY + "." + DAZE + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.ARCHERY_DAZE) < 1) {
         if (getMaxBonusLevel(SubSkillType.ARCHERY_DAZE) < 1) {
-            reason.add("Skills.Archery.Daze.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + ARCHERY + "." + DAZE + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getDazeBonusDamage() < 0) {
         if (getDazeBonusDamage() < 0) {
-            reason.add("Skills.Archery.Daze.BonusDamage should be at least 0!");
+            reason.add(SKILLS + "." + ARCHERY + "." + DAZE + "." + BONUS_DAMAGE + " should be at least 0!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.ARCHERY_ARROW_RETRIEVAL) < 1) {
         if (getMaximumProbability(SubSkillType.ARCHERY_ARROW_RETRIEVAL) < 1) {
-            reason.add("Skills.Archery.Retrieve.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + ARCHERY + ".Retrieve." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.ARCHERY_ARROW_RETRIEVAL) < 1) {
         if (getMaxBonusLevel(SubSkillType.ARCHERY_ARROW_RETRIEVAL) < 1) {
-            reason.add("Skills.Archery.Retrieve.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + ARCHERY + ".Retrieve." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getForceMultiplier() < 0) {
         if (getForceMultiplier() < 0) {
-            reason.add("Skills.Archery.ForceMultiplier should be at least 0!");
+            reason.add(SKILLS + "." + ARCHERY + "." + FORCE_MULTIPLIER + " should be at least 0!");
         }
         }
 
 
         /* AXES */
         /* AXES */
         if(getAxeMasteryRankDamageMultiplier() < 0)
         if(getAxeMasteryRankDamageMultiplier() < 0)
         {
         {
-            reason.add("Skills.Axes.AxeMastery.RankDamageMultiplier should be at least 0!");
+            reason.add(SKILLS + "." + AXES + "." + AXE_MASTERY + "." + RANK_DAMAGE_MULTIPLIER + " should be at least 0!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.AXES_CRITICAL_STRIKES) < 1) {
         if (getMaximumProbability(SubSkillType.AXES_CRITICAL_STRIKES) < 1) {
-            reason.add("Skills.Axes.CriticalHit.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + AXES + ".CriticalHit." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.AXES_CRITICAL_STRIKES) < 1) {
         if (getMaxBonusLevel(SubSkillType.AXES_CRITICAL_STRIKES) < 1) {
-            reason.add("Skills.Axes.CriticalHit.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + AXES + ".CriticalHit." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getCriticalStrikesPVPModifier() < 1) {
         if (getCriticalStrikesPVPModifier() < 1) {
-            reason.add("Skills.Axes.CriticalStrikes.PVP_Modifier should be at least 1!");
+            reason.add(SKILLS + "." + AXES + "." + CRITICAL_STRIKES + "." + PVP_MODIFIER + " should be at least 1!");
         }
         }
 
 
         if (getCriticalStrikesPVPModifier() < 1) {
         if (getCriticalStrikesPVPModifier() < 1) {
-            reason.add("Skills.Axes.CriticalStrikes.PVE_Modifier should be at least 1!");
+            reason.add(SKILLS + "." + AXES + "." + CRITICAL_STRIKES + "." + PVE_MODIFIER + " should be at least 1!");
         }
         }
 
 
         if (getGreaterImpactChance() < 1) {
         if (getGreaterImpactChance() < 1) {
-            reason.add("Skills.Axes.GreaterImpact.Chance should be at least 1!");
+            reason.add(SKILLS + "." + AXES + "." + GREATER_IMPACT + "." + CHANCE + " should be at least 1!");
         }
         }
 
 
         if (getGreaterImpactModifier() < 1) {
         if (getGreaterImpactModifier() < 1) {
-            reason.add("Skills.Axes.GreaterImpact.KnockbackModifier should be at least 1!");
+            reason.add(SKILLS + "." + AXES + "." + GREATER_IMPACT + "." + KNOCKBACK_MODIFIER + " should be at least 1!");
         }
         }
 
 
         if (getGreaterImpactBonusDamage() < 1) {
         if (getGreaterImpactBonusDamage() < 1) {
-            reason.add("Skills.Axes.GreaterImpact.BonusDamage should be at least 1!");
+            reason.add(SKILLS + "." + AXES + "." + GREATER_IMPACT + "." + BONUS_DAMAGE + " should be at least 1!");
         }
         }
 
 
         if (getArmorImpactIncreaseLevel() < 1) {
         if (getArmorImpactIncreaseLevel() < 1) {
-            reason.add("Skills.Axes.ArmorImpact.IncreaseLevel should be at least 1!");
+            reason.add(SKILLS + "." + AXES + "." + ARMOR_IMPACT + "." + INCREASE_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getImpactChance() < 1) {
         if (getImpactChance() < 1) {
-            reason.add("Skills.Axes.ArmorImpact.Chance should be at least 1!");
+            reason.add(SKILLS + "." + AXES + "." + ARMOR_IMPACT + "." + CHANCE + " should be at least 1!");
         }
         }
 
 
         if (getArmorImpactMaxDurabilityDamage() < 1) {
         if (getArmorImpactMaxDurabilityDamage() < 1) {
-            reason.add("Skills.Axes.ArmorImpact.MaxPercentageDurabilityDamage should be at least 1!");
+            reason.add(SKILLS + "." + AXES + "." + ARMOR_IMPACT + "." + MAX_PERCENTAGE_DURABILITY_DAMAGE + " should be at least 1!");
         }
         }
 
 
         if (getSkullSplitterModifier() < 1) {
         if (getSkullSplitterModifier() < 1) {
-            reason.add("Skills.Axes.SkullSplitter.DamageModifier should be at least 1!");
+            reason.add(SKILLS + "." + AXES + "." + SKULL_SPLITTER + DAMAGE_MODIFIER + " should be at least 1!");
         }
         }
 
 
-        if (getFishermanDietRankChange() < 1) {
-            reason.add("Skills.Fishing.FishermansDiet.RankChange should be at least 1!");
-        }
+        /*if (getFishermanDietRankChange() < 1) {
+            reason.add(SKILLS + "." + FISHING + ".FishermansDiet.RankChange should be at least 1!");
+        }*/
 
 
         if (getMasterAnglerBoatModifier() < 1) {
         if (getMasterAnglerBoatModifier() < 1) {
-            reason.add("Skills.Fishing.MasterAngler.BoatModifier should be at least 1!");
+            reason.add(SKILLS + "." + FISHING + "." + MASTER_ANGLER + "." + BOAT_MODIFIER + " should be at least 1!");
         }
         }
 
 
         if (getMasterAnglerBiomeModifier() < 1) {
         if (getMasterAnglerBiomeModifier() < 1) {
-            reason.add("Skills.Fishing.MasterAngler.BiomeModifier should be at least 1!");
+            reason.add(SKILLS + "." + FISHING + "." + MASTER_ANGLER + "." + BIOME_MODIFIER + " should be at least 1!");
         }
         }
 
 
         /* HERBALISM */
         /* HERBALISM */
-        if (getFarmerDietRankChange() < 1) {
-            reason.add("Skills.Herbalism.FarmersDiet.RankChange should be at least 1!");
+        /*if (getFarmerDietRankChange() < 1) {
+            reason.add(SKILLS + ".Herbalism.FarmersDiet.RankChange should be at least 1!");
         }
         }
 
 
         if (getGreenThumbStageChange() < 1) {
         if (getGreenThumbStageChange() < 1) {
-            reason.add("Skills.Herbalism.GreenThumb.StageChange should be at least 1!");
-        }
+            reason.add(SKILLS + ".Herbalism.GreenThumb.StageChange should be at least 1!");
+        }*/
 
 
         if (getMaximumProbability(SubSkillType.HERBALISM_GREEN_THUMB) < 1) {
         if (getMaximumProbability(SubSkillType.HERBALISM_GREEN_THUMB) < 1) {
-            reason.add("Skills.Herbalism.GreenThumb.ChanceMax should be at least 1!");
+            reason.add(SKILLS + ".Herbalism.GreenThumb." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.HERBALISM_GREEN_THUMB) < 1) {
         if (getMaxBonusLevel(SubSkillType.HERBALISM_GREEN_THUMB) < 1) {
-            reason.add("Skills.Herbalism.GreenThumb.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + ".Herbalism.GreenThumb." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.HERBALISM_DOUBLE_DROPS) < 1) {
         if (getMaximumProbability(SubSkillType.HERBALISM_DOUBLE_DROPS) < 1) {
-            reason.add("Skills.Herbalism.DoubleDrops.ChanceMax should be at least 1!");
+            reason.add(SKILLS + ".Herbalism.DoubleDrops." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.HERBALISM_DOUBLE_DROPS) < 1) {
         if (getMaxBonusLevel(SubSkillType.HERBALISM_DOUBLE_DROPS) < 1) {
-            reason.add("Skills.Herbalism.DoubleDrops.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + ".Herbalism.DoubleDrops." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.HERBALISM_HYLIAN_LUCK) < 1) {
         if (getMaximumProbability(SubSkillType.HERBALISM_HYLIAN_LUCK) < 1) {
-            reason.add("Skills.Herbalism.HylianLuck.ChanceMax should be at least 1!");
+            reason.add(SKILLS + ".Herbalism.HylianLuck." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.HERBALISM_HYLIAN_LUCK) < 1) {
         if (getMaxBonusLevel(SubSkillType.HERBALISM_HYLIAN_LUCK) < 1) {
-            reason.add("Skills.Herbalism.HylianLuck.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + ".Herbalism.HylianLuck." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.HERBALISM_SHROOM_THUMB) < 1) {
         if (getMaximumProbability(SubSkillType.HERBALISM_SHROOM_THUMB) < 1) {
-            reason.add("Skills.Herbalism.ShroomThumb.ChanceMax should be at least 1!");
+            reason.add(SKILLS + ".Herbalism.ShroomThumb." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.HERBALISM_SHROOM_THUMB) < 1) {
         if (getMaxBonusLevel(SubSkillType.HERBALISM_SHROOM_THUMB) < 1) {
-            reason.add("Skills.Herbalism.ShroomThumb.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + ".Herbalism.ShroomThumb." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         /* MINING */
         /* MINING */
         if (getMaximumProbability(SubSkillType.MINING_DOUBLE_DROPS) < 1) {
         if (getMaximumProbability(SubSkillType.MINING_DOUBLE_DROPS) < 1) {
-            reason.add("Skills.Mining.DoubleDrops.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + MINING + ".DoubleDrops." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.MINING_DOUBLE_DROPS) < 1) {
         if (getMaxBonusLevel(SubSkillType.MINING_DOUBLE_DROPS) < 1) {
-            reason.add("Skills.Mining.DoubleDrops.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + MINING + ".DoubleDrops." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         /* REPAIR */
         /* REPAIR */
         if (getRepairMasteryMaxBonus() < 1) {
         if (getRepairMasteryMaxBonus() < 1) {
-            reason.add("Skills.Repair.RepairMastery.MaxBonusPercentage should be at least 1!");
+            reason.add(SKILLS + "." + REPAIR + "." + REPAIR_MASTERY + "." + MAX_BONUS_PERCENTAGE + " should be at least 1!");
         }
         }
 
 
         if (getRepairMasteryMaxLevel() < 1) {
         if (getRepairMasteryMaxLevel() < 1) {
-            reason.add("Skills.Repair.RepairMastery.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + REPAIR + "." + REPAIR_MASTERY + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.REPAIR_SUPER_REPAIR) < 1) {
         if (getMaximumProbability(SubSkillType.REPAIR_SUPER_REPAIR) < 1) {
-            reason.add("Skills.Repair.SuperRepair.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + REPAIR + ".SuperRepair." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.REPAIR_SUPER_REPAIR) < 1) {
         if (getMaxBonusLevel(SubSkillType.REPAIR_SUPER_REPAIR) < 1) {
-            reason.add("Skills.Repair.SuperRepair.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + REPAIR + ".SuperRepair." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         /* SMELTING */
         /* SMELTING */
         if (getBurnModifierMaxLevel() < 1) {
         if (getBurnModifierMaxLevel() < 1) {
-            reason.add("Skills.Smelting.FuelEfficiency.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + SMELTING + "." + FUEL_EFFICIENCY + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.SMELTING_SECOND_SMELT) < 1) {
         if (getMaxBonusLevel(SubSkillType.SMELTING_SECOND_SMELT) < 1) {
-            reason.add("Skills.Smelting.SecondSmelt.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + SMELTING + ".SecondSmelt." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.SMELTING_SECOND_SMELT) < 1) {
         if (getMaximumProbability(SubSkillType.SMELTING_SECOND_SMELT) < 1) {
-            reason.add("Skills.Smelting.SecondSmelt.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + SMELTING + ".SecondSmelt." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getFluxMiningChance() < 1) {
         if (getFluxMiningChance() < 1) {
-            reason.add("Skills.Smelting.FluxMining.Chance should be at least 1!");
+            reason.add(SKILLS + "." + SMELTING + "." + FLUX + MINING + "." + CHANCE + " should be at least 1!");
         }
         }
 
 
         /* SWORDS */
         /* SWORDS */
         if (getMaximumProbability(SubSkillType.SWORDS_RUPTURE) < 1) {
         if (getMaximumProbability(SubSkillType.SWORDS_RUPTURE) < 1) {
-            reason.add("Skills.Swords.Rupture.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + SWORDS + "." + RUPTURE + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.SWORDS_RUPTURE) < 1) {
         if (getMaxBonusLevel(SubSkillType.SWORDS_RUPTURE) < 1) {
-            reason.add("Skills.Swords.Rupture.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + SWORDS + "." + RUPTURE + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getRuptureMaxTicks() < 1) {
         if (getRuptureMaxTicks() < 1) {
-            reason.add("Skills.Swords.Rupture.MaxTicks should be at least 1!");
+            reason.add(SKILLS + "." + SWORDS + "." + RUPTURE + "." + MAX_TICKS + " should be at least 1!");
         }
         }
 
 
         if (getRuptureMaxTicks() < getRuptureBaseTicks()) {
         if (getRuptureMaxTicks() < getRuptureBaseTicks()) {
-            reason.add("Skills.Swords.Rupture.MaxTicks should be at least Skills.Swords.Rupture.BaseTicks!");
+            reason.add(SKILLS + "." + SWORDS + "." + RUPTURE + "." + MAX_TICKS + " should be at least Skills.Swords.Rupture." + BASE_TICKS + "!");
         }
         }
 
 
         if (getRuptureBaseTicks() < 1) {
         if (getRuptureBaseTicks() < 1) {
-            reason.add("Skills.Swords.Rupture.BaseTicks should be at least 1!");
+            reason.add(SKILLS + "." + SWORDS + "." + RUPTURE + "." + BASE_TICKS + " should be at least 1!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.SWORDS_COUNTER_ATTACK) < 1) {
         if (getMaximumProbability(SubSkillType.SWORDS_COUNTER_ATTACK) < 1) {
-            reason.add("Skills.Swords.CounterAttack.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + SWORDS + "." + COUNTER_ATTACK + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.SWORDS_COUNTER_ATTACK) < 1) {
         if (getMaxBonusLevel(SubSkillType.SWORDS_COUNTER_ATTACK) < 1) {
-            reason.add("Skills.Swords.CounterAttack.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + SWORDS + "." + COUNTER_ATTACK + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getCounterModifier() < 1) {
         if (getCounterModifier() < 1) {
-            reason.add("Skills.Swords.CounterAttack.DamageModifier should be at least 1!");
+            reason.add(SKILLS + "." + SWORDS + "." + COUNTER_ATTACK + "." + DAMAGE_MODIFIER + " should be at least 1!");
         }
         }
 
 
         if (getSerratedStrikesModifier() < 1) {
         if (getSerratedStrikesModifier() < 1) {
-            reason.add("Skills.Swords.SerratedStrikes.DamageModifier should be at least 1!");
+            reason.add(SKILLS + "." + SWORDS + "." + SERRATED_STRIKES + "." + DAMAGE_MODIFIER + " should be at least 1!");
         }
         }
 
 
         if (getSerratedStrikesTicks() < 1) {
         if (getSerratedStrikesTicks() < 1) {
-            reason.add("Skills.Swords.SerratedStrikes.RuptureTicks should be at least 1!");
+            reason.add(SKILLS + "." + SWORDS + "." + SERRATED_STRIKES + "." + RUPTURE + "Ticks should be at least 1!");
         }
         }
 
 
         /* TAMING */
         /* TAMING */
 
 
         if (getMaximumProbability(SubSkillType.TAMING_GORE) < 1) {
         if (getMaximumProbability(SubSkillType.TAMING_GORE) < 1) {
-            reason.add("Skills.Taming.Gore.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + TAMING + "." + GORE + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.TAMING_GORE) < 1) {
         if (getMaxBonusLevel(SubSkillType.TAMING_GORE) < 1) {
-            reason.add("Skills.Taming.Gore.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + TAMING + "." + GORE + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getGoreModifier() < 1) {
         if (getGoreModifier() < 1) {
-            reason.add("Skills.Taming.Gore.Modifier should be at least 1!");
+            reason.add(SKILLS + "." + TAMING + "." + GORE + "." + MODIFIER + " should be at least 1!");
         }
         }
 
 
         if (getFastFoodChance() < 1) {
         if (getFastFoodChance() < 1) {
-            reason.add("Skills.Taming.FastFood.Chance should be at least 1!");
+            reason.add(SKILLS + "." + TAMING + "." + FAST_FOOD + "." + CHANCE + " should be at least 1!");
         }
         }
 
 
         if (getThickFurModifier() < 1) {
         if (getThickFurModifier() < 1) {
-            reason.add("Skills.Taming.ThickFur.Modifier should be at least 1!");
+            reason.add(SKILLS + "." + TAMING + "." + THICK_FUR + "." + MODIFIER + " should be at least 1!");
         }
         }
 
 
         if (getShockProofModifier() < 1) {
         if (getShockProofModifier() < 1) {
-            reason.add("Skills.Taming.ShockProof.Modifier should be at least 1!");
+            reason.add(SKILLS + "." + TAMING + "." + SHOCK_PROOF + "." + MODIFIER + " should be at least 1!");
         }
         }
 
 
         if (getSharpenedClawsBonus() < 1) {
         if (getSharpenedClawsBonus() < 1) {
-            reason.add("Skills.Taming.SharpenedClaws.Bonus should be at least 1!");
+            reason.add(SKILLS + "." + TAMING + "." + SHARPENED_CLAWS + "." + BONUS + " should be at least 1!");
         }
         }
 
 
         if (getMaxHorseJumpStrength() < 0 || getMaxHorseJumpStrength() > 2) {
         if (getMaxHorseJumpStrength() < 0 || getMaxHorseJumpStrength() > 2) {
-            reason.add("Skills.Taming.CallOfTheWild.MaxHorseJumpStrength should be between 0 and 2!");
+            reason.add(SKILLS + "." + TAMING + "." + CALL_OF_THE_WILD + "." + MAX_HORSE_JUMP_STRENGTH + " should be between 0 and 2!");
         }
         }
 
 
         /* UNARMED */
         /* UNARMED */
         if (getMaximumProbability(SubSkillType.UNARMED_DISARM) < 1) {
         if (getMaximumProbability(SubSkillType.UNARMED_DISARM) < 1) {
-            reason.add("Skills.Unarmed.Disarm.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + UNARMED + "." + DISARM + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.UNARMED_DISARM) < 1) {
         if (getMaxBonusLevel(SubSkillType.UNARMED_DISARM) < 1) {
-            reason.add("Skills.Unarmed.Disarm.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + UNARMED + "." + DISARM + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.UNARMED_ARROW_DEFLECT) < 1) {
         if (getMaximumProbability(SubSkillType.UNARMED_ARROW_DEFLECT) < 1) {
-            reason.add("Skills.Unarmed.ArrowDeflect.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + UNARMED + "." + ARROW_DEFLECT + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.UNARMED_ARROW_DEFLECT) < 1) {
         if (getMaxBonusLevel(SubSkillType.UNARMED_ARROW_DEFLECT) < 1) {
-            reason.add("Skills.Unarmed.ArrowDeflect.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + UNARMED + "." + ARROW_DEFLECT + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         if (getMaximumProbability(SubSkillType.UNARMED_IRON_GRIP) < 1) {
         if (getMaximumProbability(SubSkillType.UNARMED_IRON_GRIP) < 1) {
-            reason.add("Skills.Unarmed.IronGrip.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + UNARMED + "." + IRON_GRIP + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.UNARMED_IRON_GRIP) < 1) {
         if (getMaxBonusLevel(SubSkillType.UNARMED_IRON_GRIP) < 1) {
-            reason.add("Skills.Unarmed.IronGrip.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + UNARMED + "." + IRON_GRIP + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         /* WOODCUTTING */
         /* WOODCUTTING */
@@ -364,18 +481,18 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
         }*/
         }*/
 
 
         if (getMaximumProbability(SubSkillType.WOODCUTTING_HARVEST_LUMBER) < 1) {
         if (getMaximumProbability(SubSkillType.WOODCUTTING_HARVEST_LUMBER) < 1) {
-            reason.add("Skills.Woodcutting.HarvestLumber.ChanceMax should be at least 1!");
+            reason.add(SKILLS + "." + WOODCUTTING + "." + HARVEST_LUMBER + "." + CHANCE_MAX + " should be at least 1!");
         }
         }
 
 
         if (getMaxBonusLevel(SubSkillType.WOODCUTTING_HARVEST_LUMBER) < 1) {
         if (getMaxBonusLevel(SubSkillType.WOODCUTTING_HARVEST_LUMBER) < 1) {
-            reason.add("Skills.Woodcutting.HarvestLumber.MaxBonusLevel should be at least 1!");
+            reason.add(SKILLS + "." + WOODCUTTING + "." + HARVEST_LUMBER + "." + MAX_BONUS_LEVEL + " should be at least 1!");
         }
         }
 
 
         return reason;
         return reason;
     }
     }
 
 
     /* GENERAL */
     /* GENERAL */
-    public int getStartingLevel() { return startingLevel; }
+    public int getStartingLevel() { return getIntValue(SKILLS, GENERAL, STARTING_LEVEL); }
 
 
     /**
     /**
      * This returns the maximum level at which superabilities will stop lengthening from scaling alongside skill level.
      * This returns the maximum level at which superabilities will stop lengthening from scaling alongside skill level.
@@ -383,10 +500,10 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
      * @return the level at which abilities stop increasing in length
      * @return the level at which abilities stop increasing in length
      */
      */
     public int getAbilityLengthCap() {
     public int getAbilityLengthCap() {
-        if(!mcMMO.isRetroModeEnabled())
-            return getIntValue("Skills.General.Ability.Length.Standard.CapLevel");
+        if(!McmmoCore.isRetroModeEnabled())
+            return getIntValue(SKILLS, GENERAL, ABILITY, LENGTH, STANDARD, CAP_LEVEL);
         else
         else
-            return getIntValue("Skills.General.Ability.Length.RetroMode.CapLevel");
+            return getIntValue(SKILLS, GENERAL, ABILITY, LENGTH, RETRO_MODE, CAP_LEVEL);
     }
     }
 
 
     /**
     /**
@@ -395,13 +512,13 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
      * @return the number of levels required per ability length increase
      * @return the number of levels required per ability length increase
      */
      */
     public int getAbilityLength() {
     public int getAbilityLength() {
-        if(!mcMMO.isRetroModeEnabled())
-            return getIntValue("Skills.General.Ability.Length.Standard.IncreaseLevel");
+        if(!McmmoCore.isRetroModeEnabled())
+            return getIntValue(SKILLS, GENERAL, ABILITY, LENGTH, STANDARD, INCREASE_LEVEL);
         else
         else
-            return getIntValue("Skills.General.Ability.Length.RetroMode.IncreaseLevel");
+            return getIntValue(SKILLS, GENERAL, ABILITY, LENGTH, RETRO_MODE, INCREASE_LEVEL);
     }
     }
 
 
-    public int getEnchantBuff() { return getIntValue("Skills.General.Ability.EnchantBuff"); }
+    public int getEnchantBuff() { return getIntValue(SKILLS, GENERAL, ABILITY, ENCHANT_BUFF); }
 
 
     /**
     /**
      * Grabs the max bonus level for a skill used in RNG calculations
      * Grabs the max bonus level for a skill used in RNG calculations
@@ -411,8 +528,12 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
      * @return the level at which this skills max benefits will be reached on the curve
      * @return the level at which this skills max benefits will be reached on the curve
      */
      */
     public int getMaxBonusLevel(SubSkillType subSkillType) {
     public int getMaxBonusLevel(SubSkillType subSkillType) {
-        String keyPath = subSkillType.getAdvConfigAddress() + ".MaxBonusLevel.";
-        return mcMMO.isRetroModeEnabled() ? getIntValue(keyPath+"RetroMode") : getIntValue(keyPath+"Standard");
+        String[] category = subSkillType.getAdvConfigAddress();
+        
+        if(!McmmoCore.isRetroModeEnabled())
+            return getIntValue(category[0], category[1], category[2], MAX_BONUS_LEVEL, STANDARD);
+        else
+            return getIntValue(category[0], category[1], category[2], MAX_BONUS_LEVEL, RETRO_MODE);
     }
     }
 
 
     public int getMaxBonusLevel(AbstractSubSkill abstractSubSkill) {
     public int getMaxBonusLevel(AbstractSubSkill abstractSubSkill) {
@@ -420,7 +541,9 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
     }
     }
 
 
     public double getMaximumProbability(SubSkillType subSkillType) {
     public double getMaximumProbability(SubSkillType subSkillType) {
-        double maximumProbability = getDoubleValue(subSkillType.getAdvConfigAddress() + ".ChanceMax");
+        String[] category = subSkillType.getAdvConfigAddress();
+        
+        double maximumProbability = getDoubleValue(category[0], category[1], category[2], CHANCE_MAX);
 
 
         return maximumProbability;
         return maximumProbability;
     }
     }
@@ -434,22 +557,22 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
 
 
     public boolean doesSkillCommandSendBlankLines()
     public boolean doesSkillCommandSendBlankLines()
     {
     {
-        return getBooleanValue("Feedback.SkillCommand.BlankLinesAboveHeader");
+        return getBooleanValue(FEEDBACK,  SKILL_COMMAND,  BLANK_LINES_ABOVE_HEADER);
     }
     }
 
 
     public boolean doesNotificationUseActionBar(NotificationType notificationType)
     public boolean doesNotificationUseActionBar(NotificationType notificationType)
     {
     {
-        return getBooleanValue("Feedback.ActionBarNotifications."+notificationType.toString()+".Enabled");
+        return getBooleanValue(FEEDBACK,  ACTION_BAR_NOTIFICATIONS, notificationType.toString(),  ENABLED);
     }
     }
 
 
     public boolean doesNotificationSendCopyToChat(NotificationType notificationType)
     public boolean doesNotificationSendCopyToChat(NotificationType notificationType)
     {
     {
-        return getBooleanValue("Feedback.ActionBarNotifications."+notificationType.toString()+".SendCopyOfMessageToChat");
+        return getBooleanValue(FEEDBACK,  ACTION_BAR_NOTIFICATIONS, notificationType.toString(),  SEND_COPY_OF_MESSAGE_TO_CHAT);
     }
     }
 
 
     public boolean useTitlesForXPEvent()
     public boolean useTitlesForXPEvent()
     {
     {
-        return getBooleanValue("Feedback.Events.XP.SendTitles");
+        return getBooleanValue(FEEDBACK,  EVENTS,  XP,  SEND_TITLES);
     }
     }
 
 
     private ChatColor getChatColorFromKey(String keyLocation) {
     private ChatColor getChatColorFromKey(String keyLocation) {
@@ -460,7 +583,7 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
 
 
     private ChatColor getChatColor(String configColor) {
     private ChatColor getChatColor(String configColor) {
         for (ChatColor chatColor : ChatColor.values()) {
         for (ChatColor chatColor : ChatColor.values()) {
-            if (configColor.equalsIgnoreCase(chatColor.getName()))
+            if (configColor.equalsIgnoreCase(chatColor.toString()))
                 return chatColor;
                 return chatColor;
         }
         }
 
 
@@ -469,140 +592,129 @@ public class AdvancedConfig extends ConfigLoaderConfigurable {
         return ChatColor.WHITE;
         return ChatColor.WHITE;
     }
     }
 
 
-    /**
-     * Some SubSkills have the ability to retain classic functionality
-     * @param subSkillType SubSkillType with classic functionality
-     * @return true if the subskill is in classic mode
-     */
-    public boolean isSubSkillClassic(SubSkillType subSkillType)
-    {
-        return getBooleanValue(subSkillType.getAdvConfigAddress()+".Classic");
-    }
-
     /* ACROBATICS */
     /* ACROBATICS */
-    public double getDodgeDamageModifier() { return getDoubleValue("Skills.Acrobatics.Dodge.DamageModifier"); }
+    public double getDodgeDamageModifier() { return getDoubleValue(SKILLS, ACROBATICS, DODGE, DAMAGE_MODIFIER); }
 
 
-    public double getRollDamageThreshold() { return getDoubleValue("Skills.Acrobatics.Roll.DamageThreshold"); }
+    public double getRollDamageThreshold() { return getDoubleValue(SKILLS, ACROBATICS, ROLL, DAMAGE_THRESHOLD); }
 
 
-    public double getGracefulRollDamageThreshold() { return getDoubleValue("Skills.Acrobatics.GracefulRoll.DamageThreshold"); }
+    public double getGracefulRollDamageThreshold() { return getDoubleValue(SKILLS, ACROBATICS, GRACEFUL_ROLL, DAMAGE_THRESHOLD); }
 
 
     /* ALCHEMY */
     /* ALCHEMY */
-    public int getCatalysisMaxBonusLevel() { return getIntValue("Skills.Alchemy.Catalysis.MaxBonusLevel"); }
+    public int getCatalysisMaxBonusLevel() { return getIntValue(SKILLS, ALCHEMY, CATALYSIS, MAX_BONUS_LEVEL); }
 
 
-    public double getCatalysisMinSpeed() { return getDoubleValue("Skills.Alchemy.Catalysis.MinSpeed"); }
-    public double getCatalysisMaxSpeed() { return getDoubleValue("Skills.Alchemy.Catalysis.MaxSpeed"); }
+    public double getCatalysisMinSpeed() { return getDoubleValue(SKILLS, ALCHEMY, CATALYSIS, MIN_SPEED); }
+    public double getCatalysisMaxSpeed() { return getDoubleValue(SKILLS, ALCHEMY, CATALYSIS, MAX_SPEED); }
 
 
     /* ARCHERY */
     /* ARCHERY */
-    public double getSkillShotRankDamageMultiplier() { return getDoubleValue("Skills.Archery.SkillShot.RankDamageMultiplier"); }
-    public double getSkillShotDamageMax() { return getDoubleValue("Skills.Archery.SkillShot.MaxDamage"); }
+    public double getSkillShotRankDamageMultiplier() { return getDoubleValue(SKILLS, ARCHERY, SKILL_SHOT, RANK_DAMAGE_MULTIPLIER); }
+    public double getSkillShotDamageMax() { return getDoubleValue(SKILLS, ARCHERY, SKILL_SHOT, MAX_DAMAGE); }
 
 
-    public double getDazeBonusDamage() { return getDoubleValue("Skills.Archery.Daze.BonusDamage"); }
+    public double getDazeBonusDamage() { return getDoubleValue(SKILLS, ARCHERY, DAZE, BONUS_DAMAGE); }
 
 
-    public double getForceMultiplier() { return getDoubleValue("Skills.Archery.ForceMultiplier"); }
+    public double getForceMultiplier() { return getDoubleValue(SKILLS, ARCHERY, FORCE_MULTIPLIER); }
 
 
     /* AXES */
     /* AXES */
-    public double getAxeMasteryRankDamageMultiplier() { return getDoubleValue("Skills.Axes.AxeMastery.RankDamageMultiplier"); }
+    public double getAxeMasteryRankDamageMultiplier() { return getDoubleValue(SKILLS, AXES, AXE_MASTERY, RANK_DAMAGE_MULTIPLIER); }
 
 
-    public double getCriticalStrikesPVPModifier() { return getDoubleValue("Skills.Axes.CriticalStrikes.PVP_Modifier"); }
-    public double getCriticalStrikesPVEModifier() { return getDoubleValue("Skills.Axes.CriticalStrikes.PVE_Modifier"); }
+    public double getCriticalStrikesPVPModifier() { return getDoubleValue(SKILLS, AXES, CRITICAL_STRIKES, PVP_MODIFIER); }
+    public double getCriticalStrikesPVEModifier() { return getDoubleValue(SKILLS, AXES, CRITICAL_STRIKES, PVE_MODIFIER); }
 
 
-    public double getGreaterImpactChance() { return getDoubleValue("Skills.Axes.GreaterImpact.Chance"); }
-    public double getGreaterImpactModifier() { return getDoubleValue("Skills.Axes.GreaterImpact.KnockbackModifier"); }
-    public double getGreaterImpactBonusDamage() { return getDoubleValue("Skills.Axes.GreaterImpact.BonusDamage"); }
+    public double getGreaterImpactChance() { return getDoubleValue(SKILLS, AXES, GREATER_IMPACT, CHANCE); }
+    public double getGreaterImpactModifier() { return getDoubleValue(SKILLS, AXES, GREATER_IMPACT, KNOCKBACK_MODIFIER); }
+    public double getGreaterImpactBonusDamage() { return getDoubleValue(SKILLS, AXES, GREATER_IMPACT, BONUS_DAMAGE); }
 
 
     public int getArmorImpactIncreaseLevel() {
     public int getArmorImpactIncreaseLevel() {
-        int increaseLevel = getIntValue("Skills.Axes.ArmorImpact.IncreaseLevel");
+        int increaseLevel = getIntValue(SKILLS, AXES, ARMOR_IMPACT, INCREASE_LEVEL);
 
 
-        if(mcMMO.isRetroModeEnabled())
+        if(McmmoCore.isRetroModeEnabled())
             return increaseLevel * 10;
             return increaseLevel * 10;
 
 
         return increaseLevel;
         return increaseLevel;
     }
     }
 
 
-    public double getImpactChance() { return getDoubleValue("Skills.Axes.ArmorImpact.Chance"); }
-    public double getArmorImpactMaxDurabilityDamage() { return getDoubleValue("Skills.Axes.ArmorImpact.MaxPercentageDurabilityDamage"); }
+    public double getImpactChance() { return getDoubleValue(SKILLS, AXES, ARMOR_IMPACT, CHANCE); }
+    public double getArmorImpactMaxDurabilityDamage() { return getDoubleValue(SKILLS, AXES, ARMOR_IMPACT, MAX_PERCENTAGE_DURABILITY_DAMAGE); }
 
 
-    public double getSkullSplitterModifier() { return getDoubleValue("Skills.Axes.SkullSplitter.DamageModifier"); }
+    public double getSkullSplitterModifier() { return getDoubleValue(SKILLS, AXES, SKULL_SPLITTER, DAMAGE_MODIFIER); }
 
 
     /* EXCAVATION */
     /* EXCAVATION */
     //Nothing to configure, everything is already configurable in config.yml
     //Nothing to configure, everything is already configurable in config.yml
 
 
     /* FISHING */
     /* FISHING */
-    public double getShakeChance(int rank) { return getDoubleValue("Skills.Fishing.ShakeChance.Rank_" + rank); }
-    public int getFishingVanillaXPModifier(int rank) { return getIntValue("Skills.Fishing.VanillaXPMultiplier.Rank_" + rank); }
-    public int getFishermanDietRankChange() { return getIntValue("Skills.Fishing.FishermansDiet.RankChange"); }
-    public double getMasterAnglerBoatModifier() {return getDoubleValue("Skills.Fishing.MasterAngler.BoatModifier"); }
-    public double getMasterAnglerBiomeModifier() {return getDoubleValue("Skills.Fishing.MasterAngler.BiomeModifier"); }
+    public double getShakeChance(int rank) { return getDoubleValue(SKILLS, FISHING, SHAKE, CHANCE, RANK, String.valueOf(rank)); }
+    public int getFishingVanillaXPModifier(int rank) { return getIntValue(SKILLS, FISHING, VANILLA_XPMULTIPLIER, RANK, String.valueOf(rank)); }
+    public double getMasterAnglerBoatModifier() {return getDoubleValue(SKILLS, FISHING, MASTER_ANGLER, BOAT_MODIFIER); }
+    public double getMasterAnglerBiomeModifier() {return getDoubleValue(SKILLS, FISHING, MASTER_ANGLER, BIOME_MODIFIER); }
 
 
     /* HERBALISM */
     /* HERBALISM */
-    public int getFarmerDietRankChange() { return getIntValue("Skills.Herbalism.FarmersDiet.RankChange"); }
+    //public int getFarmerDietRankChange() { return getIntValue(SKILLS, ".Herbalism.FarmersDiet.RankChange"); }
 
 
-    public int getGreenThumbStageChange() { return getIntValue("Skills.Herbalism.GreenThumb.StageChange"); }
+    //public int getGreenThumbStageChange() { return getIntValue(SKILLS, ".Herbalism.GreenThumb.StageChange"); }
 
 
     /* MINING */
     /* MINING */
-    public boolean getDoubleDropSilkTouchEnabled() { return config.getBoolean("Skills.Mining.DoubleDrops.SilkTouch", true); }
-    public int getBlastMiningRankLevel(int rank) { return config.getInt("Skills.Mining.BlastMining.Rank_Levels.Rank_" + rank); }
-    public double getBlastDamageDecrease(int rank) { return config.getDouble("Skills.Mining.BlastMining.BlastDamageDecrease.Rank_" + rank); }
-    public double getOreBonus(int rank) { return config.getDouble("Skills.Mining.BlastMining.OreBonus.Rank_" + rank); }
-    public double getDebrisReduction(int rank) { return config.getDouble("Skills.Mining.BlastMining.DebrisReduction.Rank_" + rank); }
-    public int getDropMultiplier(int rank) { return config.getInt("Skills.Mining.BlastMining.DropMultiplier.Rank_" + rank); }
-    public double getBlastRadiusModifier(int rank) { return config.getDouble("Skills.Mining.BlastMining.BlastRadiusModifier.Rank_" + rank); }
+    public boolean getDoubleDropSilkTouchEnabled() { return getBooleanValue(SKILLS, MINING, "DoubleDrops", "SilkTouch"); }
+    public int getBlastMiningRankLevel(int rank) { return getIntValue(SKILLS, MINING, BLAST_MINING, RANK, LEVELS, RANK, String.valueOf(rank)); }
+    public double getBlastDamageDecrease(int rank) { return getDoubleValue(SKILLS, MINING, BLAST_MINING, BLAST_DAMAGE_DECREASE, RANK, String.valueOf(rank)); }
+    public double getOreBonus(int rank) { return getDoubleValue(SKILLS, MINING, BLAST_MINING, ORE_BONUS, RANK, String.valueOf(rank)); }
+    public double getDebrisReduction(int rank) { return getDoubleValue(SKILLS, MINING, BLAST_MINING, DEBRIS_REDUCTION, RANK, String.valueOf(rank)); }
+    public int getDropMultiplier(int rank) { return getIntValue(SKILLS, MINING, BLAST_MINING, DROP_MULTIPLIER, RANK, String.valueOf(rank)); }
+    public double getBlastRadiusModifier(int rank) { return getDoubleValue(SKILLS, MINING, BLAST_MINING, BLAST_RADIUS, MODIFIER, RANK, String.valueOf(rank)); }
 
 
     /* REPAIR */
     /* REPAIR */
-    public double getRepairMasteryMaxBonus() { return getDoubleValue("Skills.Repair.RepairMastery.MaxBonusPercentage"); }
-    public int getRepairMasteryMaxLevel() { return getIntValue("Skills.Repair.RepairMastery.MaxBonusLevel"); }
+    public double getRepairMasteryMaxBonus() { return getDoubleValue(SKILLS, REPAIR, REPAIR_MASTERY, MAX_BONUS_PERCENTAGE); }
+    public int getRepairMasteryMaxLevel() { return getIntValue(SKILLS, REPAIR, REPAIR_MASTERY, MAX_BONUS_LEVEL); }
 
 
     /* Arcane Forging */
     /* Arcane Forging */
-    public boolean getArcaneForgingEnchantLossEnabled() { return getBooleanValue("Skills.Repair.ArcaneForging.May_Lose_Enchants"); }
-    public double getArcaneForgingKeepEnchantsChance(int rank) { return getDoubleValue("Skills.Repair.ArcaneForging.Keep_Enchants_Chance.Rank_" + rank); }
+    public boolean getArcaneForgingEnchantLossEnabled() { return getBooleanValue(SKILLS, REPAIR, ARCANE_FORGING, MAY_LOSE_ENCHANTS); }
+    public double getArcaneForgingKeepEnchantsChance(int rank) { return getDoubleValue(SKILLS, REPAIR, ARCANE_FORGING, KEEP_ENCHANTS, CHANCE, RANK, String.valueOf(rank)); }
 
 
-    public boolean getArcaneForgingDowngradeEnabled() { return getBooleanValue("Skills.Repair.ArcaneForging.Downgrades_Enabled"); }
-    public double getArcaneForgingDowngradeChance(int rank) { return getDoubleValue("Skills.Repair.ArcaneForging.Downgrades_Chance.Rank_" + rank); }
+    public boolean getArcaneForgingDowngradeEnabled() { return getBooleanValue(SKILLS, REPAIR, ARCANE_FORGING, DOWNGRADES_ENABLED); }
+    public double getArcaneForgingDowngradeChance(int rank) { return getDoubleValue(SKILLS, REPAIR, ARCANE_FORGING, DOWNGRADES, CHANCE, RANK, String.valueOf(rank)); }
 
 
     /* SALVAGE */
     /* SALVAGE */
 
 
-    public boolean getArcaneSalvageEnchantDowngradeEnabled() { return getBooleanValue("Skills.Salvage.ArcaneSalvage.EnchantDowngradeEnabled"); }
-    public boolean getArcaneSalvageEnchantLossEnabled() { return getBooleanValue("Skills.Salvage.ArcaneSalvage.EnchantLossEnabled"); }
+    public boolean getArcaneSalvageEnchantDowngradeEnabled() { return getBooleanValue(SKILLS, SALVAGE, ARCANE_SALVAGE, ENCHANT_DOWNGRADE_ENABLED); }
+    public boolean getArcaneSalvageEnchantLossEnabled() { return getBooleanValue(SKILLS, SALVAGE, ARCANE_SALVAGE, ENCHANT_LOSS_ENABLED); }
 
 
-    public double getArcaneSalvageExtractFullEnchantsChance(int rank) { return getDoubleValue("Skills.Salvage.ArcaneSalvage.ExtractFullEnchant.Rank_" + rank); }
-    public double getArcaneSalvageExtractPartialEnchantsChance(int rank) { return getDoubleValue("Skills.Salvage.ArcaneSalvage.ExtractPartialEnchant.Rank_" + rank); }
+    public double getArcaneSalvageExtractFullEnchantsChance(int rank) { return getDoubleValue(SKILLS, SALVAGE, ARCANE_SALVAGE, EXTRACT_FULL_ENCHANT, RANK, String.valueOf(rank)); }
+    public double getArcaneSalvageExtractPartialEnchantsChance(int rank) { return getDoubleValue(SKILLS, SALVAGE, ARCANE_SALVAGE, EXTRACT_PARTIAL_ENCHANT, RANK, String.valueOf(rank)); }
 
 
     /* SMELTING */
     /* SMELTING */
-    public int getBurnModifierMaxLevel() { return getIntValue("Skills.Smelting.FuelEfficiency.MaxBonusLevel"); }
-    public double getBurnTimeMultiplier() { return getDoubleValue("Skills.Smelting.FuelEfficiency.Multiplier"); }
+    public int getBurnModifierMaxLevel() { return getIntValue(SKILLS, SMELTING, FUEL_EFFICIENCY, MAX_BONUS_LEVEL); }
+    public double getBurnTimeMultiplier() { return getDoubleValue(SKILLS, SMELTING, FUEL_EFFICIENCY, MULTIPLIER); }
 
 
-    public double getFluxMiningChance() { return getDoubleValue("Skills.Smelting.FluxMining.Chance"); }
+    public double getFluxMiningChance() { return getDoubleValue(SKILLS, SMELTING, FLUX, MINING, CHANCE); }
 
 
-    public int getSmeltingRankLevel(int rank) { return getIntValue("Skills.Smelting.Rank_Levels.Rank_" + rank); }
+    public int getSmeltingRankLevel(int rank) { return getIntValue(SKILLS, SMELTING, RANK, LEVELS, RANK, String.valueOf(rank)); }
 
 
-    public int getSmeltingVanillaXPBoostMultiplier(int rank) { return getIntValue("Skills.Smelting.VanillaXPMultiplier.Rank_" + rank); }
+    public int getSmeltingVanillaXPBoostMultiplier(int rank) { return getIntValue(SKILLS, SMELTING, VANILLA_XPMULTIPLIER, RANK, String.valueOf(rank)); }
 
 
     /* SWORDS */
     /* SWORDS */
-    public double getRuptureDamagePlayer() { return getDoubleValue("Skills.Swords.Rupture.DamagePlayer"); }
-    public double getRuptureDamageMobs() { return getDoubleValue("Skills.Swords.Rupture.DamageMobs"); }
+    public double getRuptureDamagePlayer() { return getDoubleValue(SKILLS, SWORDS, RUPTURE, DAMAGE_PLAYER); }
+    public double getRuptureDamageMobs() { return getDoubleValue(SKILLS, SWORDS, RUPTURE, DAMAGE_MOBS); }
 
 
-    public int getRuptureMaxTicks() { return getIntValue("Skills.Swords.Rupture.MaxTicks"); }
-    public int getRuptureBaseTicks() { return getIntValue("Skills.Swords.Rupture.BaseTicks"); }
+    public int getRuptureMaxTicks() { return getIntValue(SKILLS, SWORDS, RUPTURE, MAX_TICKS); }
+    public int getRuptureBaseTicks() { return getIntValue(SKILLS, SWORDS, RUPTURE, BASE_TICKS); }
 
 
-    public double getCounterModifier() { return getDoubleValue("Skills.Swords.CounterAttack.DamageModifier"); }
+    public double getCounterModifier() { return getDoubleValue(SKILLS, SWORDS, COUNTER_ATTACK, DAMAGE_MODIFIER); }
 
 
-    public double getSerratedStrikesModifier() { return getDoubleValue("Skills.Swords.SerratedStrikes.DamageModifier"); }
-    public int getSerratedStrikesTicks() { return getIntValue("Skills.Swords.SerratedStrikes.RuptureTicks"); }
+    public double getSerratedStrikesModifier() { return getDoubleValue(SKILLS, SWORDS, SERRATED_STRIKES, DAMAGE_MODIFIER); }
+    public int getSerratedStrikesTicks() { return getIntValue(SKILLS, SWORDS, SERRATED_STRIKES, RUPTURE, TICKS); }
 
 
     /* TAMING */
     /* TAMING */
-    public double getGoreModifier() { return getDoubleValue("Skills.Taming.Gore.Modifier"); }
-    public double getFastFoodChance() { return getDoubleValue("Skills.Taming.FastFoodService.Chance"); }
-    public double getPummelChance() { return getDoubleValue("Skills.Taming.Pummel.Chance"); }
-    public double getThickFurModifier() { return getDoubleValue("Skills.Taming.ThickFur.Modifier"); }
-    public double getShockProofModifier() { return getDoubleValue("Skills.Taming.ShockProof.Modifier"); }
+    public double getGoreModifier() { return getDoubleValue(SKILLS, TAMING, GORE, MODIFIER); }
+    public double getFastFoodChance() { return getDoubleValue(SKILLS, TAMING, FAST_FOOD_SERVICE, CHANCE); }
+    public double getPummelChance() { return getDoubleValue(SKILLS, TAMING, PUMMEL, CHANCE); }
+    public double getThickFurModifier() { return getDoubleValue(SKILLS, TAMING, THICK_FUR, MODIFIER); }
+    public double getShockProofModifier() { return getDoubleValue(SKILLS, TAMING, SHOCK_PROOF, MODIFIER); }
 
 
-    public double getSharpenedClawsBonus() { return getDoubleValue("Skills.Taming.SharpenedClaws.Bonus"); }
+    public double getSharpenedClawsBonus() { return getDoubleValue(SKILLS, TAMING, SHARPENED_CLAWS, BONUS); }
 
 
-    public double getMinHorseJumpStrength() { return getDoubleValue("Skills.Taming.CallOfTheWild.MinHorseJumpStrength"); }
-    public double getMaxHorseJumpStrength() { return getDoubleValue("Skills.Taming.CallOfTheWild.MaxHorseJumpStrength"); }
+    public double getMinHorseJumpStrength() { return getDoubleValue(SKILLS, TAMING, CALL_OF_THE_WILD, MIN_HORSE_JUMP_STRENGTH); }
+    public double getMaxHorseJumpStrength() { return getDoubleValue(SKILLS, TAMING, CALL_OF_THE_WILD, MAX_HORSE_JUMP_STRENGTH); }
 
 
     /* UNARMED */
     /* UNARMED */
-    public boolean getDisarmProtected() { return getBooleanValue("Skills.Unarmed.Disarm.AntiTheft"); }
+    public boolean getDisarmProtected() { return getBooleanValue(SKILLS, UNARMED, DISARM, ANTI_THEFT); }
 
 
     /* WOODCUTTING */
     /* WOODCUTTING */
 }
 }

+ 0 - 135
src/main/java/com/gmail/nossr50/config/AutoUpdateConfigLoader.java

@@ -1,135 +0,0 @@
-package com.gmail.nossr50.config;
-
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
-
-import java.io.*;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.Set;
-
-public abstract class AutoUpdateConfigLoader extends ConfigLoader {
-    public AutoUpdateConfigLoader(String relativePath, String fileName) {
-        super(relativePath, fileName);
-    }
-
-    public AutoUpdateConfigLoader(String fileName) {
-        super(fileName);
-    }
-
-    @Override
-    protected void loadFile() {
-        super.loadFile();
-        FileConfiguration internalConfig = YamlConfiguration.loadConfiguration(plugin.getResourceAsReader(fileName));
-
-        Set<String> configKeys = config.getKeys(true);
-        Set<String> internalConfigKeys = internalConfig.getKeys(true);
-
-        boolean needSave = false;
-
-        Set<String> oldKeys = new HashSet<String>(configKeys);
-        oldKeys.removeAll(internalConfigKeys);
-
-        Set<String> newKeys = new HashSet<String>(internalConfigKeys);
-        newKeys.removeAll(configKeys);
-
-        // Don't need a re-save if we have old keys sticking around?
-        // Would be less saving, but less... correct?
-        if (!newKeys.isEmpty() || !oldKeys.isEmpty()) {
-            needSave = true;
-        }
-
-        for (String key : oldKeys) {
-            plugin.debug("Detected potentially unused key: " + key);
-            //config.set(key, null);
-        }
-
-        for (String key : newKeys) {
-            plugin.debug("Adding new key: " + key + " = " + internalConfig.get(key));
-            config.set(key, internalConfig.get(key));
-        }
-
-        if (needSave) {
-            // Get Bukkit's version of an acceptable config with new keys, and no old keys
-            String output = config.saveToString();
-
-            // Convert to the superior 4 space indentation
-            output = output.replace("  ", "    ");
-
-            // Rip out Bukkit's attempt to save comments at the top of the file
-            while (output.replaceAll("[//s]", "").startsWith("#")) {
-                output = output.substring(output.indexOf('\n', output.indexOf('#')) + 1);
-            }
-
-            // Read the internal config to get comments, then put them in the new one
-            try {
-                // Read internal
-                BufferedReader reader = new BufferedReader(new InputStreamReader(plugin.getResource(fileName)));
-                LinkedHashMap<String, String> comments = new LinkedHashMap<String, String>();
-                String temp = "";
-
-                String line;
-                while ((line = reader.readLine()) != null) {
-                    if (line.contains("#")) {
-                        temp += line + "\n";
-                    }
-                    else if (line.contains(":")) {
-                        line = line.substring(0, line.indexOf(":") + 1);
-                        if (!temp.isEmpty()) {
-                            if(comments.containsKey(line)) {
-                                int index = 0;
-                                while(comments.containsKey(line + index)) {
-                                    index++;
-                                }
-                                
-                                line = line + index;
-                            }
-
-                            comments.put(line, temp);
-                            temp = "";
-                        }
-                    }
-                }
-
-                // Dump to the new one
-                HashMap<String, Integer> indexed = new HashMap<String, Integer>();
-                for (String key : comments.keySet()) {
-                    String actualkey = key.substring(0, key.indexOf(":") + 1);
-
-                    int index = 0;
-                    if(indexed.containsKey(actualkey)) {
-                        index = indexed.get(actualkey);
-                    }
-                    boolean isAtTop = !output.contains("\n" + actualkey);
-                    index = output.indexOf((isAtTop ? "" : "\n") + actualkey, index);
-
-                    if (index >= 0) {
-                        output = output.substring(0, index) + "\n" + comments.get(key) + output.substring(isAtTop ? index : index + 1);
-                        indexed.put(actualkey, index + comments.get(key).length() + actualkey.length() + 1);
-                    }
-                }
-            }
-            catch (Exception e) {
-                e.printStackTrace();
-            }
-
-            // Save it
-            try {
-                String saveName = fileName;
-                // At this stage we cannot guarantee that Config has been loaded, so we do the check directly here
-                if (!plugin.getConfig().getBoolean("General.Config_Update_Overwrite", true)) {
-                    saveName += ".new";
-                }
-
-                BufferedWriter writer = new BufferedWriter(new FileWriter(new File(plugin.getDataFolder(), saveName)));
-                writer.write(output);
-                writer.flush();
-                writer.close();
-            }
-            catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-    }
-}

+ 59 - 0
src/main/java/com/gmail/nossr50/config/ChildConfig.java

@@ -0,0 +1,59 @@
+package com.gmail.nossr50.config;
+
+import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.skills.child.FamilyTree;
+import com.gmail.nossr50.util.StringUtils;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.util.EnumSet;
+
+public class ChildConfig extends ConfigCollections {
+    public ChildConfig() {
+        super("child.yml");
+    }
+
+    @Override
+    protected void loadKeys() {
+        config.setDefaults(YamlConfiguration.loadConfiguration(plugin.getResourceAsReader("child.yml")));
+
+        FamilyTree.clearRegistrations(); // when reloading, need to clear statics
+
+        for (PrimarySkillType skill : PrimarySkillType.CHILD_SKILLS) {
+            plugin.debug("Finding parents of " + skill.name());
+
+            EnumSet<PrimarySkillType> parentSkills = EnumSet.noneOf(PrimarySkillType.class);
+            boolean useDefaults = false; // If we had an error we back out and use defaults
+
+            for (String name : config.getStringList(StringUtils.getCapitalized(skill.name()))) {
+                try {
+                    PrimarySkillType parentSkill = PrimarySkillType.valueOf(name.toUpperCase());
+                    FamilyTree.enforceNotChildSkill(parentSkill);
+                    parentSkills.add(parentSkill);
+                } catch (IllegalArgumentException ex) {
+                    plugin.getLogger().warning(name + " is not a valid skill type, or is a child skill!");
+                    useDefaults = true;
+                    break;
+                }
+            }
+
+            if (useDefaults) {
+                parentSkills.clear();
+                for (String name : config.getDefaults().getStringList(StringUtils.getCapitalized(skill.name()))) {
+                    /* We do less checks in here because it's from inside our jar.
+                     * If they're dedicated enough to have modified it, they can have the errors it may produce.
+                     * Alternatively, this can be used to allow child skills to be parent skills, provided there are no circular dependencies this is an advanced sort of configuration.
+                     */
+                    parentSkills.add(PrimarySkillType.valueOf(name.toUpperCase()));
+                }
+            }
+
+            // Register them
+            for (PrimarySkillType parentSkill : parentSkills) {
+                plugin.debug("Registering " + parentSkill.name() + " as parent of " + skill.name());
+                FamilyTree.registerParent(skill, parentSkill);
+            }
+        }
+
+        FamilyTree.closeRegistration();
+    }
+}

+ 38 - 0
src/main/java/com/gmail/nossr50/config/ChunkConversionOptions.java

@@ -0,0 +1,38 @@
+package com.gmail.nossr50.config;
+
+/**
+ * This class is used to define settings for upgrading EXTREMELY OLD versions of mcMMO to newer versions
+ * It could probably be deleted
+ */
+public class ChunkConversionOptions {
+    private static final boolean chunkletsEnabled = true;
+    private static final int conversionRate = 1;
+    private static final boolean useEnchantmentBuffs = true;
+    private static final int uuidConvertAmount = 5;
+    private static final int mojangRateLimit = 50000;
+    private static final long mojangLimitPeriod = 600000;
+
+    public static boolean getChunkletsEnabled() {
+        return chunkletsEnabled;
+    }
+
+    public static int getConversionRate() {
+        return conversionRate;
+    }
+
+    public static boolean useEnchantmentBuffs() {
+        return useEnchantmentBuffs;
+    }
+
+    public static int getUUIDConvertAmount() {
+        return uuidConvertAmount;
+    }
+
+    public static int getMojangRateLimit() {
+        return mojangRateLimit;
+    }
+
+    public static long getMojangLimitPeriod() {
+        return mojangLimitPeriod;
+    }
+}

+ 259 - 497
src/main/java/com/gmail/nossr50/config/Config.java

@@ -1,575 +1,337 @@
 package com.gmail.nossr50.config;
 package com.gmail.nossr50.config;
 
 
-import com.gmail.nossr50.database.SQLDatabaseManager.PoolIdentifier;
-import com.gmail.nossr50.datatypes.MobHealthbarType;
-import com.gmail.nossr50.datatypes.party.PartyFeature;
-import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
-import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
-import com.gmail.nossr50.util.StringUtils;
-import org.bukkit.Material;
-import org.bukkit.block.data.BlockData;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.entity.EntityType;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-public class Config extends AutoUpdateConfigLoader {
-    private static Config instance;
-
-    private Config() {
-        super("config.yml");
-        validate();
-    }
-
-    public static Config getInstance() {
-        if (instance == null) {
-            instance = new Config();
-        }
-
-        return instance;
-    }
-
-    @Override
-    protected void loadKeys() {
-
-    }
-
-    @Override
-    protected boolean validateKeys() {
-        // Validate all the settings!
-        List<String> reason = new ArrayList<String>();
-
-        /* General Settings */
-        if (getSaveInterval() <= 0) {
-            reason.add("General.Save_Interval should be greater than 0!");
-        }
-
-        /* MySQL Settings */
-        for (PoolIdentifier identifier : PoolIdentifier.values()) {
-            if (getMySQLMaxConnections(identifier) <= 0) {
-                reason.add("MySQL.Database.MaxConnections." + StringUtils.getCapitalized(identifier.toString()) + " should be greater than 0!");
-            }
-            if (getMySQLMaxPoolSize(identifier) <= 0) {
-                reason.add("MySQL.Database.MaxPoolSize." + StringUtils.getCapitalized(identifier.toString()) + " should be greater than 0!");
-            }
-        }
+import com.google.common.io.Files;
+import ninja.leaping.configurate.ConfigurationNode;
+import ninja.leaping.configurate.commented.CommentedConfigurationNode;
+import ninja.leaping.configurate.loader.ConfigurationLoader;
+import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
+import org.yaml.snakeyaml.DumperOptions;
 
 
-        /* Mob Healthbar */
-        if (getMobHealthbarTime() == 0) {
-            reason.add("Mob_Healthbar.Display_Time cannot be 0! Set to -1 to disable or set a valid value.");
-        }
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
 
 
-        /* Scoreboards */
-        /*if (getRankScoreboardTime() != -1 && getRankScoreboardTime() <= 0) {
-            reason.add("Scoreboard.Types.Rank.Display_Time should be greater than 0, or -1!");
-        }
+/**
+ * Handles loading and cacheing configuration settings from a configurable compatible config file
+ */
+//@ConfigSerializable
+public abstract class Config implements VersionedConfig, Unload {
 
 
-        if (getStatsScoreboardTime() != -1 && getStatsScoreboardTime() <= 0) {
-            reason.add("Scoreboard.Types.Stats.Display_Time should be greater than 0, or -1!");
-        }
+    /* SETTINGS */
+    private boolean mergeNewKeys;
 
 
-        if (getTopScoreboardTime() != -1 && getTopScoreboardTime() <= 0) {
-            reason.add("Scoreboard.Types.Top.Display_Time should be greater than 0, or -1!");
-        }
+    /* PATH VARS */
 
 
-        if (getInspectScoreboardTime() != -1 && getInspectScoreboardTime() <= 0) {
-            reason.add("Scoreboard.Types.Inspect.Display_Time should be greater than 0, or -1!");
-        }
+    public final File DIRECTORY_DATA_FOLDER; //Directory that the file is in
+    public final String FILE_RELATIVE_PATH; //Relative Path to the file
+    protected final String DIRECTORY_DEFAULTS = "defaults";
 
 
-        if (getSkillScoreboardTime() != -1 && getSkillScoreboardTime() <= 0) {
-            reason.add("Scoreboard.Types.Skill.Display_Time should be greater than 0, or -1!");
-        }
+    /* LOADERS */
 
 
-        if (getSkillLevelUpTime() != -1 && getSkillScoreboardTime() <= 0) {
-            reason.add("Scoreboard.Types.Skill.Display_Time should be greater than 0, or -1!");
-        }
+    private YAMLConfigurationLoader defaultCopyLoader;
+    private YAMLConfigurationLoader userCopyLoader;
 
 
-        if (!(getRankUseChat() || getRankUseBoard())) {
-            reason.add("Either Board or Print in Scoreboard.Types.Rank must be true!");
-        }
-
-        if (!(getTopUseChat() || getTopUseBoard())) {
-            reason.add("Either Board or Print in Scoreboard.Types.Top must be true!");
-        }
+    /* CONFIG FILES */
 
 
-        if (!(getStatsUseChat() || getStatsUseBoard())) {
-            reason.add("Either Board or Print in Scoreboard.Types.Stats must be true!");
-        }
+    private File resourceConfigCopy; //Copy of the default config from the JAR (file is copied so that admins can easily compare to defaults)
+    private File resourceUserCopy; //File in the /$MCMMO_ROOT/mcMMO/ directory that may contain user edited settings
 
 
-        if (!(getInspectUseChat() || getInspectUseBoard())) {
-            reason.add("Either Board or Print in Scoreboard.Types.Inspect must be true!");
-        }*/
+    /* ROOT NODES */
 
 
-        /* Database Purging */
-        if (getPurgeInterval() < -1) {
-            reason.add("Database_Purging.Purge_Interval should be greater than, or equal to -1!");
-        }
+    private ConfigurationNode userRootNode = null;
+    private ConfigurationNode defaultRootNode = null;
 
 
-        if (getOldUsersCutoff() != -1 && getOldUsersCutoff() <= 0) {
-            reason.add("Database_Purging.Old_User_Cutoff should be greater than 0 or -1!");
-        }
+    /* CONFIG MANAGER */
+    private ConfigurationLoader<CommentedConfigurationNode> configManager;
 
 
-        /* Hardcore Mode */
-        if (getHardcoreDeathStatPenaltyPercentage() < 0.01 || getHardcoreDeathStatPenaltyPercentage() > 100) {
-            reason.add("Hardcore.Death_Stat_Loss.Penalty_Percentage only accepts values from 0.01 to 100!");
-        }
-
-        if (getHardcoreVampirismStatLeechPercentage() < 0.01 || getHardcoreVampirismStatLeechPercentage() > 100) {
-            reason.add("Hardcore.Vampirism.Leech_Percentage only accepts values from 0.01 to 100!");
-        }
-
-        /* Items */
-        if (getChimaeraUseCost() < 1 || getChimaeraUseCost() > 64) {
-            reason.add("Items.Chimaera_Wing.Use_Cost only accepts values from 1 to 64!");
-        }
+    public Config(String pathToParentFolder, String relativePath, boolean mergeNewKeys) {
+        //TODO: Check if this works...
+        this(new File(pathToParentFolder), relativePath, mergeNewKeys);
+        System.out.println("mcMMO Debug: Don't forget to check if loading config file by string instead of File works...");
+    }
 
 
-        if (getChimaeraRecipeCost() < 1 || getChimaeraRecipeCost() > 9) {
-            reason.add("Items.Chimaera_Wing.Recipe_Cost only accepts values from 1 to 9!");
-        }
+    public Config(File pathToParentFolder, String relativePath, boolean mergeNewKeys) {
+        /*
+         * These must be at the top
+         */
+        this.mergeNewKeys = mergeNewKeys; //Whether or not we add new keys when they are found
+        mkdirDefaults(); // Make our default config dir
+        DIRECTORY_DATA_FOLDER = pathToParentFolder; //Data Folder for our plugin
+        FILE_RELATIVE_PATH = relativePath; //Relative path to config from a parent folder
 
 
-        if (getChimaeraItem() == null) {
-            reason.add("Items.Chimaera_Wing.Item_Name is invalid!");
-        }
+        //Attempt IO Operations
+        try {
+            //Makes sure we have valid Files corresponding to this config
+            initConfigFiles();
 
 
-        /* Particles */
-        if (getLevelUpEffectsTier() < 1) {
-            reason.add("Particles.LevelUp_Tier should be at least 1!");
-        }
+            //Init MainConfig Loaders
+            initConfigLoaders();
 
 
-        /* PARTY SETTINGS */
-        if (getAutoPartyKickInterval() < -1) {
-            reason.add("Party.AutoKick_Interval should be at least -1!");
-        }
+            //Load MainConfig Nodes
+            loadConfig();
 
 
-        if (getAutoPartyKickTime() < 0) {
-            reason.add("Party.Old_Party_Member_Cutoff should be at least 0!");
+            //Attempt to update user file, and then load it into memory
+            readConfig();
+        } catch (IOException e) {
+            e.printStackTrace();
         }
         }
 
 
-        if (getPartyShareBonusBase() <= 0) {
-            reason.add("Party.Sharing.ExpShare_bonus_base should be greater than 0!");
-        }
 
 
-        if (getPartyShareBonusIncrease() < 0) {
-            reason.add("Party.Sharing.ExpShare_bonus_increase should be at least 0!");
-        }
+    }
 
 
-        if (getPartyShareBonusCap() <= 0) {
-            reason.add("Party.Sharing.ExpShare_bonus_cap should be greater than 0!");
-        }
+    /**
+     * Initializes the default copy File and the user config File
+     * @throws IOException
+     */
+    private void initConfigFiles() throws IOException {
+        //Init our config copy
+        resourceConfigCopy = initDefaultConfig();
 
 
-        if (getPartyShareRange() <= 0) {
-            reason.add("Party.Sharing.Range should be greater than 0!");
-        }
+        //Init the user file
+        resourceUserCopy = initUserConfig();
+    }
 
 
-        if (getPartyXpCurveMultiplier() < 1) {
-            reason.add("Party.Leveling.Xp_Curve_Modifier should be at least 1!");
-        }
+    /**
+     * Loads the root node for the default config File and user config File
+     */
+    private void loadConfig()
+    {
+        try {
+            final ConfigurationNode defaultConfig = this.defaultCopyLoader.load();
+            defaultRootNode = defaultConfig;
 
 
-        for (PartyFeature partyFeature : PartyFeature.values()) {
-            if (getPartyFeatureUnlockLevel(partyFeature) < 0) {
-                reason.add("Party.Leveling." + StringUtils.getPrettyPartyFeatureString(partyFeature).replace(" ", "") + "_UnlockLevel should be at least 0!");
-            }
-        }
+            final ConfigurationNode userConfig = this.userCopyLoader.load();
+            userRootNode = userConfig;
 
 
-        /* Inspect command distance */
-        if (getInspectDistance() <= 0) {
-            reason.add("Commands.inspect.Max_Distance should be greater than 0!");
+        } catch (IOException e) {
+            e.printStackTrace();
         }
         }
+    }
 
 
-        if (getTreeFellerThreshold() <= 0) {
-            reason.add("Abilities.Limits.Tree_Feller_Threshold should be greater than 0!");
-        }
+    /**
+     * Initializes the YAMLConfigurationLoaders for this config
+     */
+    private void initConfigLoaders()
+    {
+        this.defaultCopyLoader = YAMLConfigurationLoader.builder().setPath(resourceConfigCopy.toPath()).setFlowStyle(DumperOptions.FlowStyle.BLOCK).build();
+        this.userCopyLoader = YAMLConfigurationLoader.builder().setPath(resourceUserCopy.toPath()).setFlowStyle(DumperOptions.FlowStyle.FLOW).build();
+    }
 
 
-        if (getFishingLureModifier() < 0) {
-            reason.add("Abilities.Fishing.Lure_Modifier should be at least 0!");
-        }
+    /**
+     * Copies a new file from the JAR to the defaults directory and uses that new file to initialize our resourceConfigCopy
+     * @see Config#resourceConfigCopy
+     * @throws IOException
+     */
+    private File initDefaultConfig() throws IOException {
+        return copyDefaultFromJar(getDefaultConfigCopyRelativePath(), true);
+    }
 
 
-        if (getDetonatorItem() == null) {
-            reason.add("Skills.Mining.Detonator_Item is invalid!");
-        }
+    /**
+     * Attemps to load the config file if it exists, if it doesn't it copies a new one from within the JAR
+     * @return user config File
+     * @see Config#resourceUserCopy
+     * @throws IOException
+     */
+    private File initUserConfig() throws IOException {
+        File userCopy = new File(DIRECTORY_DATA_FOLDER, FILE_RELATIVE_PATH); //Load the user file;
 
 
-        if (getRepairAnvilMaterial() == null) {
-            reason.add("Skills.Repair.Anvil_Type is invalid!!");
+        if(userCopy.exists())
+        {
+            // Yay
+            return userCopy;
         }
         }
-
-        if (getSalvageAnvilMaterial() == null) {
-            reason.add("Skills.Repair.Salvage_Anvil_Type is invalid!");
+        else
+        {
+            //If it's gone we copy default files
+            //Note that we don't copy the values from the default copy put in /defaults/ that file exists only as a reference to admins and is unreliable
+            return copyDefaultFromJar(FILE_RELATIVE_PATH, false);
         }
         }
+    }
 
 
-        if (getRepairAnvilMaterial() == getSalvageAnvilMaterial()) {
-            reason.add("Cannot use the same item for Repair and Salvage anvils!");
-        }
+    /**
+     * Used to make a new config file at a specified relative output path inside the data directory by copying the matching file found in that same relative path within the JAR
+     * @param relativeOutputPath the path to the output file
+     * @param deleteOld whether or not to delete the existing output file on disk
+     * @return a copy of the default config within the JAR
+     * @throws IOException
+     */
+    private File copyDefaultFromJar(String relativeOutputPath, boolean deleteOld) throws IOException
+    {
+        /*
+         * Gen a Default config from inside the JAR
+         */
+        McmmoCore.getLogger().info("Preparing to copy internal resource file (in JAR) - "+FILE_RELATIVE_PATH);
+        InputStream inputStream = McmmoCore.getResource(FILE_RELATIVE_PATH);
 
 
-        if (getTamingCOTWMaterial(EntityType.WOLF) == null) {
-            reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Item_Material is invalid!!");
-        }
+        byte[] buffer = new byte[inputStream.available()];
+        inputStream.read(buffer);
 
 
-        if (getTamingCOTWMaterial(EntityType.OCELOT) == null) {
-            reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Item_Material is invalid!!");
-        }
+        //This is a copy of the default file, which we will overwrite every time mcMMO loads
+        File targetFile = new File(DIRECTORY_DATA_FOLDER, relativeOutputPath);
 
 
-        if (getTamingCOTWMaterial(EntityType.HORSE) == null) {
-            reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Item_Material is invalid!!");
+        //Wipe old default file on disk
+        if (targetFile.exists() && deleteOld)
+        {
+            McmmoCore.getLogger().info("Updating file " + relativeOutputPath);
+            targetFile.delete(); //Necessary?
         }
         }
 
 
-        if (getTamingCOTWCost(EntityType.WOLF) <= 0) {
-            reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Item_Amount should be greater than 0!");
+        if(!targetFile.exists())
+        {
+            targetFile.getParentFile().mkdirs();
+            targetFile.createNewFile(); //New File Boys
         }
         }
 
 
-        if (getTamingCOTWCost(EntityType.OCELOT) <= 0) {
-            reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Item_Amount should be greater than 0!");
-        }
+        Files.write(buffer, targetFile);
+        McmmoCore.getLogger().info("Created config file - " + relativeOutputPath);
 
 
-        if (getTamingCOTWCost(EntityType.HORSE) <= 0) {
-            reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Item_Amount should be greater than 0!");
-        }
+        inputStream.close(); //Close the input stream
 
 
-        if (getTamingCOTWAmount(EntityType.WOLF) <= 0) {
-            reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Summon_Amount should be greater than 0!");
-        }
+        return targetFile;
+    }
 
 
-        if (getTamingCOTWAmount(EntityType.OCELOT) <= 0) {
-            reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Summon_Amount should be greater than 0!");
-        }
+    /**
+     * The path to the defaults directory
+     * @return the path to the defaults directory
+     */
+    private String getDefaultConfigCopyRelativePath() {
+        return DIRECTORY_DEFAULTS + File.separator + FILE_RELATIVE_PATH;
+    }
 
 
-        if (getTamingCOTWAmount(EntityType.HORSE) <= 0) {
-            reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Summon_Amount should be greater than 0!");
-        }
+    /**
+     * Creates the defaults directory
+     */
+    private void mkdirDefaults() {
+        //Make Default Subdirectory
+        File defaultsDir = new File (DIRECTORY_DATA_FOLDER, "defaults");
 
 
-        return noErrorsInConfig(reason);
+        if(!defaultsDir.exists())
+            defaultsDir.mkdir();
     }
     }
 
 
-    /*
-     * GENERAL SETTINGS
+    /**
+     * Configs are versioned based on when they had significant changes to keys
+     * @return current MainConfig Version String
      */
      */
+    public String getVersion()
+    {
+         return String.valueOf(getConfigVersion());
+    }
 
 
-    /* General Settings */
-    public boolean getIsMetricsEnabled() { return config.getBoolean("Metrics.bstats", true); }
-
-    //Retro mode will default the value to true if the config file doesn't contain the entry (server is from a previous mcMMO install)
-    public boolean getIsRetroMode() { return config.getBoolean("General.RetroMode.Enabled", true); }
+    /**
+     * Attempts to read the loaded config file
+     * MainConfig will have any necessary updates applied
+     * MainConfig will be compared to the default config to see if it is missing any nodes
+     * MainConfig will have any missing nodes inserted with their default value
+     */
+    public void readConfig() {
+        McmmoCore.getLogger().info("Attempting to read " + FILE_RELATIVE_PATH + ".");
 
 
-    public String getLocale() { return config.getString("General.Locale", "en_us"); }
-    public boolean getMOTDEnabled() { return config.getBoolean("General.MOTD_Enabled", true); }
-    public boolean getShowProfileLoadedMessage() { return config.getBoolean("General.Show_Profile_Loaded", true); }
-    public boolean getDonateMessageEnabled() { return config.getBoolean("Commands.mcmmo.Donate_Message", true); }
-    public int getSaveInterval() { return config.getInt("General.Save_Interval", 10); }
-    public boolean getStatsTrackingEnabled() { return config.getBoolean("General.Stats_Tracking", true); }
-    public boolean getUpdateCheckEnabled() { return config.getBoolean("General.Update_Check", true); }
-    public boolean getPreferBeta() { return config.getBoolean("General.Prefer_Beta", false); }
-    public boolean getVerboseLoggingEnabled() { return config.getBoolean("General.Verbose_Logging", false); }
+        int version = this.userRootNode.getNode("ConfigVersion").getInt();
+        McmmoCore.getLogger().info(FILE_RELATIVE_PATH + " version is " + version);
 
 
-    public String getPartyChatPrefix() { return config.getString("Commands.partychat.Chat_Prefix_Format", "[[GREEN]]([[WHITE]]{0}[[GREEN]])"); }
-    public boolean getPartyChatColorLeaderName() { return config.getBoolean("Commands.partychat.Gold_Leader_Name", true); }
-    public boolean getPartyDisplayNames() { return config.getBoolean("Commands.partychat.Use_Display_Names", true); }
-    public String getPartyChatPrefixAlly() { return config.getString("Commands.partychat.Chat_Prefix_Format_Ally", "[[GREEN]](A)[[RESET]]"); }
+        //Update our config
+        updateConfig();
+    }
 
 
-    public String getAdminChatPrefix() { return config.getString("Commands.adminchat.Chat_Prefix_Format", "[[AQUA]][[[WHITE]]{0}[[AQUA]]]"); }
-    public boolean getAdminDisplayNames() { return config.getBoolean("Commands.adminchat.Use_Display_Names", true); }
+    /**
+     * Compares the users config file to the default and adds any missing nodes and applies any necessary updates
+     */
+    private void updateConfig()
+    {
+        McmmoCore.getLogger().info(defaultRootNode.getChildrenMap().size() +" items in default children map");
+        McmmoCore.getLogger().info(userRootNode.getChildrenMap().size() +" items in default root map");
 
 
-    public boolean getMatchOfflinePlayers() { return config.getBoolean("Commands.Generic.Match_OfflinePlayers", false); }
-    public long getDatabasePlayerCooldown() { return config.getLong("Commands.Database.Player_Cooldown", 1750); }
+        // Merge Values from default
+        if(mergeNewKeys)
+            userRootNode = userRootNode.mergeValuesFrom(defaultRootNode);
 
 
-    public boolean getLevelUpSoundsEnabled() { return config.getBoolean("General.LevelUp_Sounds", true); }
-    public boolean getRefreshChunksEnabled() { return config.getBoolean("General.Refresh_Chunks", false); }
+        removeOldKeys();
 
 
-    public boolean getMobHealthbarEnabled() { return config.getBoolean("Mob_Healthbar.Enabled", true); }
+        // Update config version
+        updateConfigVersion();
 
 
-    /* Mob Healthbar */
-    public MobHealthbarType getMobHealthbarDefault() {
+        //Attempt to save
         try {
         try {
-            return MobHealthbarType.valueOf(config.getString("Mob_Healthbar.Display_Type", "HEARTS").toUpperCase().trim());
-        }
-        catch (IllegalArgumentException ex) {
-            return MobHealthbarType.HEARTS;
+            saveUserCopy();
+        } catch (IOException e) {
+            e.printStackTrace();
         }
         }
     }
     }
 
 
-    public int getMobHealthbarTime() { return config.getInt("Mob_Healthbar.Display_Time", 3); }
-
-    /* Scoreboards */
-    public boolean getScoreboardsEnabled() { return config.getBoolean("Scoreboard.UseScoreboards", true); }
-    public boolean getPowerLevelTagsEnabled() { return config.getBoolean("Scoreboard.Power_Level_Tags", false); }
-    public boolean getAllowKeepBoard() { return config.getBoolean("Scoreboard.Allow_Keep", true); }
-    public int getTipsAmount() { return config.getInt("Scoreboard.Tips_Amount", 5); }
-    public boolean getShowStatsAfterLogin() { return config.getBoolean("Scoreboard.Show_Stats_After_Login", false); }
-    public boolean getScoreboardRainbows() { return config.getBoolean("Scoreboard.Rainbows", false); }
-    public boolean getShowAbilityNames() { return config.getBoolean("Scoreboard.Ability_Names", true); }
-
-    public boolean getRankUseChat() { return config.getBoolean("Scoreboard.Types.Rank.Print", false); }
-    public boolean getRankUseBoard() { return config.getBoolean("Scoreboard.Types.Rank.Board", true); }
-    public int getRankScoreboardTime() { return config.getInt("Scoreboard.Types.Rank.Display_Time", 10); }
-
-    public boolean getTopUseChat() { return config.getBoolean("Scoreboard.Types.Top.Print", true); }
-    public boolean getTopUseBoard() { return config.getBoolean("Scoreboard.Types.Top.Board", true); }
-    public int getTopScoreboardTime() { return config.getInt("Scoreboard.Types.Top.Display_Time", 15); }
-
-    public boolean getStatsUseChat() { return config.getBoolean("Scoreboard.Types.Stats.Print", true); }
-    public boolean getStatsUseBoard() { return config.getBoolean("Scoreboard.Types.Stats.Board", true); }
-    public int getStatsScoreboardTime() { return config.getInt("Scoreboard.Types.Stats.Display_Time", 10); }
-
-    public boolean getInspectUseChat() { return config.getBoolean("Scoreboard.Types.Inspect.Print", true); }
-    public boolean getInspectUseBoard() { return config.getBoolean("Scoreboard.Types.Inspect.Board", true); }
-    public int getInspectScoreboardTime() { return config.getInt("Scoreboard.Types.Inspect.Display_Time", 25); }
-
-    public boolean getCooldownUseChat() { return config.getBoolean("Scoreboard.Types.Cooldown.Print", false); }
-    public boolean getCooldownUseBoard() { return config.getBoolean("Scoreboard.Types.Cooldown.Board", true); }
-    public int getCooldownScoreboardTime() { return config.getInt("Scoreboard.Types.Cooldown.Display_Time", 41); }
-
-    public boolean getSkillUseBoard() { return config.getBoolean("Scoreboard.Types.Skill.Board", true); }
-    public int getSkillScoreboardTime() { return config.getInt("Scoreboard.Types.Skill.Display_Time", 30); }
-    public boolean getSkillLevelUpBoard() { return config.getBoolean("Scoreboard.Types.Skill.LevelUp_Board", true); }
-    public int getSkillLevelUpTime() { return config.getInt("Scoreboard.Types.Skill.LevelUp_Time", 5); }
-
-    /* Database Purging */
-    public int getPurgeInterval() { return config.getInt("Database_Purging.Purge_Interval", -1); }
-    public int getOldUsersCutoff() { return config.getInt("Database_Purging.Old_User_Cutoff", 6); }
-
-    /* Backups */
-    public boolean getBackupsEnabled() { return config.getBoolean("Backups.Enabled", true); }
-    public boolean getKeepLast24Hours() { return config.getBoolean("Backups.Keep.Last_24_Hours", true); }
-    public boolean getKeepDailyLastWeek() { return config.getBoolean("Backups.Keep.Daily_Last_Week", true); }
-    public boolean getKeepWeeklyPastMonth() { return config.getBoolean("Backups.Keep.Weekly_Past_Months", true); }
-
-    /* mySQL */
-    public boolean getUseMySQL() { return config.getBoolean("MySQL.Enabled", false); }
-    public String getMySQLTablePrefix() { return config.getString("MySQL.Database.TablePrefix", "mcmmo_"); }
-    public String getMySQLDatabaseName() { return getStringIncludingInts("MySQL.Database.Name"); }
-    public String getMySQLUserName() { return getStringIncludingInts("MySQL.Database.User_Name"); }
-    public int getMySQLServerPort() { return config.getInt("MySQL.Server.Port", 3306); }
-    public String getMySQLServerName() { return config.getString("MySQL.Server.Address", "localhost"); }
-    public String getMySQLUserPassword() { return getStringIncludingInts("MySQL.Database.User_Password"); }
-    public int getMySQLMaxConnections(PoolIdentifier identifier) { return config.getInt("MySQL.Database.MaxConnections." + StringUtils.getCapitalized(identifier.toString()), 30); }
-    public int getMySQLMaxPoolSize(PoolIdentifier identifier) { return config.getInt("MySQL.Database.MaxPoolSize." + StringUtils.getCapitalized(identifier.toString()), 10); }
-    public boolean getMySQLSSL() { return config.getBoolean("MySQL.Server.SSL", true); }
-
-    private String getStringIncludingInts(String key) {
-        String str = config.getString(key);
-
-        if (str == null) {
-            str = String.valueOf(config.getInt(key));
-        }
-
-        if (str.equals("0")) {
-            str = "No value set for '" + key + "'";
-        }
-        return str;
+    /**
+     * Saves the current state information of the config to the users copy (which they may edit)
+     * @throws IOException
+     */
+    private void saveUserCopy() throws IOException
+    {
+        McmmoCore.getLogger().info("Saving new node");
+        userCopyLoader.save(userRootNode);
     }
     }
 
 
-    /* Hardcore Mode */
-    public boolean getHardcoreStatLossEnabled(PrimarySkillType primarySkillType) { return config.getBoolean("Hardcore.Death_Stat_Loss.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), false); }
-    public void setHardcoreStatLossEnabled(PrimarySkillType primarySkillType, boolean enabled) { config.set("Hardcore.Death_Stat_Loss.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), enabled); }
-
-    public double getHardcoreDeathStatPenaltyPercentage() { return config.getDouble("Hardcore.Death_Stat_Loss.Penalty_Percentage", 75.0D); }
-    public void setHardcoreDeathStatPenaltyPercentage(double value) { config.set("Hardcore.Death_Stat_Loss.Penalty_Percentage", value); }
-
-    public int getHardcoreDeathStatPenaltyLevelThreshold() { return config.getInt("Hardcore.Death_Stat_Loss.Level_Threshold", 0); }
-
-    public boolean getHardcoreVampirismEnabled(PrimarySkillType primarySkillType) { return config.getBoolean("Hardcore.Vampirism.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), false); }
-    public void setHardcoreVampirismEnabled(PrimarySkillType primarySkillType, boolean enabled) { config.set("Hardcore.Vampirism.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), enabled); }
-
-    public double getHardcoreVampirismStatLeechPercentage() { return config.getDouble("Hardcore.Vampirism.Leech_Percentage", 5.0D); }
-    public void setHardcoreVampirismStatLeechPercentage(double value) { config.set("Hardcore.Vampirism.Leech_Percentage", value); }
-
-    public int getHardcoreVampirismLevelThreshold() { return config.getInt("Hardcore.Vampirism.Level_Threshold", 0); }
-
-    /* SMP Mods */
-    public boolean getToolModsEnabled() { return config.getBoolean("Mods.Tool_Mods_Enabled", false); }
-    public boolean getArmorModsEnabled() { return config.getBoolean("Mods.Armor_Mods_Enabled", false); }
-    public boolean getBlockModsEnabled() { return config.getBoolean("Mods.Block_Mods_Enabled", false); }
-    public boolean getEntityModsEnabled() { return config.getBoolean("Mods.Entity_Mods_Enabled", false); }
-
-    /* Items */
-    public int getChimaeraUseCost() { return config.getInt("Items.Chimaera_Wing.Use_Cost", 1); }
-    public int getChimaeraRecipeCost() { return config.getInt("Items.Chimaera_Wing.Recipe_Cost", 5); }
-    public Material getChimaeraItem() { return Material.matchMaterial(config.getString("Items.Chimaera_Wing.Item_Name", "Feather")); }
-    public boolean getChimaeraEnabled() { return config.getBoolean("Items.Chimaera_Wing.Enabled", true); }
-    public boolean getChimaeraPreventUseUnderground() { return config.getBoolean("Items.Chimaera_Wing.Prevent_Use_Underground", true); }
-    public boolean getChimaeraUseBedSpawn() { return config.getBoolean("Items.Chimaera_Wing.Use_Bed_Spawn", true); }
-    public int getChimaeraCooldown() { return config.getInt("Items.Chimaera_Wing.Cooldown", 240); }
-    public int getChimaeraWarmup() { return config.getInt("Items.Chimaera_Wing.Warmup", 5); }
-    public int getChimaeraRecentlyHurtCooldown() { return config.getInt("Items.Chimaera_Wing.RecentlyHurt_Cooldown", 60); }
-    public boolean getChimaeraSoundEnabled() { return config.getBoolean("Items.Chimaera_Wing.Sound_Enabled", true); }
-
-    public boolean getFluxPickaxeSoundEnabled() { return config.getBoolean("Items.Flux_Pickaxe.Sound_Enabled", true); }
-
-    /* Particles */
-    public boolean getAbilityActivationEffectEnabled() { return config.getBoolean("Particles.Ability_Activation", true); }
-    public boolean getAbilityDeactivationEffectEnabled() { return config.getBoolean("Particles.Ability_Deactivation", true); }
-    public boolean getBleedEffectEnabled() { return config.getBoolean("Particles.Bleed", true); }
-    public boolean getDodgeEffectEnabled() { return config.getBoolean("Particles.Dodge", true); }
-    public boolean getFluxEffectEnabled() { return config.getBoolean("Particles.Flux", true); }
-    public boolean getGreaterImpactEffectEnabled() { return config.getBoolean("Particles.Greater_Impact", true); }
-    public boolean getCallOfTheWildEffectEnabled() { return config.getBoolean("Particles.Call_of_the_Wild", true); }
-    public boolean getLevelUpEffectsEnabled() { return config.getBoolean("Particles.LevelUp_Enabled", true); }
-    public int getLevelUpEffectsTier() { return config.getInt("Particles.LevelUp_Tier", 100); }
-    public boolean getLargeFireworks() { return config.getBoolean("Particles.LargeFireworks", true); }
-
-    /* PARTY SETTINGS */
-    public boolean getPartyFriendlyFire() { return config.getBoolean("Party.FriendlyFire", false);}
-    public int getPartyMaxSize() {return config.getInt("Party.MaxSize", -1); }
-    public int getAutoPartyKickInterval() { return config.getInt("Party.AutoKick_Interval", 12); }
-    public int getAutoPartyKickTime() { return config.getInt("Party.Old_Party_Member_Cutoff", 7); }
-
-    public double getPartyShareBonusBase() { return config.getDouble("Party.Sharing.ExpShare_bonus_base", 1.1D); }
-    public double getPartyShareBonusIncrease() { return config.getDouble("Party.Sharing.ExpShare_bonus_increase", 0.05D); }
-    public double getPartyShareBonusCap() { return config.getDouble("Party.Sharing.ExpShare_bonus_cap", 1.5D); }
-    public double getPartyShareRange() { return config.getDouble("Party.Sharing.Range", 75.0D); }
-
-    public int getPartyLevelCap() {
-        int cap = config.getInt("Party.Leveling.Level_Cap", 10);
-        return (cap <= 0) ? Integer.MAX_VALUE : cap;
+    /**
+     * Performs any necessary operations to update this config
+     */
+    private void updateConfigVersion() {
+        // Set a version for our config
+        this.userRootNode.getNode("ConfigVersion").setValue(getConfigVersion());
+        McmmoCore.getLogger().info("Updated config to ["+getConfigVersion()+"] - " + FILE_RELATIVE_PATH);
     }
     }
 
 
-    public int getPartyXpCurveMultiplier() { return config.getInt("Party.Leveling.Xp_Curve_Modifier", 3); }
-    public boolean getPartyXpNearMembersNeeded() { return config.getBoolean("Party.Leveling.Near_Members_Needed", false); }
-    public boolean getPartyInformAllMembers() { return config.getBoolean("Party.Leveling.Inform_All_Party_Members_On_LevelUp", false); }
-
-    public int getPartyFeatureUnlockLevel(PartyFeature partyFeature) { return config.getInt("Party.Leveling." + StringUtils.getPrettyPartyFeatureString(partyFeature).replace(" ", "") + "_UnlockLevel", 0); }
-
-    /* Party Teleport Settings */
-    public int getPTPCommandCooldown() { return config.getInt("Commands.ptp.Cooldown", 120); }
-    public int getPTPCommandWarmup() { return config.getInt("Commands.ptp.Warmup", 5); }
-    public int getPTPCommandRecentlyHurtCooldown() { return config.getInt("Commands.ptp.RecentlyHurt_Cooldown", 60); }
-    public int getPTPCommandTimeout() { return config.getInt("Commands.ptp.Request_Timeout", 300); }
-    public boolean getPTPCommandConfirmRequired() { return config.getBoolean("Commands.ptp.Accept_Required", true); }
-    public boolean getPTPCommandWorldPermissions() { return config.getBoolean("Commands.ptp.World_Based_Permissions", false); }
-
-    /* Inspect command distance */
-    public double getInspectDistance() { return config.getDouble("Commands.inspect.Max_Distance", 30.0D); }
-
-    /*
-     * ABILITY SETTINGS
+    /**
+     * Returns the root node of this config
+     * @return the root node of this config
      */
      */
+    protected ConfigurationNode getUserRootNode() {
+        return userRootNode;
+    }
 
 
-    /* General Settings */
-    public boolean getUrlLinksEnabled() { return config.getBoolean("Commands.Skills.URL_Links"); }
-    public boolean getAbilityMessagesEnabled() { return config.getBoolean("Abilities.Messages", true); }
-    public boolean getAbilitiesEnabled() { return config.getBoolean("Abilities.Enabled", true); }
-    public boolean getAbilitiesOnlyActivateWhenSneaking() { return config.getBoolean("Abilities.Activation.Only_Activate_When_Sneaking", false); }
-    public boolean getAbilitiesGateEnabled() { return config.getBoolean("Abilities.Activation.Level_Gate_Abilities"); }
-
-    public int getCooldown(SuperAbilityType ability) { return config.getInt("Abilities.Cooldowns." + ability.toString()); }
-    public int getMaxLength(SuperAbilityType ability) { return config.getInt("Abilities.Max_Seconds." + ability.toString()); }
-
-    /* Durability Settings */
-    public int getAbilityToolDamage() { return config.getInt("Abilities.Tools.Durability_Loss", 1); }
-
-    /* Thresholds */
-    public int getTreeFellerThreshold() { return config.getInt("Abilities.Limits.Tree_Feller_Threshold", 500); }
-
-    /*
-     * SKILL SETTINGS
+    /**
+     * Grabs an int from the specified node
+     * @param path
+     * @return the int from the node, null references will zero initialize
      */
      */
-    public boolean getDoubleDropsEnabled(PrimarySkillType skill, Material material) { return config.getBoolean("Double_Drops." + StringUtils.getCapitalized(skill.toString()) + "." + StringUtils.getPrettyItemString(material).replace(" ", "_")); }
-
-    public boolean getDoubleDropsDisabled(PrimarySkillType skill) {
-        String skillName = StringUtils.getCapitalized(skill.toString());
-        ConfigurationSection section = config.getConfigurationSection("Double_Drops." + skillName);
-        if (section == null)
-            return false;
-        Set<String> keys = section.getKeys(false);
-        boolean disabled = true;
-
-        for (String key : keys) {
-            if (config.getBoolean("Double_Drops." + skillName + "." + key)) {
-                disabled = false;
-                break;
-            }
-        }
-
-        return disabled;
+    public int getIntValue(String... path)
+    {
+        return userRootNode.getNode(path).getInt();
     }
     }
 
 
-    /* Axes */
-    public int getAxesGate() { return config.getInt("Skills.Axes.Ability_Activation_Level_Gate", 10); }
-
-    /* Acrobatics */
-    public boolean getDodgeLightningDisabled() { return config.getBoolean("Skills.Acrobatics.Prevent_Dodge_Lightning", false); }
-    public int getXPAfterTeleportCooldown() { return config.getInt("Skills.Acrobatics.XP_After_Teleport_Cooldown", 5); }
-
-    /* Alchemy */
-    public boolean getEnabledForHoppers() { return config.getBoolean("Skills.Alchemy.Enabled_for_Hoppers", true); }
-    public boolean getPreventHopperTransferIngredients() { return config.getBoolean("Skills.Alchemy.Prevent_Hopper_Transfer_Ingredients", false); }
-    public boolean getPreventHopperTransferBottles() { return config.getBoolean("Skills.Alchemy.Prevent_Hopper_Transfer_Bottles", false); }
-
-    /* Fishing */
-    public boolean getFishingDropsEnabled() { return config.getBoolean("Skills.Fishing.Drops_Enabled", true); }
-    public boolean getFishingOverrideTreasures() { return config.getBoolean("Skills.Fishing.Override_Vanilla_Treasures", true); }
-    public boolean getFishingExtraFish() { return config.getBoolean("Skills.Fishing.Extra_Fish", true); }
-    public double getFishingLureModifier() { return config.getDouble("Skills.Fishing.Lure_Modifier", 4.0D); }
-
-    /* Mining */
-    public Material getDetonatorItem() { return Material.matchMaterial(config.getString("Skills.Mining.Detonator_Name", "FLINT_AND_STEEL")); }
-    public int getMiningGate() { return config.getInt("Skills.Mining.Ability_Activation_Level_Gate", 10); }
-
-    /* Excavation */
-    public int getExcavationGate() { return config.getInt("Skills.Excavation.Ability_Activation_Level_Gate", 10); }
-
-    /* Repair */
-    public boolean getRepairAnvilMessagesEnabled() { return config.getBoolean("Skills.Repair.Anvil_Messages", true); }
-    public boolean getRepairAnvilPlaceSoundsEnabled() { return config.getBoolean("Skills.Repair.Anvil_Placed_Sounds", true); }
-    public boolean getRepairAnvilUseSoundsEnabled() { return config.getBoolean("Skills.Repair.Anvil_Use_Sounds", true); }
-    public Material getRepairAnvilMaterial() { return Material.matchMaterial(config.getString("Skills.Repair.Anvil_Material", "IRON_BLOCK")); }
-    public boolean getRepairConfirmRequired() { return config.getBoolean("Skills.Repair.Confirm_Required", true); }
-
-    /* Salvage */
-    public boolean getSalvageAnvilMessagesEnabled() { return config.getBoolean("Skills.Salvage.Anvil_Messages", true); }
-    public boolean getSalvageAnvilPlaceSoundsEnabled() { return config.getBoolean("Skills.Salvage.Anvil_Placed_Sounds", true); }
-    public boolean getSalvageAnvilUseSoundsEnabled() { return config.getBoolean("Skills.Salvage.Anvil_Use_Sounds", true); }
-    public Material getSalvageAnvilMaterial() { return Material.matchMaterial(config.getString("Skills.Salvage.Anvil_Material", "GOLD_BLOCK")); }
-    public boolean getSalvageConfirmRequired() { return config.getBoolean("Skills.Salvage.Confirm_Required", true); }
-
-    /* Unarmed */
-    public boolean getUnarmedBlockCrackerSmoothbrickToCracked() { return config.getBoolean("Skills.Unarmed.Block_Cracker.SmoothBrick_To_CrackedBrick", true); }
-    public boolean getUnarmedItemPickupDisabled() { return config.getBoolean("Skills.Unarmed.Item_Pickup_Disabled_Full_Inventory", true); }
-    public boolean getUnarmedItemsAsUnarmed() { return config.getBoolean("Skills.Unarmed.Items_As_Unarmed", false); }
-    public int getUnarmedGate() { return config.getInt("Skills.Unarmed.Ability_Activation_Level_Gate", 10); }
-
-    /* Swords */
-    public int getSwordsGate() { return config.getInt("Skills.Swords.Ability_Activation_Level_Gate", 10); }
-
-    /* Taming */
-    public Material getTamingCOTWMaterial(EntityType type) { return Material.matchMaterial(config.getString("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Material")); }
-    public int getTamingCOTWCost(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Amount"); }
-    public int getTamingCOTWAmount(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Summon_Amount"); }
-    public int getTamingCOTWLength(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type)+ ".Summon_Length"); }
-    public int getTamingCOTWMaxAmount(EntityType type) { return config.getInt("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type)+ ".Summon_Max_Amount"); }
-    public double getTamingCOTWRange() { return config.getDouble("Skills.Taming.Call_Of_The_Wild.Range", 40.0D); }
-
-    /* Woodcutting */
-    public boolean getWoodcuttingDoubleDropsEnabled(BlockData material) { return config.getBoolean("Double_Drops.Woodcutting." + StringUtils.getFriendlyConfigBlockDataString(material)); }
-    public boolean getTreeFellerSoundsEnabled() { return config.getBoolean("Skills.Woodcutting.Tree_Feller_Sounds", true); }
-    public int getWoodcuttingGate() { return config.getInt("Skills.Woodcutting.Ability_Activation_Level_Gate", 10); }
-
-    /* AFK Leveling */
-    public boolean getAcrobaticsPreventAFK() { return config.getBoolean("Skills.Acrobatics.Prevent_AFK_Leveling", true); }
-    public int getAcrobaticsAFKMaxTries() { return config.getInt("Skills.Acrobatics.Max_Tries_At_Same_Location", 3); }
-    public boolean getHerbalismPreventAFK() { return config.getBoolean("Skills.Herbalism.Prevent_AFK_Leveling", true); }
-
-    /* Level Caps */
-    public int getPowerLevelCap() {
-        int cap = config.getInt("General.Power_Level_Cap", 0);
-        return (cap <= 0) ? Integer.MAX_VALUE : cap;
+    /**
+     * Grabs a double from the specified node
+     * @param path
+     * @return the double from the node, null references will zero initialize
+     */
+    public double getDoubleValue(String... path)
+    {
+        return userRootNode.getNode(path).getDouble();
     }
     }
 
 
-    public int getLevelCap(PrimarySkillType skill) {
-        int cap = config.getInt("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Level_Cap");
-        return (cap <= 0) ? Integer.MAX_VALUE : cap;
+    /**
+     * Grabs a boolean from the specified node
+     * @param path
+     * @return the boolean from the node, null references will zero initialize
+     */
+    public boolean getBooleanValue(String... path)
+    {
+        return userRootNode.getNode(path).getBoolean();
     }
     }
 
 
+    /**
+     * Grabs a string from the specified node
+     * @param path
+     * @return the string from the node, null references will zero initialize
+     */
+    public String getStringValue(String... path)
+    {
+        return userRootNode.getNode(path).getString();
+    }
 
 
-    /*public int isSuperAbilityUnlocked(PrimarySkillType skill) {
-        return config.getInt("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Ability_Activation_Level_Gate");
-    }*/
-
-    public boolean getTruncateSkills() { return config.getBoolean("General.TruncateSkills", false); }
-
-    /* PVP & PVE Settings */
-    public boolean getPVPEnabled(PrimarySkillType skill) { return config.getBoolean("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Enabled_For_PVP", true); }
-    public boolean getPVEEnabled(PrimarySkillType skill) { return config.getBoolean("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Enabled_For_PVE", true); }
-    
-    //public float getMasterVolume() { return (float) config.getDouble("Sounds.MasterVolume", 1.0); }
+    /**
+     * Checks to see if a node exists in the user's config file
+     * @param path path to the node
+     * @return true if the node exists
+     */
+    public boolean hasNode(String... path) {
+        return (userRootNode.getNode(path) != null);
+    }
 }
 }

+ 7 - 0
src/main/java/com/gmail/nossr50/config/ConfigCollection.java

@@ -0,0 +1,7 @@
+package com.gmail.nossr50.config;
+
+import java.util.Collection;
+
+public interface ConfigCollection<T> {
+    Collection<T> getLoadedCollection();
+}

+ 19 - 0
src/main/java/com/gmail/nossr50/config/ConfigCollections.java

@@ -0,0 +1,19 @@
+package com.gmail.nossr50.config;
+
+import java.io.File;
+
+/**
+ * Represents a config file that registers keys after its initialized
+ */
+public abstract class ConfigCollections extends Config implements RegistersKeys, ConfigCollection {
+
+    public ConfigCollections(String pathToParentFolder, String relativePath, boolean mergeNewKeys) {
+        super(pathToParentFolder, relativePath, mergeNewKeys);
+        loadKeys();
+    }
+
+    public ConfigCollections(File pathToParentFolder, String relativePath, boolean mergeNewKeys) {
+        super(pathToParentFolder, relativePath, mergeNewKeys);
+        loadKeys();
+    }
+}

+ 0 - 89
src/main/java/com/gmail/nossr50/config/ConfigLoader.java

@@ -1,89 +0,0 @@
-package com.gmail.nossr50.config;
-
-import com.gmail.nossr50.mcMMO;
-import org.bukkit.configuration.file.FileConfiguration;
-import org.bukkit.configuration.file.YamlConfiguration;
-
-import java.io.File;
-import java.util.List;
-
-public abstract class ConfigLoader {
-    protected static final mcMMO plugin = mcMMO.p;
-    protected String fileName;
-    private File configFile;
-    protected FileConfiguration config;
-
-    public ConfigLoader(String relativePath, String fileName) {
-        this.fileName = fileName;
-        configFile = new File(plugin.getDataFolder(), relativePath + File.separator + fileName);
-        loadFile();
-    }
-
-    public ConfigLoader(String fileName) {
-        this.fileName = fileName;
-        configFile = new File(plugin.getDataFolder(), fileName);
-        loadFile();
-    }
-
-    protected void loadFile() {
-        if (!configFile.exists()) {
-            plugin.debug("Creating mcMMO " + fileName + " File...");
-
-            try {
-                plugin.saveResource(fileName, false); // Normal files
-            }
-            catch (IllegalArgumentException ex) {
-                plugin.saveResource(configFile.getParentFile().getName() + File.separator + fileName, false); // Mod files
-            }
-        }
-        else {
-            plugin.debug("Loading mcMMO " + fileName + " File...");
-        }
-
-        config = YamlConfiguration.loadConfiguration(configFile);
-    }
-
-    protected abstract void loadKeys();
-
-    protected boolean validateKeys() {
-        return true;
-    }
-
-    protected boolean noErrorsInConfig(List<String> issues) {
-        for (String issue : issues) {
-            plugin.getLogger().warning(issue);
-        }
-
-        return issues.isEmpty();
-    }
-
-    protected void validate() {
-        if (validateKeys()) {
-            plugin.debug("No errors found in " + fileName + "!");
-        }
-        else {
-            plugin.getLogger().warning("Errors were found in " + fileName + "! mcMMO was disabled!");
-            plugin.getServer().getPluginManager().disablePlugin(plugin);
-            plugin.noErrorsInConfigFiles = false;
-        }
-    }
-
-    public File getFile() {
-        return configFile;
-    }
-
-    public void backup() {
-        plugin.getLogger().warning("You are using an old version of the " + fileName + " file.");
-        plugin.getLogger().warning("Your old file has been renamed to " + fileName + ".old and has been replaced by an updated version.");
-
-        configFile.renameTo(new File(configFile.getPath() + ".old"));
-
-        if (plugin.getResource(fileName) != null) {
-            plugin.saveResource(fileName, true);
-        }
-
-        plugin.getLogger().warning("Reloading " + fileName + " with new values...");
-        loadFile();
-        loadKeys();
-    }
-}

+ 0 - 312
src/main/java/com/gmail/nossr50/config/ConfigLoaderConfigurable.java

@@ -1,312 +0,0 @@
-package com.gmail.nossr50.config;
-
-import com.gmail.nossr50.mcMMO;
-import com.google.common.io.Files;
-import ninja.leaping.configurate.ConfigurationNode;
-import ninja.leaping.configurate.commented.CommentedConfigurationNode;
-import ninja.leaping.configurate.loader.ConfigurationLoader;
-import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
-import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.List;
-
-/**
- * Handles loading and cacheing configuration settings from a configurable compatible config file
- */
-@ConfigSerializable
-public abstract class ConfigLoaderConfigurable implements DefaultKeys {
-
-    /* PATH VARS */
-
-    public final File DIRECTORY_DATA_FOLDER; //Directory that the file is in
-    public final String FILE_RELATIVE_PATH; //Relative Path to the file
-    protected final String DIRECTORY_DEFAULTS = "defaults";
-
-    /* LOADERS */
-
-    private YAMLConfigurationLoader defaultCopyLoader;
-    private YAMLConfigurationLoader userCopyLoader;
-
-    /* CONFIG FILES */
-
-    private File resourceConfigCopy; //Copy of the default config from the JAR (file is copied so that admins can easily compare to defaults)
-    private File resourceUserCopy; //File in the /$MCMMO_ROOT/mcMMO/ directory that may contain user edited settings
-
-    /* ROOT NODES */
-
-    private ConfigurationNode userRootNode = null;
-    private ConfigurationNode defaultRootNode = null;
-
-    /* CONFIG MANAGER */
-    private ConfigurationLoader<CommentedConfigurationNode> configManager;
-
-    //TODO: Needed?
-    //private ConfigurationLoader<CommentedConfigurationNode> configManager;
-
-    public ConfigLoaderConfigurable(File pathToDataFolder, String relativePath) {
-        /*
-         * These must be at the top
-         */
-        mkdirDefaults(); // Make our default config dir
-        DIRECTORY_DATA_FOLDER = pathToDataFolder; //Data Folder for our plugin
-        FILE_RELATIVE_PATH = relativePath; //Relative path to config from a parent folder
-
-        //Attempt IO Operations
-        try {
-            //Makes sure we have valid Files corresponding to this config
-            initConfigFiles();
-
-            //Init Config Loaders
-            initConfigLoaders();
-
-            //Load Config Nodes
-            loadConfig();
-
-            //Attempt to update user file, and then load it into memory
-            readConfig();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
-        /*
-         * Print Errors about Keys
-         */
-
-        List<String> validKeyErrors = validateKeys(); // Validate Keys
-
-        if(validKeyErrors != null && validKeyErrors.size() > 0)
-        {
-            for(String error : validKeyErrors)
-            {
-                mcMMO.p.getLogger().severe(error);
-            }
-        }
-    }
-
-    /**
-     * Initializes the default copy File and the user config File
-     * @throws IOException
-     */
-    private void initConfigFiles() throws IOException {
-        //Init our config copy
-        resourceConfigCopy = initDefaultConfig();
-
-        //Init the user file
-        resourceUserCopy = initUserConfig();
-    }
-
-    /**
-     * Loads the root node for the default config File and user config File
-     */
-    private void loadConfig()
-    {
-        try {
-            final ConfigurationNode defaultConfig = this.defaultCopyLoader.load();
-            defaultRootNode = defaultConfig;
-
-            final ConfigurationNode userConfig = this.userCopyLoader.load();
-            userRootNode = userConfig;
-
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Initializes the YAMLConfigurationLoaders for this config
-     */
-    private void initConfigLoaders()
-    {
-        this.defaultCopyLoader = YAMLConfigurationLoader.builder().setPath(resourceConfigCopy.toPath()).build();
-        this.userCopyLoader = YAMLConfigurationLoader.builder().setPath(resourceUserCopy.toPath()).build();
-    }
-
-    /**
-     * Copies a new file from the JAR to the defaults directory and uses that new file to initialize our resourceConfigCopy
-     * @see ConfigLoaderConfigurable#resourceConfigCopy
-     * @throws IOException
-     */
-    private File initDefaultConfig() throws IOException {
-        return copyDefaultFromJar(getDefaultConfigCopyRelativePath(), true);
-    }
-
-    /**
-     * Attemps to load the config file if it exists, if it doesn't it copies a new one from within the JAR
-     * @return user config File
-     * @see ConfigLoaderConfigurable#resourceUserCopy
-     * @throws IOException
-     */
-    private File initUserConfig() throws IOException {
-        File userCopy = new File(DIRECTORY_DATA_FOLDER, FILE_RELATIVE_PATH); //Load the user file;
-
-        if(userCopy.exists())
-        {
-            // Yay
-            return userCopy;
-        }
-        else
-        {
-            //If it's gone we copy default files
-            //Note that we don't copy the values from the default copy put in /defaults/ that file exists only as a reference to admins and is unreliable
-            return copyDefaultFromJar(FILE_RELATIVE_PATH, false);
-        }
-    }
-
-    /**
-     * Used to make a new config file at a specified relative output path inside the data directory by copying the matching file found in that same relative path within the JAR
-     * @param relativeOutputPath the path to the output file
-     * @param deleteOld whether or not to delete the existing output file on disk
-     * @return a copy of the default config within the JAR
-     * @throws IOException
-     */
-    private File copyDefaultFromJar(String relativeOutputPath, boolean deleteOld) throws IOException
-    {
-        /*
-         * Gen a Default config from inside the JAR
-         */
-        mcMMO.p.getLogger().info("Preparing to copy internal resource file (in JAR) - "+FILE_RELATIVE_PATH);
-        InputStream inputStream = mcMMO.p.getResource(FILE_RELATIVE_PATH);
-
-        byte[] buffer = new byte[inputStream.available()];
-        inputStream.read(buffer);
-
-        //This is a copy of the default file, which we will overwrite every time mcMMO loads
-        File targetFile = new File(DIRECTORY_DATA_FOLDER, relativeOutputPath);
-
-        //Wipe old default file on disk
-        if (targetFile.exists() && deleteOld)
-        {
-            mcMMO.p.getLogger().info("Updating file " + relativeOutputPath);
-            targetFile.delete(); //Necessary?
-        }
-
-        if(!targetFile.exists())
-        {
-            targetFile.getParentFile().mkdirs();
-            targetFile.createNewFile(); //New File Boys
-        }
-
-        Files.write(buffer, targetFile);
-        mcMMO.p.getLogger().info("Created config file - " + relativeOutputPath);
-
-        inputStream.close(); //Close the input stream
-
-        return targetFile;
-    }
-
-    /**
-     * The path to the defaults directory
-     * @return the path to the defaults directory
-     */
-    private String getDefaultConfigCopyRelativePath() {
-        return DIRECTORY_DEFAULTS + File.separator + FILE_RELATIVE_PATH;
-    }
-
-    /**
-     * Creates the defaults directory
-     */
-    private void mkdirDefaults() {
-        //Make Default Subdirectory
-        File defaultsDir = new File (DIRECTORY_DATA_FOLDER, "defaults");
-
-        if(!defaultsDir.exists())
-            defaultsDir.mkdir();
-    }
-
-    /**
-     * Configs are always versioned to the last version of mcMMO
-     * @return Config Version String (mirrors mcMMO version)
-     */
-    public String getConfigVersion()
-    {
-        return mcMMO.p.getDescription().getVersion();
-    }
-
-    /**
-     * Attempts to read the loaded config file
-     * Config will have any necessary updates applied
-     * Config will be compared to the default config to see if it is missing any nodes
-     * Config will have any missing nodes inserted with their default value
-     */
-    public void readConfig() {
-        mcMMO.p.getLogger().info("Attempting to read " + FILE_RELATIVE_PATH + ".");
-
-        int version = this.userRootNode.getNode("ConfigVersion").getInt();
-        mcMMO.p.getLogger().info(FILE_RELATIVE_PATH + " version is " + version);
-
-        //Update our config
-        updateConfig();
-    }
-
-    /**
-     * Compares the users config file to the default and adds any missing nodes and applies any necessary updates
-     */
-    private void updateConfig()
-    {
-        mcMMO.p.getLogger().info(defaultRootNode.getChildrenMap().size() +" items in default children map");
-        mcMMO.p.getLogger().info(userRootNode.getChildrenMap().size() +" items in default root map");
-
-        // Merge Values from default
-        userRootNode = userRootNode.mergeValuesFrom(defaultRootNode);
-
-        // Update config version
-        updateConfigVersion();
-
-        //Attempt to save
-        try {
-            saveUserCopy();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-    }
-
-    /**
-     * Saves the current state information of the config to the users copy (which they may edit)
-     * @throws IOException
-     */
-    private void saveUserCopy() throws IOException
-    {
-        mcMMO.p.getLogger().info("Saving new node");
-        userCopyLoader.save(userRootNode);
-    }
-
-    /**
-     * Performs any necessary operations to update this config
-     */
-    private void updateConfigVersion() {
-        // Set a version for our config
-        this.userRootNode.getNode("ConfigVersion").setValue(getConfigVersion());
-        mcMMO.p.getLogger().info("Updated config to ["+getConfigVersion()+"] - " + FILE_RELATIVE_PATH);
-    }
-
-    /**
-     * Returns the root node of this config
-     * @return the root node of this config
-     */
-    protected ConfigurationNode getUserRootNode() {
-        return userRootNode;
-    }
-
-    int getIntValue(String path)
-    {
-        return userRootNode.getNode(path.split("\\.")).getInt();
-    }
-
-    double getDoubleValue(String path)
-    {
-        return userRootNode.getNode(path.split("\\.")).getDouble();
-    }
-
-    boolean getBooleanValue(String path)
-    {
-        return userRootNode.getNode(path.split("\\.")).getBoolean();
-    }
-
-    String getStringValue(String path)
-    {
-        return userRootNode.getNode(path.split("\\.")).getString();
-    }
-}

+ 43 - 0
src/main/java/com/gmail/nossr50/config/ConfigValidated.java

@@ -0,0 +1,43 @@
+package com.gmail.nossr50.config;
+
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * This class is used for config files that validate their entries
+ */
+public abstract class ConfigValidated extends Config implements DefaultKeys {
+    public ConfigValidated(String parentFolderPath, String relativePath, boolean mergeNewKeys)
+    {
+        super(parentFolderPath, relativePath, mergeNewKeys);
+        validateEntries();
+    }
+
+    public ConfigValidated(File parentFolderFile, String relativePath, boolean mergeNewKeys)
+    {
+        super(parentFolderFile, relativePath, mergeNewKeys);
+        validateEntries();
+    }
+
+    /**
+     * Prints all errors found when validating the config
+     */
+    private void validateEntries()
+    {
+        /*
+         * Print Errors about Keys
+         */
+
+        List<String> validKeyErrors = validateKeys(); // Validate Keys
+
+        if(validKeyErrors != null && validKeyErrors.size() > 0)
+        {
+            for(String error : validKeyErrors)
+            {
+                McmmoCore.getLogger().severe(error);
+            }
+        }
+    }
+
+}

+ 0 - 35
src/main/java/com/gmail/nossr50/config/ConfigurableTest.java

@@ -1,35 +0,0 @@
-package com.gmail.nossr50.config;
-
-import com.gmail.nossr50.mcMMO;
-import ninja.leaping.configurate.objectmapping.Setting;
-import ninja.leaping.configurate.objectmapping.serialize.ConfigSerializable;
-
-import java.util.List;
-
-@ConfigSerializable
-public class ConfigurableTest extends ConfigLoaderConfigurable {
-
-    public final static String relativePath = "configurabletest.yml";
-    private static ConfigurableTest instance;
-
-    public ConfigurableTest() {
-        super(mcMMO.p.getDataFolder().getAbsoluteFile(), relativePath);
-
-        mcMMO.p.getLogger().severe("The value of bone "+boneValue);
-    }
-
-    public static ConfigurableTest getInstance() {
-        if(instance == null)
-            instance = new ConfigurableTest();
-
-        return instance;
-    }
-
-    @Setting(value = "woof.bone", comment = "Finally we have found the value of bone")
-    double boneValue = 9.4447;
-
-    @Override
-    public List<String> validateKeys() {
-        return null;
-    }
-}

+ 24 - 21
src/main/java/com/gmail/nossr50/config/CoreSkillsConfig.java

@@ -2,34 +2,37 @@ package com.gmail.nossr50.config;
 
 
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
 import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
+import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
 
 
-public class CoreSkillsConfig extends AutoUpdateConfigLoader {
+public class CoreSkillsConfig extends Config {
     private static CoreSkillsConfig instance;
     private static CoreSkillsConfig instance;
 
 
-    public CoreSkillsConfig()
-    {
-        super("coreskills.yml");
-        validate();
+    public CoreSkillsConfig() {
+        //super(McmmoCore.getDataFolderPath().getAbsoluteFile(),"coreskills.yml", true);
+        super(mcMMO.p.getDataFolder().getAbsoluteFile(),"coreskills.yml", true);
     }
     }
 
 
-    @Override
-    protected void loadKeys() {
-
-    }
-
-    public static CoreSkillsConfig getInstance()
-    {
-        if(instance == null)
+    public static CoreSkillsConfig getInstance() {
+        if (instance == null)
             return new CoreSkillsConfig();
             return new CoreSkillsConfig();
 
 
         return instance;
         return instance;
     }
     }
 
 
+    /**
+     * The version of this config
+     *
+     * @return
+     */
     @Override
     @Override
-    protected boolean validateKeys() {
+    public double getConfigVersion() {
+        return 1;
+    }
 
 
-        return true;
+    @Override
+    public void unload() {
+        instance = null;
     }
     }
 
 
     /*
     /*
@@ -39,21 +42,21 @@ public class CoreSkillsConfig extends AutoUpdateConfigLoader {
     /**
     /**
      * Whether or not a skill is enabled
      * Whether or not a skill is enabled
      * Defaults true
      * Defaults true
+     *
      * @param abstractSubSkill SubSkill definition to check
      * @param abstractSubSkill SubSkill definition to check
      * @return true if subskill is enabled
      * @return true if subskill is enabled
      */
      */
-    public boolean isSkillEnabled(AbstractSubSkill abstractSubSkill)
-    {
-        return config.getBoolean(StringUtils.getCapitalized(abstractSubSkill.getPrimarySkill().toString())+"."+ abstractSubSkill.getConfigKeyName()+".Enabled", true);
+    public boolean isSkillEnabled(AbstractSubSkill abstractSubSkill) {
+        return getBooleanValue(StringUtils.getCapitalized(abstractSubSkill.getPrimarySkill().toString()) + "." + abstractSubSkill.getConfigKeyName() + ".Enabled", true);
     }
     }
 
 
     /**
     /**
      * Whether or not this primary skill is enabled
      * Whether or not this primary skill is enabled
+     *
      * @param primarySkillType target primary skill
      * @param primarySkillType target primary skill
      * @return true if enabled
      * @return true if enabled
      */
      */
-    public boolean isPrimarySkillEnabled(PrimarySkillType primarySkillType)
-    {
-        return config.getBoolean(StringUtils.getCapitalized(primarySkillType.toString())+".Enabled", true);
+    public boolean isPrimarySkillEnabled(PrimarySkillType primarySkillType) {
+        return getBooleanValue(StringUtils.getCapitalized(primarySkillType.toString()) + ".Enabled", true);
     }
     }
 }
 }

+ 3 - 0
src/main/java/com/gmail/nossr50/config/DefaultKeys.java

@@ -2,6 +2,9 @@ package com.gmail.nossr50.config;
 
 
 import java.util.List;
 import java.util.List;
 
 
+/**
+ * This is for config validation
+ */
 public interface DefaultKeys {
 public interface DefaultKeys {
     List<String> validateKeys();
     List<String> validateKeys();
 }
 }

+ 0 - 68
src/main/java/com/gmail/nossr50/config/HiddenConfig.java

@@ -1,68 +0,0 @@
-package com.gmail.nossr50.config;
-
-import com.gmail.nossr50.mcMMO;
-import org.bukkit.configuration.file.YamlConfiguration;
-
-import java.io.InputStreamReader;
-
-public class HiddenConfig {
-    private static HiddenConfig instance;
-    private String fileName;
-    private YamlConfiguration config;
-    private boolean chunkletsEnabled;
-    private int conversionRate;
-    private boolean useEnchantmentBuffs;
-    private int uuidConvertAmount;
-    private int mojangRateLimit;
-    private long mojangLimitPeriod;
-
-    public HiddenConfig(String fileName) {
-        this.fileName = fileName;
-        load();
-    }
-
-    public static HiddenConfig getInstance() {
-        if (instance == null) {
-            instance = new HiddenConfig("hidden.yml");
-        }
-
-        return instance;
-    }
-
-    public void load() {
-        InputStreamReader reader = mcMMO.p.getResourceAsReader(fileName);
-        if (reader != null) {
-            config = YamlConfiguration.loadConfiguration(reader);
-            chunkletsEnabled = config.getBoolean("Options.Chunklets", true);
-            conversionRate = config.getInt("Options.ConversionRate", 1);
-            useEnchantmentBuffs = config.getBoolean("Options.EnchantmentBuffs", true);
-            uuidConvertAmount = config.getInt("Options.UUIDConvertAmount", 5);
-            mojangRateLimit = config.getInt("Options.MojangRateLimit", 50000);
-            mojangLimitPeriod = config.getLong("Options.MojangLimitPeriod", 600000);
-        }
-    }
-
-    public boolean getChunkletsEnabled() {
-        return chunkletsEnabled;
-    }
-
-    public int getConversionRate() {
-        return conversionRate;
-    }
-
-    public boolean useEnchantmentBuffs() {
-        return useEnchantmentBuffs;
-    }
-
-    public int getUUIDConvertAmount() {
-        return uuidConvertAmount;
-    }
-
-    public int getMojangRateLimit() {
-        return mojangRateLimit;
-    }
-
-    public long getMojangLimitPeriod() {
-        return mojangLimitPeriod;
-    }
-}

+ 1045 - 0
src/main/java/com/gmail/nossr50/config/MainConfig.java

@@ -0,0 +1,1045 @@
+package com.gmail.nossr50.config;
+
+import com.gmail.nossr50.database.SQLDatabaseManager;
+import com.gmail.nossr50.datatypes.MobHealthbarType;
+import com.gmail.nossr50.datatypes.party.PartyFeature;
+import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
+import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
+import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.util.StringUtils;
+import org.bukkit.Material;
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.entity.EntityType;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+public class MainConfig extends ConfigValidated {
+    private static MainConfig instance;
+
+    private MainConfig() {
+        //super(McmmoCore.getDataFolderPath().getAbsoluteFile(), "config.yml", true);
+        super(mcMMO.p.getDataFolder().getAbsoluteFile(), "config.yml", true);
+    }
+
+    public static MainConfig getInstance() {
+        if (instance == null) {
+            instance = new MainConfig();
+        }
+
+        return instance;
+    }
+
+    @Override
+    public void unload() {
+        instance = null;
+    }
+
+    /**
+     * The version of this config
+     *
+     * @return
+     */
+    @Override
+    public double getConfigVersion() {
+        return 1;
+    }
+
+    @Override
+    public List<String> validateKeys() {
+        // Validate all the settings!
+        List<String> reason = new ArrayList<String>();
+
+        /* General Settings */
+        if (getSaveInterval() <= 0) {
+            reason.add("General.Save_Interval should be greater than 0!");
+        }
+
+        /* MySQL Settings */
+        for (SQLDatabaseManager.PoolIdentifier identifier : SQLDatabaseManager.PoolIdentifier.values()) {
+            if (getMySQLMaxConnections(identifier) <= 0) {
+                reason.add("MySQL.Database.MaxConnections." + StringUtils.getCapitalized(identifier.toString()) + " should be greater than 0!");
+            }
+            if (getMySQLMaxPoolSize(identifier) <= 0) {
+                reason.add("MySQL.Database.MaxPoolSize." + StringUtils.getCapitalized(identifier.toString()) + " should be greater than 0!");
+            }
+        }
+
+        /* Mob Healthbar */
+        if (getMobHealthbarTime() == 0) {
+            reason.add("Mob_Healthbar.Display_Time cannot be 0! Set to -1 to disable or set a valid value.");
+        }
+
+        /* Scoreboards */
+        /*if (getRankScoreboardTime() != -1 && getRankScoreboardTime() <= 0) {
+            reason.add("Scoreboard.Types.Rank.Display_Time should be greater than 0, or -1!");
+        }
+
+        if (getStatsScoreboardTime() != -1 && getStatsScoreboardTime() <= 0) {
+            reason.add("Scoreboard.Types.Stats.Display_Time should be greater than 0, or -1!");
+        }
+
+        if (getTopScoreboardTime() != -1 && getTopScoreboardTime() <= 0) {
+            reason.add("Scoreboard.Types.Top.Display_Time should be greater than 0, or -1!");
+        }
+
+        if (getInspectScoreboardTime() != -1 && getInspectScoreboardTime() <= 0) {
+            reason.add("Scoreboard.Types.Inspect.Display_Time should be greater than 0, or -1!");
+        }
+
+        if (getSkillScoreboardTime() != -1 && getSkillScoreboardTime() <= 0) {
+            reason.add("Scoreboard.Types.Skill.Display_Time should be greater than 0, or -1!");
+        }
+
+        if (getSkillLevelUpTime() != -1 && getSkillScoreboardTime() <= 0) {
+            reason.add("Scoreboard.Types.Skill.Display_Time should be greater than 0, or -1!");
+        }
+
+        if (!(getRankUseChat() || getRankUseBoard())) {
+            reason.add("Either Board or Print in Scoreboard.Types.Rank must be true!");
+        }
+
+        if (!(getTopUseChat() || getTopUseBoard())) {
+            reason.add("Either Board or Print in Scoreboard.Types.Top must be true!");
+        }
+
+        if (!(getStatsUseChat() || getStatsUseBoard())) {
+            reason.add("Either Board or Print in Scoreboard.Types.Stats must be true!");
+        }
+
+        if (!(getInspectUseChat() || getInspectUseBoard())) {
+            reason.add("Either Board or Print in Scoreboard.Types.Inspect must be true!");
+        }*/
+
+        /* Database Purging */
+        if (getPurgeInterval() < -1) {
+            reason.add("Database_Purging.Purge_Interval should be greater than, or equal to -1!");
+        }
+
+        if (getOldUsersCutoff() != -1 && getOldUsersCutoff() <= 0) {
+            reason.add("Database_Purging.Old_User_Cutoff should be greater than 0 or -1!");
+        }
+
+        /* Hardcore Mode */
+        if (getHardcoreDeathStatPenaltyPercentage() < 0.01 || getHardcoreDeathStatPenaltyPercentage() > 100) {
+            reason.add("Hardcore.Death_Stat_Loss.Penalty_Percentage only accepts values from 0.01 to 100!");
+        }
+
+        if (getHardcoreVampirismStatLeechPercentage() < 0.01 || getHardcoreVampirismStatLeechPercentage() > 100) {
+            reason.add("Hardcore.Vampirism.Leech_Percentage only accepts values from 0.01 to 100!");
+        }
+
+        /* Items */
+        if (getChimaeraUseCost() < 1 || getChimaeraUseCost() > 64) {
+            reason.add("Items.Chimaera_Wing.Use_Cost only accepts values from 1 to 64!");
+        }
+
+        if (getChimaeraRecipeCost() < 1 || getChimaeraRecipeCost() > 9) {
+            reason.add("Items.Chimaera_Wing.Recipe_Cost only accepts values from 1 to 9!");
+        }
+
+        if (getChimaeraItem() == null) {
+            reason.add("Items.Chimaera_Wing.Item_Name is invalid!");
+        }
+
+        /* Particles */
+        if (getLevelUpEffectsTier() < 1) {
+            reason.add("Particles.LevelUp_Tier should be at least 1!");
+        }
+
+        /* PARTY SETTINGS */
+        if (getAutoPartyKickInterval() < -1) {
+            reason.add("Party.AutoKick_Interval should be at least -1!");
+        }
+
+        if (getAutoPartyKickTime() < 0) {
+            reason.add("Party.Old_Party_Member_Cutoff should be at least 0!");
+        }
+
+        if (getPartyShareBonusBase() <= 0) {
+            reason.add("Party.Sharing.ExpShare_bonus_base should be greater than 0!");
+        }
+
+        if (getPartyShareBonusIncrease() < 0) {
+            reason.add("Party.Sharing.ExpShare_bonus_increase should be at least 0!");
+        }
+
+        if (getPartyShareBonusCap() <= 0) {
+            reason.add("Party.Sharing.ExpShare_bonus_cap should be greater than 0!");
+        }
+
+        if (getPartyShareRange() <= 0) {
+            reason.add("Party.Sharing.Range should be greater than 0!");
+        }
+
+        if (getPartyXpCurveMultiplier() < 1) {
+            reason.add("Party.Leveling.Xp_Curve_Modifier should be at least 1!");
+        }
+
+        for (PartyFeature partyFeature : PartyFeature.values()) {
+            if (getPartyFeatureUnlockLevel(partyFeature) < 0) {
+                reason.add("Party.Leveling." + StringUtils.getPrettyPartyFeatureString(partyFeature).replace(" ", "") + "_UnlockLevel should be at least 0!");
+            }
+        }
+
+        /* Inspect command distance */
+        if (getInspectDistance() <= 0) {
+            reason.add("Commands.inspect.Max_Distance should be greater than 0!");
+        }
+
+        if (getTreeFellerThreshold() <= 0) {
+            reason.add("Abilities.Limits.Tree_Feller_Threshold should be greater than 0!");
+        }
+
+        if (getFishingLureModifier() < 0) {
+            reason.add("Abilities.Fishing.Lure_Modifier should be at least 0!");
+        }
+
+        if (getDetonatorItem() == null) {
+            reason.add("Skills.Mining.Detonator_Item is invalid!");
+        }
+
+        if (getRepairAnvilMaterial() == null) {
+            reason.add("Skills.Repair.Anvil_Type is invalid!!");
+        }
+
+        if (getSalvageAnvilMaterial() == null) {
+            reason.add("Skills.Repair.Salvage_Anvil_Type is invalid!");
+        }
+
+        if (getRepairAnvilMaterial() == getSalvageAnvilMaterial()) {
+            reason.add("Cannot use the same item for Repair and Salvage anvils!");
+        }
+
+        if (getTamingCOTWMaterial(EntityType.WOLF) == null) {
+            reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Item_Material is invalid!!");
+        }
+
+        if (getTamingCOTWMaterial(EntityType.OCELOT) == null) {
+            reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Item_Material is invalid!!");
+        }
+
+        if (getTamingCOTWMaterial(EntityType.HORSE) == null) {
+            reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Item_Material is invalid!!");
+        }
+
+        if (getTamingCOTWCost(EntityType.WOLF) <= 0) {
+            reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Item_Amount should be greater than 0!");
+        }
+
+        if (getTamingCOTWCost(EntityType.OCELOT) <= 0) {
+            reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Item_Amount should be greater than 0!");
+        }
+
+        if (getTamingCOTWCost(EntityType.HORSE) <= 0) {
+            reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Item_Amount should be greater than 0!");
+        }
+
+        if (getTamingCOTWAmount(EntityType.WOLF) <= 0) {
+            reason.add("Skills.Taming.Call_Of_The_Wild.Wolf.Summon_Amount should be greater than 0!");
+        }
+
+        if (getTamingCOTWAmount(EntityType.OCELOT) <= 0) {
+            reason.add("Skills.Taming.Call_Of_The_Wild.Ocelot.Summon_Amount should be greater than 0!");
+        }
+
+        if (getTamingCOTWAmount(EntityType.HORSE) <= 0) {
+            reason.add("Skills.Taming.Call_Of_The_Wild.Horse.Summon_Amount should be greater than 0!");
+        }
+
+        return reason;
+    }
+
+    /*
+     * GENERAL SETTINGS
+     */
+
+    /* General Settings */
+    public boolean getIsMetricsEnabled() {
+        return getBooleanValue("Metrics.bstats", true);
+    }
+
+    //Retro mode will default the value to true if the config file doesn't contain the entry (server is from a previous mcMMO install)
+    public boolean getIsRetroMode() {
+        return getBooleanValue("General.RetroMode.Enabled", true);
+    }
+
+    public String getLocale() {
+        return getStringValue("General.Locale", "en_us");
+    }
+
+    public boolean getMOTDEnabled() {
+        return getBooleanValue("General.MOTD_Enabled", true);
+    }
+
+    public boolean getShowProfileLoadedMessage() {
+        return getBooleanValue("General.Show_Profile_Loaded", true);
+    }
+
+    public boolean getDonateMessageEnabled() {
+        return getBooleanValue("Commands.mcmmo.Donate_Message", true);
+    }
+
+    public int getSaveInterval() {
+        return getIntValue("General.Save_Interval", 10);
+    }
+
+    public boolean getStatsTrackingEnabled() {
+        return getBooleanValue("General.Stats_Tracking", true);
+    }
+
+    public boolean getUpdateCheckEnabled() {
+        return getBooleanValue("General.Update_Check", true);
+    }
+
+    public boolean getPreferBeta() {
+        return getBooleanValue("General.Prefer_Beta", false);
+    }
+
+    public boolean getVerboseLoggingEnabled() {
+        return getBooleanValue("General.Verbose_Logging", false);
+    }
+
+    public String getPartyChatPrefix() {
+        return getStringValue("Commands.partychat.Chat_Prefix_Format", "[[GREEN]]([[WHITE]]{0}[[GREEN]])");
+    }
+
+    public boolean getPartyChatColorLeaderName() {
+        return getBooleanValue("Commands.partychat.Gold_Leader_Name", true);
+    }
+
+    public boolean getPartyDisplayNames() {
+        return getBooleanValue("Commands.partychat.Use_Display_Names", true);
+    }
+
+    public String getPartyChatPrefixAlly() {
+        return getStringValue("Commands.partychat.Chat_Prefix_Format_Ally", "[[GREEN]](A)[[RESET]]");
+    }
+
+    public String getAdminChatPrefix() {
+        return getStringValue("Commands.adminchat.Chat_Prefix_Format", "[[AQUA]][[[WHITE]]{0}[[AQUA]]]");
+    }
+
+    public boolean getAdminDisplayNames() {
+        return getBooleanValue("Commands.adminchat.Use_Display_Names", true);
+    }
+
+    public boolean getMatchOfflinePlayers() {
+        return getBooleanValue("Commands.Generic.Match_OfflinePlayers", false);
+    }
+
+    public long getDatabasePlayerCooldown() {
+        return config.getLong("Commands.Database.Player_Cooldown", 1750);
+    }
+
+    public boolean getLevelUpSoundsEnabled() {
+        return getBooleanValue("General.LevelUp_Sounds", true);
+    }
+
+    public boolean getRefreshChunksEnabled() {
+        return getBooleanValue("General.Refresh_Chunks", false);
+    }
+
+    public boolean getMobHealthbarEnabled() {
+        return getBooleanValue("Mob_Healthbar.Enabled", true);
+    }
+
+    /* Mob Healthbar */
+    public MobHealthbarType getMobHealthbarDefault() {
+        try {
+            return MobHealthbarType.valueOf(getStringValue("Mob_Healthbar.Display_Type", "HEARTS").toUpperCase().trim());
+        } catch (IllegalArgumentException ex) {
+            return MobHealthbarType.HEARTS;
+        }
+    }
+
+    public int getMobHealthbarTime() {
+        return getIntValue("Mob_Healthbar.Display_Time", 3);
+    }
+
+    /* Scoreboards */
+    public boolean getScoreboardsEnabled() {
+        return getBooleanValue("Scoreboard.UseScoreboards", true);
+    }
+
+    public boolean getPowerLevelTagsEnabled() {
+        return getBooleanValue("Scoreboard.Power_Level_Tags", false);
+    }
+
+    public boolean getAllowKeepBoard() {
+        return getBooleanValue("Scoreboard.Allow_Keep", true);
+    }
+
+    public int getTipsAmount() {
+        return getIntValue("Scoreboard.Tips_Amount", 5);
+    }
+
+    public boolean getShowStatsAfterLogin() {
+        return getBooleanValue("Scoreboard.Show_Stats_After_Login", false);
+    }
+
+    public boolean getScoreboardRainbows() {
+        return getBooleanValue("Scoreboard.Rainbows", false);
+    }
+
+    public boolean getShowAbilityNames() {
+        return getBooleanValue("Scoreboard.Ability_Names", true);
+    }
+
+    public boolean getRankUseChat() {
+        return getBooleanValue("Scoreboard.Types.Rank.Print", false);
+    }
+
+    public boolean getRankUseBoard() {
+        return getBooleanValue("Scoreboard.Types.Rank.Board", true);
+    }
+
+    public int getRankScoreboardTime() {
+        return getIntValue("Scoreboard.Types.Rank.Display_Time", 10);
+    }
+
+    public boolean getTopUseChat() {
+        return getBooleanValue("Scoreboard.Types.Top.Print", true);
+    }
+
+    public boolean getTopUseBoard() {
+        return getBooleanValue("Scoreboard.Types.Top.Board", true);
+    }
+
+    public int getTopScoreboardTime() {
+        return getIntValue("Scoreboard.Types.Top.Display_Time", 15);
+    }
+
+    public boolean getStatsUseChat() {
+        return getBooleanValue("Scoreboard.Types.Stats.Print", true);
+    }
+
+    public boolean getStatsUseBoard() {
+        return getBooleanValue("Scoreboard.Types.Stats.Board", true);
+    }
+
+    public int getStatsScoreboardTime() {
+        return getIntValue("Scoreboard.Types.Stats.Display_Time", 10);
+    }
+
+    public boolean getInspectUseChat() {
+        return getBooleanValue("Scoreboard.Types.Inspect.Print", true);
+    }
+
+    public boolean getInspectUseBoard() {
+        return getBooleanValue("Scoreboard.Types.Inspect.Board", true);
+    }
+
+    public int getInspectScoreboardTime() {
+        return getIntValue("Scoreboard.Types.Inspect.Display_Time", 25);
+    }
+
+    public boolean getCooldownUseChat() {
+        return getBooleanValue("Scoreboard.Types.Cooldown.Print", false);
+    }
+
+    public boolean getCooldownUseBoard() {
+        return getBooleanValue("Scoreboard.Types.Cooldown.Board", true);
+    }
+
+    public int getCooldownScoreboardTime() {
+        return getIntValue("Scoreboard.Types.Cooldown.Display_Time", 41);
+    }
+
+    public boolean getSkillUseBoard() {
+        return getBooleanValue("Scoreboard.Types.Skill.Board", true);
+    }
+
+    public int getSkillScoreboardTime() {
+        return getIntValue("Scoreboard.Types.Skill.Display_Time", 30);
+    }
+
+    public boolean getSkillLevelUpBoard() {
+        return getBooleanValue("Scoreboard.Types.Skill.LevelUp_Board", true);
+    }
+
+    public int getSkillLevelUpTime() {
+        return getIntValue("Scoreboard.Types.Skill.LevelUp_Time", 5);
+    }
+
+    /* Database Purging */
+    public int getPurgeInterval() {
+        return getIntValue("Database_Purging.Purge_Interval", -1);
+    }
+
+    public int getOldUsersCutoff() {
+        return getIntValue("Database_Purging.Old_User_Cutoff", 6);
+    }
+
+    /* Backups */
+    public boolean getBackupsEnabled() {
+        return getBooleanValue("Backups.Enabled", true);
+    }
+
+    public boolean getKeepLast24Hours() {
+        return getBooleanValue("Backups.Keep.Last_24_Hours", true);
+    }
+
+    public boolean getKeepDailyLastWeek() {
+        return getBooleanValue("Backups.Keep.Daily_Last_Week", true);
+    }
+
+    public boolean getKeepWeeklyPastMonth() {
+        return getBooleanValue("Backups.Keep.Weekly_Past_Months", true);
+    }
+
+    /* mySQL */
+    public boolean getUseMySQL() {
+        return getBooleanValue("MySQL.Enabled", false);
+    }
+
+    public String getMySQLTablePrefix() {
+        return getStringValue("MySQL.Database.TablePrefix", "mcmmo_");
+    }
+
+    public String getMySQLDatabaseName() {
+        return getStringIncludingInts("MySQL.Database.Name");
+    }
+
+    public String getMySQLUserName() {
+        return getStringIncludingInts("MySQL.Database.User_Name");
+    }
+
+    public int getMySQLServerPort() {
+        return getIntValue("MySQL.Server.Port", 3306);
+    }
+
+    public String getMySQLServerName() {
+        return getStringValue("MySQL.Server.Address", "localhost");
+    }
+
+    public String getMySQLUserPassword() {
+        return getStringIncludingInts("MySQL.Database.User_Password");
+    }
+
+    public int getMySQLMaxConnections(SQLDatabaseManager.PoolIdentifier identifier) {
+        return getIntValue("MySQL.Database.MaxConnections." + StringUtils.getCapitalized(identifier.toString()), 30);
+    }
+
+    public int getMySQLMaxPoolSize(SQLDatabaseManager.PoolIdentifier identifier) {
+        return getIntValue("MySQL.Database.MaxPoolSize." + StringUtils.getCapitalized(identifier.toString()), 10);
+    }
+
+    public boolean getMySQLSSL() {
+        return getBooleanValue("MySQL.Server.SSL", true);
+    }
+
+    private String getStringIncludingInts(String key) {
+        String str = getStringValue(key);
+
+        if (str == null) {
+            str = String.valueOf(getIntValue(key));
+        }
+
+        if (str.equals("0")) {
+            str = "No value set for '" + key + "'";
+        }
+        return str;
+    }
+
+    /* Hardcore Mode */
+    public boolean getHardcoreStatLossEnabled(PrimarySkillType primarySkillType) {
+        return getBooleanValue("Hardcore.Death_Stat_Loss.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), false);
+    }
+
+    public void setHardcoreStatLossEnabled(PrimarySkillType primarySkillType, boolean enabled) {
+        config.set("Hardcore.Death_Stat_Loss.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), enabled);
+    }
+
+    public double getHardcoreDeathStatPenaltyPercentage() {
+        return getDoubleValue("Hardcore.Death_Stat_Loss.Penalty_Percentage", 75.0D);
+    }
+
+    public void setHardcoreDeathStatPenaltyPercentage(double value) {
+        config.set("Hardcore.Death_Stat_Loss.Penalty_Percentage", value);
+    }
+
+    public int getHardcoreDeathStatPenaltyLevelThreshold() {
+        return getIntValue("Hardcore.Death_Stat_Loss.Level_Threshold", 0);
+    }
+
+    public boolean getHardcoreVampirismEnabled(PrimarySkillType primarySkillType) {
+        return getBooleanValue("Hardcore.Vampirism.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), false);
+    }
+
+    public void setHardcoreVampirismEnabled(PrimarySkillType primarySkillType, boolean enabled) {
+        config.set("Hardcore.Vampirism.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), enabled);
+    }
+
+    public double getHardcoreVampirismStatLeechPercentage() {
+        return getDoubleValue("Hardcore.Vampirism.Leech_Percentage", 5.0D);
+    }
+
+    public void setHardcoreVampirismStatLeechPercentage(double value) {
+        config.set("Hardcore.Vampirism.Leech_Percentage", value);
+    }
+
+    public int getHardcoreVampirismLevelThreshold() {
+        return getIntValue("Hardcore.Vampirism.Level_Threshold", 0);
+    }
+
+    /* SMP Mods */
+    public boolean getToolModsEnabled() {
+        return getBooleanValue("Mods.Tool_Mods_Enabled", false);
+    }
+
+    public boolean getArmorModsEnabled() {
+        return getBooleanValue("Mods.Armor_Mods_Enabled", false);
+    }
+
+    public boolean getBlockModsEnabled() {
+        return getBooleanValue("Mods.Block_Mods_Enabled", false);
+    }
+
+    public boolean getEntityModsEnabled() {
+        return getBooleanValue("Mods.Entity_Mods_Enabled", false);
+    }
+
+    /* Items */
+    public int getChimaeraUseCost() {
+        return getIntValue("Items.Chimaera_Wing.Use_Cost", 1);
+    }
+
+    public int getChimaeraRecipeCost() {
+        return getIntValue("Items.Chimaera_Wing.Recipe_Cost", 5);
+    }
+
+    public Material getChimaeraItem() {
+        return Material.matchMaterial(getStringValue("Items.Chimaera_Wing.Item_Name", "Feather"));
+    }
+
+    public boolean getChimaeraEnabled() {
+        return getBooleanValue("Items.Chimaera_Wing.Enabled", true);
+    }
+
+    public boolean getChimaeraPreventUseUnderground() {
+        return getBooleanValue("Items.Chimaera_Wing.Prevent_Use_Underground", true);
+    }
+
+    public boolean getChimaeraUseBedSpawn() {
+        return getBooleanValue("Items.Chimaera_Wing.Use_Bed_Spawn", true);
+    }
+
+    public int getChimaeraCooldown() {
+        return getIntValue("Items.Chimaera_Wing.Cooldown", 240);
+    }
+
+    public int getChimaeraWarmup() {
+        return getIntValue("Items.Chimaera_Wing.Warmup", 5);
+    }
+
+    public int getChimaeraRecentlyHurtCooldown() {
+        return getIntValue("Items.Chimaera_Wing.RecentlyHurt_Cooldown", 60);
+    }
+
+    public boolean getChimaeraSoundEnabled() {
+        return getBooleanValue("Items.Chimaera_Wing.Sound_Enabled", true);
+    }
+
+    public boolean getFluxPickaxeSoundEnabled() {
+        return getBooleanValue("Items.Flux_Pickaxe.Sound_Enabled", true);
+    }
+
+    /* Particles */
+    public boolean getAbilityActivationEffectEnabled() {
+        return getBooleanValue("Particles.Ability_Activation", true);
+    }
+
+    public boolean getAbilityDeactivationEffectEnabled() {
+        return getBooleanValue("Particles.Ability_Deactivation", true);
+    }
+
+    public boolean getBleedEffectEnabled() {
+        return getBooleanValue("Particles.Bleed", true);
+    }
+
+    public boolean getDodgeEffectEnabled() {
+        return getBooleanValue("Particles.Dodge", true);
+    }
+
+    public boolean getFluxEffectEnabled() {
+        return getBooleanValue("Particles.Flux", true);
+    }
+
+    public boolean getGreaterImpactEffectEnabled() {
+        return getBooleanValue("Particles.Greater_Impact", true);
+    }
+
+    public boolean getCallOfTheWildEffectEnabled() {
+        return getBooleanValue("Particles.Call_of_the_Wild", true);
+    }
+
+    public boolean getLevelUpEffectsEnabled() {
+        return getBooleanValue("Particles.LevelUp_Enabled", true);
+    }
+
+    public int getLevelUpEffectsTier() {
+        return getIntValue("Particles.LevelUp_Tier", 100);
+    }
+
+    public boolean getLargeFireworks() {
+        return getBooleanValue("Particles.LargeFireworks", true);
+    }
+
+    /* PARTY SETTINGS */
+    public boolean getPartyFriendlyFire() {
+        return getBooleanValue("Party.FriendlyFire", false);
+    }
+
+    public int getPartyMaxSize() {
+        return getIntValue("Party.MaxSize", -1);
+    }
+
+    public int getAutoPartyKickInterval() {
+        return getIntValue("Party.AutoKick_Interval", 12);
+    }
+
+    public int getAutoPartyKickTime() {
+        return getIntValue("Party.Old_Party_Member_Cutoff", 7);
+    }
+
+    public double getPartyShareBonusBase() {
+        return getDoubleValue("Party.Sharing.ExpShare_bonus_base", 1.1D);
+    }
+
+    public double getPartyShareBonusIncrease() {
+        return getDoubleValue("Party.Sharing.ExpShare_bonus_increase", 0.05D);
+    }
+
+    public double getPartyShareBonusCap() {
+        return getDoubleValue("Party.Sharing.ExpShare_bonus_cap", 1.5D);
+    }
+
+    public double getPartyShareRange() {
+        return getDoubleValue("Party.Sharing.Range", 75.0D);
+    }
+
+    public int getPartyLevelCap() {
+        int cap = getIntValue("Party.Leveling.Level_Cap", 10);
+        return (cap <= 0) ? Integer.MAX_VALUE : cap;
+    }
+
+    public int getPartyXpCurveMultiplier() {
+        return getIntValue("Party.Leveling.Xp_Curve_Modifier", 3);
+    }
+
+    public boolean getPartyXpNearMembersNeeded() {
+        return getBooleanValue("Party.Leveling.Near_Members_Needed", false);
+    }
+
+    public boolean getPartyInformAllMembers() {
+        return getBooleanValue("Party.Leveling.Inform_All_Party_Members_On_LevelUp", false);
+    }
+
+    public int getPartyFeatureUnlockLevel(PartyFeature partyFeature) {
+        return getIntValue("Party.Leveling." + StringUtils.getPrettyPartyFeatureString(partyFeature).replace(" ", "") + "_UnlockLevel", 0);
+    }
+
+    /* Party Teleport Settings */
+    public int getPTPCommandCooldown() {
+        return getIntValue("Commands.ptp.Cooldown", 120);
+    }
+
+    public int getPTPCommandWarmup() {
+        return getIntValue("Commands.ptp.Warmup", 5);
+    }
+
+    public int getPTPCommandRecentlyHurtCooldown() {
+        return getIntValue("Commands.ptp.RecentlyHurt_Cooldown", 60);
+    }
+
+    public int getPTPCommandTimeout() {
+        return getIntValue("Commands.ptp.Request_Timeout", 300);
+    }
+
+    public boolean getPTPCommandConfirmRequired() {
+        return getBooleanValue("Commands.ptp.Accept_Required", true);
+    }
+
+    public boolean getPTPCommandWorldPermissions() {
+        return getBooleanValue("Commands.ptp.World_Based_Permissions", false);
+    }
+
+    /* Inspect command distance */
+    public double getInspectDistance() {
+        return getDoubleValue("Commands.inspect.Max_Distance", 30.0D);
+    }
+
+    /*
+     * ABILITY SETTINGS
+     */
+
+    /* General Settings */
+    public boolean getUrlLinksEnabled() {
+        return getBooleanValue("Commands.Skills.URL_Links");
+    }
+
+    public boolean getAbilityMessagesEnabled() {
+        return getBooleanValue("Abilities.Messages", true);
+    }
+
+    public boolean getAbilitiesEnabled() {
+        return getBooleanValue("Abilities.Enabled", true);
+    }
+
+    public boolean getAbilitiesOnlyActivateWhenSneaking() {
+        return getBooleanValue("Abilities.Activation.Only_Activate_When_Sneaking", false);
+    }
+
+    public boolean getAbilitiesGateEnabled() {
+        return getBooleanValue("Abilities.Activation.Level_Gate_Abilities");
+    }
+
+    public int getCooldown(SuperAbilityType ability) {
+        return getIntValue("Abilities.Cooldowns." + ability.toString());
+    }
+
+    public int getMaxLength(SuperAbilityType ability) {
+        return getIntValue("Abilities.Max_Seconds." + ability.toString());
+    }
+
+    /* Durability Settings */
+    public int getAbilityToolDamage() {
+        return getIntValue("Abilities.Tools.Durability_Loss", 1);
+    }
+
+    /* Thresholds */
+    public int getTreeFellerThreshold() {
+        return getIntValue("Abilities.Limits.Tree_Feller_Threshold", 500);
+    }
+
+    /*
+     * SKILL SETTINGS
+     */
+    public boolean getDoubleDropsEnabled(PrimarySkillType skill, Material material) {
+        return getBooleanValue("Double_Drops." + StringUtils.getCapitalized(skill.toString()) + "." + StringUtils.getPrettyItemString(material).replace(" ", "_"));
+    }
+
+    public boolean getDoubleDropsDisabled(PrimarySkillType skill) {
+        String skillName = StringUtils.getCapitalized(skill.toString());
+        ConfigurationSection section = config.getConfigurationSection("Double_Drops." + skillName);
+        if (section == null)
+            return false;
+        Set<String> keys = section.getKeys(false);
+        boolean disabled = true;
+
+        for (String key : keys) {
+            if (getBooleanValue("Double_Drops." + skillName + "." + key)) {
+                disabled = false;
+                break;
+            }
+        }
+
+        return disabled;
+    }
+
+    /* Axes */
+    public int getAxesGate() {
+        return getIntValue("Skills.Axes.Ability_Activation_Level_Gate", 10);
+    }
+
+    /* Acrobatics */
+    public boolean getDodgeLightningDisabled() {
+        return getBooleanValue("Skills.Acrobatics.Prevent_Dodge_Lightning", false);
+    }
+
+    public int getXPAfterTeleportCooldown() {
+        return getIntValue("Skills.Acrobatics.XP_After_Teleport_Cooldown", 5);
+    }
+
+    /* Alchemy */
+    public boolean getEnabledForHoppers() {
+        return getBooleanValue("Skills.Alchemy.Enabled_for_Hoppers", true);
+    }
+
+    public boolean getPreventHopperTransferIngredients() {
+        return getBooleanValue("Skills.Alchemy.Prevent_Hopper_Transfer_Ingredients", false);
+    }
+
+    public boolean getPreventHopperTransferBottles() {
+        return getBooleanValue("Skills.Alchemy.Prevent_Hopper_Transfer_Bottles", false);
+    }
+
+    /* Fishing */
+    public boolean getFishingDropsEnabled() {
+        return getBooleanValue("Skills.Fishing.Drops_Enabled", true);
+    }
+
+    public boolean getFishingOverrideTreasures() {
+        return getBooleanValue("Skills.Fishing.Override_Vanilla_Treasures", true);
+    }
+
+    public boolean getFishingExtraFish() {
+        return getBooleanValue("Skills.Fishing.Extra_Fish", true);
+    }
+
+    public double getFishingLureModifier() {
+        return getDoubleValue("Skills.Fishing.Lure_Modifier", 4.0D);
+    }
+
+    /* Mining */
+    public Material getDetonatorItem() {
+        return Material.matchMaterial(getStringValue("Skills.Mining.Detonator_Name", "FLINT_AND_STEEL"));
+    }
+
+    public int getMiningGate() {
+        return getIntValue("Skills.Mining.Ability_Activation_Level_Gate", 10);
+    }
+
+    /* Excavation */
+    public int getExcavationGate() {
+        return getIntValue("Skills.Excavation.Ability_Activation_Level_Gate", 10);
+    }
+
+    /* Repair */
+    public boolean getRepairAnvilMessagesEnabled() {
+        return getBooleanValue("Skills.Repair.Anvil_Messages", true);
+    }
+
+    public boolean getRepairAnvilPlaceSoundsEnabled() {
+        return getBooleanValue("Skills.Repair.Anvil_Placed_Sounds", true);
+    }
+
+    public boolean getRepairAnvilUseSoundsEnabled() {
+        return getBooleanValue("Skills.Repair.Anvil_Use_Sounds", true);
+    }
+
+    public Material getRepairAnvilMaterial() {
+        return Material.matchMaterial(getStringValue("Skills.Repair.Anvil_Material", "IRON_BLOCK"));
+    }
+
+    public boolean getRepairConfirmRequired() {
+        return getBooleanValue("Skills.Repair.Confirm_Required", true);
+    }
+
+    /* Salvage */
+    public boolean getSalvageAnvilMessagesEnabled() {
+        return getBooleanValue("Skills.Salvage.Anvil_Messages", true);
+    }
+
+    public boolean getSalvageAnvilPlaceSoundsEnabled() {
+        return getBooleanValue("Skills.Salvage.Anvil_Placed_Sounds", true);
+    }
+
+    public boolean getSalvageAnvilUseSoundsEnabled() {
+        return getBooleanValue("Skills.Salvage.Anvil_Use_Sounds", true);
+    }
+
+    public Material getSalvageAnvilMaterial() {
+        return Material.matchMaterial(getStringValue("Skills.Salvage.Anvil_Material", "GOLD_BLOCK"));
+    }
+
+    public boolean getSalvageConfirmRequired() {
+        return getBooleanValue("Skills.Salvage.Confirm_Required", true);
+    }
+
+    /* Unarmed */
+    public boolean getUnarmedBlockCrackerSmoothbrickToCracked() {
+        return getBooleanValue("Skills.Unarmed.Block_Cracker.SmoothBrick_To_CrackedBrick", true);
+    }
+
+    public boolean getUnarmedItemPickupDisabled() {
+        return getBooleanValue("Skills.Unarmed.Item_Pickup_Disabled_Full_Inventory", true);
+    }
+
+    public boolean getUnarmedItemsAsUnarmed() {
+        return getBooleanValue("Skills.Unarmed.Items_As_Unarmed", false);
+    }
+
+    public int getUnarmedGate() {
+        return getIntValue("Skills.Unarmed.Ability_Activation_Level_Gate", 10);
+    }
+
+    /* Swords */
+    public int getSwordsGate() {
+        return getIntValue("Skills.Swords.Ability_Activation_Level_Gate", 10);
+    }
+
+    /* Taming */
+    public Material getTamingCOTWMaterial(EntityType type) {
+        return Material.matchMaterial(getStringValue("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Material"));
+    }
+
+    public int getTamingCOTWCost(EntityType type) {
+        return getIntValue("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Item_Amount");
+    }
+
+    public int getTamingCOTWAmount(EntityType type) {
+        return getIntValue("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Summon_Amount");
+    }
+
+    public int getTamingCOTWLength(EntityType type) {
+        return getIntValue("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Summon_Length");
+    }
+
+    public int getTamingCOTWMaxAmount(EntityType type) {
+        return getIntValue("Skills.Taming.Call_Of_The_Wild." + StringUtils.getPrettyEntityTypeString(type) + ".Summon_Max_Amount");
+    }
+
+    public double getTamingCOTWRange() {
+        return getDoubleValue("Skills.Taming.Call_Of_The_Wild.Range", 40.0D);
+    }
+
+    /* Woodcutting */
+    public boolean getWoodcuttingDoubleDropsEnabled(BlockData material) {
+        return getBooleanValue("Double_Drops.Woodcutting." + StringUtils.getFriendlyConfigBlockDataString(material));
+    }
+
+    public boolean getTreeFellerSoundsEnabled() {
+        return getBooleanValue("Skills.Woodcutting.Tree_Feller_Sounds", true);
+    }
+
+    public int getWoodcuttingGate() {
+        return getIntValue("Skills.Woodcutting.Ability_Activation_Level_Gate", 10);
+    }
+
+    /* AFK Leveling */
+    public boolean getAcrobaticsPreventAFK() {
+        return getBooleanValue("Skills.Acrobatics.Prevent_AFK_Leveling", true);
+    }
+
+    public int getAcrobaticsAFKMaxTries() {
+        return getIntValue("Skills.Acrobatics.Max_Tries_At_Same_Location", 3);
+    }
+
+    public boolean getHerbalismPreventAFK() {
+        return getBooleanValue("Skills.Herbalism.Prevent_AFK_Leveling", true);
+    }
+
+    /* Level Caps */
+    public int getPowerLevelCap() {
+        int cap = getIntValue("General.Power_Level_Cap", 0);
+        return (cap <= 0) ? Integer.MAX_VALUE : cap;
+    }
+
+    public int getLevelCap(PrimarySkillType skill) {
+        int cap = getIntValue("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Level_Cap");
+        return (cap <= 0) ? Integer.MAX_VALUE : cap;
+    }
+
+
+    /*public int isSuperAbilityUnlocked(PrimarySkillType skill) {
+        return getIntValue("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Ability_Activation_Level_Gate");
+    }*/
+
+    public boolean getTruncateSkills() {
+        return getBooleanValue("General.TruncateSkills", false);
+    }
+
+    /* PVP & PVE Settings */
+    public boolean getPVPEnabled(PrimarySkillType skill) {
+        return getBooleanValue("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Enabled_For_PVP", true);
+    }
+
+    public boolean getPVEEnabled(PrimarySkillType skill) {
+        return getBooleanValue("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Enabled_For_PVE", true);
+    }
+
+    //public float getMasterVolume() { return (float) getDoubleValue("Sounds.MasterVolume", 1.0); }
+}

+ 42 - 37
src/main/java/com/gmail/nossr50/config/RankConfig.java

@@ -2,35 +2,44 @@ package com.gmail.nossr50.config;
 
 
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
 import com.gmail.nossr50.datatypes.skills.subskills.AbstractSubSkill;
+import com.gmail.nossr50.mcMMO;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 
 
-public class RankConfig extends AutoUpdateConfigLoader {
+public class RankConfig extends ConfigValidated {
     private static RankConfig instance;
     private static RankConfig instance;
 
 
-    public RankConfig()
-    {
-        super("skillranks.yml");
-        validate();
+    public RankConfig() {
+        //super(McmmoCore.getDataFolderPath().getAbsoluteFile(),"skillranks.yml", true);
+        super(mcMMO.p.getDataFolder().getAbsoluteFile(),"skillranks.yml", true);
         this.instance = this;
         this.instance = this;
     }
     }
 
 
-    @Override
-    protected void loadKeys() {
+    public static RankConfig getInstance() {
+        if (instance == null)
+            return new RankConfig();
 
 
+        return instance;
     }
     }
 
 
-    public static RankConfig getInstance()
-    {
-        if(instance == null)
-            return new RankConfig();
+    @Override
+    public void unload() {
+        instance = null;
+    }
 
 
-        return instance;
+    /**
+     * The version of this config
+     *
+     * @return
+     */
+    @Override
+    public double getConfigVersion() {
+        return 1;
     }
     }
 
 
     @Override
     @Override
-    protected boolean validateKeys() {
+    public List<String> validateKeys() {
         List<String> reason = new ArrayList<String>();
         List<String> reason = new ArrayList<String>();
 
 
         /*
         /*
@@ -38,17 +47,17 @@ public class RankConfig extends AutoUpdateConfigLoader {
          */
          */
         checkKeys(reason);
         checkKeys(reason);
 
 
-        return noErrorsInConfig(reason);
+        return reason;
     }
     }
 
 
     /**
     /**
      * Returns the unlock level for a subskill depending on the gamemode
      * Returns the unlock level for a subskill depending on the gamemode
+     *
      * @param subSkillType target subskill
      * @param subSkillType target subskill
-     * @param rank the rank we are checking
+     * @param rank         the rank we are checking
      * @return the level requirement for a subskill at this particular rank
      * @return the level requirement for a subskill at this particular rank
      */
      */
-    public int getSubSkillUnlockLevel(SubSkillType subSkillType, int rank)
-    {
+    public int getSubSkillUnlockLevel(SubSkillType subSkillType, int rank) {
         String key = subSkillType.getRankConfigAddress();
         String key = subSkillType.getRankConfigAddress();
 
 
         return findRankByRootAddress(rank, key);
         return findRankByRootAddress(rank, key);
@@ -56,63 +65,59 @@ public class RankConfig extends AutoUpdateConfigLoader {
 
 
     /**
     /**
      * Returns the unlock level for a subskill depending on the gamemode
      * Returns the unlock level for a subskill depending on the gamemode
+     *
      * @param abstractSubSkill target subskill
      * @param abstractSubSkill target subskill
-     * @param rank the rank we are checking
+     * @param rank             the rank we are checking
      * @return the level requirement for a subskill at this particular rank
      * @return the level requirement for a subskill at this particular rank
      */
      */
-    public int getSubSkillUnlockLevel(AbstractSubSkill abstractSubSkill, int rank)
-    {
-        String key = abstractSubSkill.getPrimaryKeyName()+"."+abstractSubSkill.getConfigKeyName();
+    public int getSubSkillUnlockLevel(AbstractSubSkill abstractSubSkill, int rank) {
+        String key = abstractSubSkill.getPrimaryKeyName() + "." + abstractSubSkill.getConfigKeyName();
 
 
         return findRankByRootAddress(rank, key);
         return findRankByRootAddress(rank, key);
     }
     }
 
 
     /**
     /**
      * Returns the unlock level for a subskill depending on the gamemode
      * Returns the unlock level for a subskill depending on the gamemode
-     * @param key root address of the subskill in the rankskills.yml file
+     *
+     * @param key  root address of the subskill in the rankskills.yml file
      * @param rank the rank we are checking
      * @param rank the rank we are checking
      * @return the level requirement for a subskill at this particular rank
      * @return the level requirement for a subskill at this particular rank
      */
      */
     private int findRankByRootAddress(int rank, String key) {
     private int findRankByRootAddress(int rank, String key) {
-        String scalingKey = Config.getInstance().getIsRetroMode() ? ".RetroMode." : ".Standard.";
+        String scalingKey = MainMainConfig.getInstance().getIsRetroMode() ? ".RetroMode." : ".Standard.";
 
 
         String targetRank = "Rank_" + rank;
         String targetRank = "Rank_" + rank;
 
 
         key += scalingKey;
         key += scalingKey;
         key += targetRank;
         key += targetRank;
 
 
-        return config.getInt(key);
+        return getIntValue(key);
     }
     }
 
 
     /**
     /**
      * Checks for valid keys for subskill ranks
      * Checks for valid keys for subskill ranks
      */
      */
-    private void checkKeys(List<String> reasons)
-    {
+    private void checkKeys(List<String> reasons) {
         //For now we will only check ranks of stuff I've overhauled
         //For now we will only check ranks of stuff I've overhauled
-        for(SubSkillType subSkillType : SubSkillType.values())
-        {
+        for (SubSkillType subSkillType : SubSkillType.values()) {
             //Keeping track of the rank requirements and making sure there are no logical errors
             //Keeping track of the rank requirements and making sure there are no logical errors
             int curRank = 0;
             int curRank = 0;
             int prevRank = 0;
             int prevRank = 0;
 
 
-            for(int x = 0; x < subSkillType.getNumRanks(); x++)
-            {
-                if(curRank > 0)
+            for (int x = 0; x < subSkillType.getNumRanks(); x++) {
+                if (curRank > 0)
                     prevRank = curRank;
                     prevRank = curRank;
 
 
                 curRank = getSubSkillUnlockLevel(subSkillType, x);
                 curRank = getSubSkillUnlockLevel(subSkillType, x);
 
 
                 //Do we really care if its below 0? Probably not
                 //Do we really care if its below 0? Probably not
-                if(curRank < 0)
-                {
-                    reasons.add(subSkillType.getAdvConfigAddress() + ".Rank_Levels.Rank_"+curRank+".LevelReq should be above or equal to 0!");
+                if (curRank < 0) {
+                    reasons.add(subSkillType.getAdvConfigAddress() + ".Rank_Levels.Rank_" + curRank + ".LevelReq should be above or equal to 0!");
                 }
                 }
 
 
-                if(prevRank > curRank)
-                {
+                if (prevRank > curRank) {
                     //We're going to allow this but we're going to warn them
                     //We're going to allow this but we're going to warn them
-                    plugin.getLogger().info("You have the ranks for the subskill "+ subSkillType.toString()+" set up poorly, sequential ranks should have ascending requirements");
+                    plugin.getLogger().info("You have the ranks for the subskill " + subSkillType.toString() + " set up poorly, sequential ranks should have ascending requirements");
                 }
                 }
             }
             }
         }
         }

+ 11 - 0
src/main/java/com/gmail/nossr50/config/RegistersKeys.java

@@ -0,0 +1,11 @@
+package com.gmail.nossr50.config;
+
+/**
+ * A class that registers keys
+ */
+public interface RegistersKeys {
+    /**
+     * Loads up keys
+     */
+    void loadKeys();
+}

+ 47 - 39
src/main/java/com/gmail/nossr50/config/SoundConfig.java

@@ -1,70 +1,78 @@
 package com.gmail.nossr50.config;
 package com.gmail.nossr50.config;
 
 
+import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.sounds.SoundType;
 import com.gmail.nossr50.util.sounds.SoundType;
 
 
-public class SoundConfig extends AutoUpdateConfigLoader {
+import java.util.ArrayList;
+import java.util.List;
+
+public class SoundConfig extends ConfigValidated {
     private static SoundConfig instance;
     private static SoundConfig instance;
 
 
-    public SoundConfig()
-    {
-        super("sounds.yml");
-        validate();
+    public SoundConfig() {
+        //super(McmmoCore.getDataFolderPath().getAbsoluteFile(), "sounds.yml", true);
+        super(mcMMO.p.getDataFolder().getAbsoluteFile(), "sounds.yml", true);
         this.instance = this;
         this.instance = this;
     }
     }
 
 
-    @Override
-    protected void loadKeys() {
+    public static SoundConfig getInstance() {
+        if (instance == null)
+            return new SoundConfig();
 
 
+        return instance;
     }
     }
 
 
-    public static SoundConfig getInstance()
-    {
-        if(instance == null)
-            return new SoundConfig();
+    @Override
+    public void unload() {
+        instance = null;
+    }
 
 
-        return instance;
+    /**
+     * The version of this config
+     *
+     * @return
+     */
+    @Override
+    public double getConfigVersion() {
+        return 1;
     }
     }
 
 
     @Override
     @Override
-    protected boolean validateKeys() {
-        for(SoundType soundType : SoundType.values())
-        {
-            if(config.getDouble("Sounds."+soundType.toString()+".Volume") < 0)
-            {
-                plugin.getLogger().info("[mcMMO] Sound volume cannot be below 0 for "+soundType.toString());
-                return false;
+    public List<String> validateKeys() {
+        ArrayList<String> reasons = new ArrayList<>();
+
+        for (SoundType soundType : SoundType.values()) {
+            if (getDoubleValue("Sounds." + soundType.toString() + ".Volume") < 0) {
+                reasons.add("[mcMMO] Sound volume cannot be below 0 for " + soundType.toString());
             }
             }
 
 
             //Sounds with custom pitching don't use pitch values
             //Sounds with custom pitching don't use pitch values
-            if(!soundType.usesCustomPitch())
-            {
-                if(config.getDouble("Sounds."+soundType.toString()+".Pitch") < 0)
-                {
-                    plugin.getLogger().info("[mcMMO] Sound pitch cannot be below 0 for "+soundType.toString());
-                    return false;
+            if (!soundType.usesCustomPitch()) {
+                if (getDoubleValue("Sounds." + soundType.toString() + ".Pitch") < 0) {
+                    reasons.add("[mcMMO] Sound pitch cannot be below 0 for " + soundType.toString());
                 }
                 }
             }
             }
         }
         }
-        return true;
+
+        return reasons;
     }
     }
 
 
-    public float getMasterVolume() { return (float) config.getDouble("Sounds.MasterVolume", 1.0); }
+    public float getMasterVolume() {
+        return (float) getDoubleValue("Sounds.MasterVolume");
+    }
 
 
-    public float getVolume(SoundType soundType)
-    {
-        String key = "Sounds."+soundType.toString()+".Volume";
-        return (float) config.getDouble(key);
+    public float getVolume(SoundType soundType) {
+        String key = "Sounds." + soundType.toString() + ".Volume";
+        return (float) getDoubleValue(key);
     }
     }
 
 
-    public float getPitch(SoundType soundType)
-    {
-        String key = "Sounds."+soundType.toString()+".Pitch";
-        return (float) config.getDouble(key);
+    public float getPitch(SoundType soundType) {
+        String key = "Sounds." + soundType.toString() + ".Pitch";
+        return (float) getDoubleValue(key);
     }
     }
 
 
-    public boolean getIsEnabled(SoundType soundType)
-    {
-        String key = "Sounds."+soundType.toString()+".Enabled";
-        return config.getBoolean(key, true);
+    public boolean getIsEnabled(SoundType soundType) {
+        String key = "Sounds." + soundType.toString() + ".Enabled";
+        return getBooleanValue(key, true);
     }
     }
 }
 }

+ 8 - 0
src/main/java/com/gmail/nossr50/config/Unload.java

@@ -0,0 +1,8 @@
+package com.gmail.nossr50.config;
+
+/**
+ * Unloads values, sort of like a constructor
+ */
+public interface Unload {
+    void unload();
+}

+ 12 - 0
src/main/java/com/gmail/nossr50/config/VersionedConfig.java

@@ -0,0 +1,12 @@
+package com.gmail.nossr50.config;
+
+/**
+ * Represents a config that is version checked
+ */
+public interface VersionedConfig {
+    /**
+     * The version of this config
+     * @return
+     */
+    double getConfigVersion();
+}

+ 23 - 28
src/main/java/com/gmail/nossr50/config/WorldBlacklist.java

@@ -1,5 +1,6 @@
 package com.gmail.nossr50.config;
 package com.gmail.nossr50.config;
 
 
+
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import org.bukkit.World;
 import org.bukkit.World;
 
 
@@ -11,24 +12,31 @@ import java.util.ArrayList;
  */
  */
 public class WorldBlacklist {
 public class WorldBlacklist {
     private static ArrayList<String> blacklist;
     private static ArrayList<String> blacklist;
-    private mcMMO plugin;
-
     private final String blackListFileName = "world_blacklist.txt";
     private final String blackListFileName = "world_blacklist.txt";
 
 
-    public WorldBlacklist(mcMMO plugin)
-    {
-        this.plugin = plugin;
+    public WorldBlacklist() {
         blacklist = new ArrayList<>();
         blacklist = new ArrayList<>();
         init();
         init();
     }
     }
 
 
-    public void init()
-    {
+    public static boolean isWorldBlacklisted(World world) {
+
+        for (String s : blacklist) {
+            if (world.getName().equalsIgnoreCase(s))
+                return true;
+        }
+
+        return false;
+    }
+
+    public void init() {
         //Make the blacklist file if it doesn't exist
         //Make the blacklist file if it doesn't exist
-        File blackListFile = new File(plugin.getDataFolder() + File.separator + blackListFileName);
+        //TODO: Check if this works
+        File blackListFile = new File(mcMMO.p.getDataFolder().getAbsolutePath() + File.separator + blackListFileName);
+        //File blackListFile = new File(McmmoCore.getDataFolderPath().getAbsoluteFile() + File.separator + blackListFileName);
 
 
         try {
         try {
-            if(!blackListFile.exists())
+            if (!blackListFile.exists())
                 blackListFile.createNewFile();
                 blackListFile.createNewFile();
         } catch (IOException e) {
         } catch (IOException e) {
             e.printStackTrace();
             e.printStackTrace();
@@ -46,12 +54,11 @@ public class WorldBlacklist {
 
 
             String currentLine;
             String currentLine;
 
 
-            while((currentLine = bufferedReader.readLine()) != null)
-            {
-                if(currentLine.length() == 0)
+            while ((currentLine = bufferedReader.readLine()) != null) {
+                if (currentLine.length() == 0)
                     continue;
                     continue;
 
 
-                if(!blacklist.contains(currentLine))
+                if (!blacklist.contains(currentLine))
                     blacklist.add(currentLine);
                     blacklist.add(currentLine);
             }
             }
 
 
@@ -60,23 +67,11 @@ public class WorldBlacklist {
             fileReader.close();
             fileReader.close();
         } catch (FileNotFoundException e) {
         } catch (FileNotFoundException e) {
             e.printStackTrace();
             e.printStackTrace();
-        } catch (IOException e)
-        {
+        } catch (IOException e) {
             e.printStackTrace();
             e.printStackTrace();
         }
         }
 
 
-        plugin.getLogger().info(blacklist.size()+" entries in mcMMO World Blacklist");
-    }
-
-    public static boolean isWorldBlacklisted(World world)
-    {
-
-        for(String s : blacklist)
-        {
-            if(world.getName().equalsIgnoreCase(s))
-                return true;
-        }
-
-        return false;
+        //McmmoCore.getLogger().info(blacklist.size() + " entries in mcMMO World Blacklist");
+        mcMMO.p.getLogger().info(blacklist.size() + " entries in mcMMO World Blacklist");
     }
     }
 }
 }

+ 6 - 0
src/main/java/com/gmail/nossr50/config/collectionconfigs/CollectionClassType.java

@@ -0,0 +1,6 @@
+package com.gmail.nossr50.config.collectionconfigs;
+
+public enum CollectionClassType {
+    REPAIR,
+    SALVAGE;
+}

+ 119 - 0
src/main/java/com/gmail/nossr50/config/collectionconfigs/MultiConfigManager.java

@@ -0,0 +1,119 @@
+package com.gmail.nossr50.config.collectionconfigs;
+
+import com.gmail.nossr50.config.ConfigCollection;
+import com.gmail.nossr50.config.ConfigCollections;
+import com.gmail.nossr50.mcMMO;
+import com.gmail.nossr50.skills.repair.repairables.Repairable;
+import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * Represents a collection of config files that serve a similar purpose
+ * For example, files named repair.*.yml are all loaded into memory, this lets admins keep their config files clean
+ *
+ * To be honest I'm not sure how many people make use of this system, but I'm keeping it since its been in mcMMO for like 6+ years
+ */
+public final class MultiConfigManager {
+
+    public static final String DEFAULT_MULTICONFIG_FILENAME_SUFFIX = ".vanilla.yml";
+
+    //Configs
+    public com.gmail.nossr50.config.collectionconfigs.RepairConfig vanillaRepairConfig; //This is the main config file that mcMMO will copy out
+    public com.gmail.nossr50.config.collectionconfigs.SalvageConfig vanillaSalvageConfig;
+
+    private static List<Repairable> repairables;
+    private static List<Salvageable> salvageables;
+
+    public MultiConfigManager(String fileNamePrefix)
+    {
+        //init Collections
+        repairables = new ArrayList<>();
+        salvageables = new ArrayList<>();
+
+        //init vanilla configs
+        vanillaRepairConfig = new com.gmail.nossr50.config.collectionconfigs.RepairConfig(getVanillaConfigName("repair"));
+        vanillaSalvageConfig = new com.gmail.nossr50.config.collectionconfigs.SalvageConfig(getVanillaConfigName("salvage"));
+
+        //add valid vanilla collections to main collection
+        repairables.addAll(vanillaRepairConfig.getLoadedCollection());
+        salvageables.addAll(vanillaSalvageConfig.getLoadedCollection());
+
+        //add valid custom collections to main collection
+        loadCustomCollections("repair", repairables, com.gmail.nossr50.config.collectionconfigs.RepairConfig.class);
+        loadCustomCollections("salvage", salvageables, com.gmail.nossr50.config.collectionconfigs.SalvageConfig.class);
+    }
+
+    /**
+     * mcMMO allows collection config files to be named things like repair.whatevernameyouwanthere.yml and so on,
+     *  these files are treated in the same way as the vanilla file. They serve the purpose of organization
+     * @param configPrefix the prefix of the file name, for example "repair", "salvage", etc
+     * @param collection the collection that will be added to
+     */
+    public void loadCustomCollections(String configPrefix, Collection<?> collection, Class<? extends ConfigCollection> configClass)
+    {
+        String vanillaConfigFileName = getVanillaConfigName(configPrefix);
+
+        //Find other files
+        Pattern pattern = Pattern.compile(configPrefix+"\\.(?:.+)\\.yml");
+        //File dataFolder = McmmoCore.getDataFolderPath();
+        File dataFolder = mcMMO.p.getDataFolder();
+
+        for (String fileName : dataFolder.list()) {
+            //Vanilla Config is already loaded
+            if(fileName.equalsIgnoreCase(vanillaConfigFileName))
+                continue;
+
+            //Find files that match the pattern
+            if (!pattern.matcher(fileName).matches()) {
+                continue;
+            }
+
+            //Init file
+            File currentFile = new File(dataFolder, fileName);
+
+            //Make sure its not a directory (needed?)
+            if(currentFile.isDirectory())
+                continue;
+
+            try {
+                //TODO: Valid?
+                ConfigCollections customConfig = (ConfigCollections) getConfigClass(configPrefix).getConstructor(String.class).newInstance(configPrefix);
+                collection.addAll(customConfig.getLoadedCollection());
+
+            } catch (InstantiationException e) {
+                e.printStackTrace();
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            } catch (InvocationTargetException e) {
+                e.printStackTrace();
+            } catch (NoSuchMethodException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private String getVanillaConfigName(String configPrefix)
+    {
+        return configPrefix+DEFAULT_MULTICONFIG_FILENAME_SUFFIX;
+    }
+
+    private Class getConfigClass(String configPrefix)
+    {
+        switch(configPrefix) {
+            case "repair":
+                return RepairConfig.class;
+            case "salvage":
+                return SalvageConfig.class;
+            default:
+                mcMMO.p.getLogger().severe("[DEBUG] Config Class is null!");
+                return null;
+        }
+    }
+
+}

+ 185 - 0
src/main/java/com/gmail/nossr50/config/collectionconfigs/RepairConfig.java

@@ -0,0 +1,185 @@
+package com.gmail.nossr50.config.collectionconfigs;
+
+import com.gmail.nossr50.config.ConfigCollections;
+import com.gmail.nossr50.datatypes.skills.MaterialType;
+import com.gmail.nossr50.skills.repair.repairables.Repairable;
+import com.gmail.nossr50.skills.repair.repairables.RepairableFactory;
+import com.gmail.nossr50.util.ItemUtils;
+import com.gmail.nossr50.util.skills.SkillUtils;
+import com.sk89q.worldedit.InvalidItemException;
+import ninja.leaping.configurate.ConfigurationNode;
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This config
+ */
+public class RepairConfig extends ConfigCollections {
+    private List<Repairable> repairables;
+
+    public RepairConfig(String fileName) {
+        super(McmmoCore.getDataFolderPath().getAbsoluteFile(), fileName, false);
+    }
+
+    @Override
+    public void unload() {
+        repairables = null;
+    }
+
+    @Override
+    public Collection getLoadedCollection() {
+        return repairables == null ? new ArrayList<Repairable>() : repairables;
+    }
+
+    /**
+     * The version of this config
+     *
+     * @return
+     */
+    @Override
+    public double getConfigVersion() {
+        return 1;
+    }
+
+    @Override
+    public void loadKeys() {
+        repairables = new ArrayList<Repairable>();
+
+        ConfigurationNode repairablesNode = getUserRootNode().getNode("Repairables");
+        List<? extends ConfigurationNode> repairablesNodeChildrenList = repairablesNode.getChildrenList();
+        Iterator<? extends ConfigurationNode> configIter = repairablesNodeChildrenList.iterator();
+
+        for(Iterator<? extends ConfigurationNode> i = repairablesNodeChildrenList.iterator(); i.hasNext();)
+        {
+            ConfigurationNode iterNode = i.next();
+            //TODO: Verify that this is getting the key
+            String key = iterNode.getKey().toString(); //Get the String of the node
+
+            // Validate all the things!
+            List<String> reason = new ArrayList<String>();
+
+            try {
+                // ItemStack Material
+                ConfigItemCategory configItemCategory = ItemUtils.matchItemType(key);
+            } catch (InvalidItemException e) {
+                e.printStackTrace();
+            }
+
+            if (itemType == null) {
+                reason.add("Invalid material: " + key);
+            }
+
+            // Repair Material Type
+            MaterialType repairMaterialType = MaterialType.OTHER;
+            String repairMaterialTypeString = getStringValue("Repairables." + key + ".MaterialType", "OTHER");
+
+            if (!config.contains("Repairables." + key + ".MaterialType") && itemType != null) {
+                ItemStack repairItem = ItemStack.makeNew(itemType);
+
+                if (ItemUtils.isWoodTool(repairItem)) {
+                    repairMaterialType = MaterialType.WOOD;
+                } else if (ItemUtils.isStoneTool(repairItem)) {
+                    repairMaterialType = MaterialType.STONE;
+                } else if (ItemUtils.isStringTool(repairItem)) {
+                    repairMaterialType = MaterialType.STRING;
+                } else if (ItemUtils.isLeatherArmor(repairItem)) {
+                    repairMaterialType = MaterialType.LEATHER;
+                } else if (ItemUtils.isIronArmor(repairItem) || ItemUtils.isIronTool(repairItem)) {
+                    repairMaterialType = MaterialType.IRON;
+                } else if (ItemUtils.isGoldArmor(repairItem) || ItemUtils.isGoldTool(repairItem)) {
+                    repairMaterialType = MaterialType.GOLD;
+                } else if (ItemUtils.isDiamondArmor(repairItem) || ItemUtils.isDiamondTool(repairItem)) {
+                    repairMaterialType = MaterialType.DIAMOND;
+                }
+            } else {
+                try {
+                    repairMaterialType = MaterialType.valueOf(repairMaterialTypeString);
+                } catch (IllegalArgumentException ex) {
+                    reason.add(key + " has an invalid MaterialType of " + repairMaterialTypeString);
+                }
+            }
+
+            // Repair Material
+            String repairMaterialName = getStringValue("Repairables." + key + ".RepairMaterial");
+            Material repairMaterial = (repairMaterialName == null ? repairMaterialType.getDefaultMaterial() : Material.matchMaterial(repairMaterialName));
+
+            if (repairMaterial == null) {
+                reason.add(key + " has an invalid repair material: " + repairMaterialName);
+            }
+
+            // Maximum Durability
+            short maximumDurability = (itemType != null ? itemType.getMaxDurability() : (short) getIntValue("Repairables." + key + ".MaximumDurability"));
+
+            if (maximumDurability <= 0) {
+                maximumDurability = (short) getIntValue("Repairables." + key + ".MaximumDurability");
+            }
+
+            if (maximumDurability <= 0) {
+                reason.add("Maximum durability of " + key + " must be greater than 0!");
+            }
+
+            // ItemStack Type
+            ConfigItemCategory repairConfigItemCategory = ConfigItemCategory.OTHER;
+            String repairItemTypeString = getStringValue("Repairables." + key + ".ItemType", "OTHER");
+
+            if (!config.contains("Repairables." + key + ".ItemType") && itemType != null) {
+                ItemStack repairItem = new ItemStack(itemType);
+
+                if (ItemUtils.isMinecraftTool(repairItem)) {
+                    repairConfigItemCategory = ConfigItemCategory.TOOL;
+                } else if (ItemUtils.isArmor(repairItem)) {
+                    repairConfigItemCategory = ConfigItemCategory.ARMOR;
+                }
+            } else {
+                try {
+                    repairConfigItemCategory = ConfigItemCategory.valueOf(repairItemTypeString);
+                } catch (IllegalArgumentException ex) {
+                    reason.add(key + " has an invalid ItemType of " + repairItemTypeString);
+                }
+            }
+
+            byte repairMetadata = (byte) getIntValue("Repairables." + key + ".RepairMaterialMetadata", -1);
+            int minimumLevel = getIntValue("Repairables." + key + ".MinimumLevel");
+            double xpMultiplier = getDoubleValue("Repairables." + key + ".XpMultiplier", 1);
+
+            if (minimumLevel < 0) {
+                reason.add(key + " has an invalid MinimumLevel of " + minimumLevel);
+            }
+
+            // Minimum Quantity
+            int minimumQuantity = (itemType != null ? SkillUtils.getRepairAndSalvageQuantities(new ItemStack(itemType), repairMaterial, repairMetadata) : getIntValue("Repairables." + key + ".MinimumQuantity", 2));
+
+            if (minimumQuantity <= 0 && itemType != null) {
+                minimumQuantity = getIntValue("Repairables." + key + ".MinimumQuantity", 2);
+            }
+
+            if (minimumQuantity <= 0) {
+                reason.add("Minimum quantity of " + key + " must be greater than 0!");
+            }
+
+            if (noErrorsInRepairable(reason)) {
+                Repairable repairable = RepairableFactory.getRepairable(itemType, repairMaterial, repairMetadata, minimumLevel, minimumQuantity, maximumDurability, repairConfigItemCategory, repairMaterialType, xpMultiplier);
+                repairables.add(repairable);
+            }
+        }
+    }
+
+
+    /**
+     * Check if there are any errors for this repairable and if there are reports them to console
+     * @param issues errors related to loading a repairable
+     * @return returns true if there are no errors for this repairable
+     */
+    private boolean noErrorsInRepairable(List<String> issues) {
+        for (String issue : issues) {
+            McmmoCore.getLogger().warning(issue);
+        }
+
+        return issues.isEmpty();
+    }
+}

+ 48 - 43
src/main/java/com/gmail/nossr50/config/skills/salvage/SalvageConfig.java → src/main/java/com/gmail/nossr50/config/collectionconfigs/SalvageConfig.java

@@ -1,6 +1,6 @@
-package com.gmail.nossr50.config.skills.salvage;
+package com.gmail.nossr50.config.collectionconfigs;
 
 
-import com.gmail.nossr50.config.ConfigLoader;
+import com.gmail.nossr50.config.ConfigCollections;
 import com.gmail.nossr50.datatypes.skills.ItemType;
 import com.gmail.nossr50.datatypes.skills.ItemType;
 import com.gmail.nossr50.datatypes.skills.MaterialType;
 import com.gmail.nossr50.datatypes.skills.MaterialType;
 import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
 import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
@@ -12,15 +12,35 @@ import org.bukkit.configuration.ConfigurationSection;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
 
 
 import java.util.ArrayList;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
 import java.util.List;
 import java.util.Set;
 import java.util.Set;
 
 
-public class SalvageConfig extends ConfigLoader {
+public class SalvageConfig extends ConfigCollections {
     private List<Salvageable> salvageables;
     private List<Salvageable> salvageables;
 
 
     public SalvageConfig(String fileName) {
     public SalvageConfig(String fileName) {
-        super(fileName);
-        loadKeys();
+        super(McmmoCore.getDataFolderPath().getAbsoluteFile(), fileName, false);
+    }
+
+    @Override
+    public Collection getLoadedCollection() {
+        return salvageables == null ? new ArrayList<Salvageable>() : salvageables;
+    }
+
+    @Override
+    public void unload() {
+        salvageables = null;
+    }
+
+    /**
+     * The version of this config
+     *
+     * @return
+     */
+    @Override
+    public double getConfigVersion() {
+        return 1;
     }
     }
 
 
     @Override
     @Override
@@ -34,7 +54,7 @@ public class SalvageConfig extends ConfigLoader {
             // Validate all the things!
             // Validate all the things!
             List<String> reason = new ArrayList<String>();
             List<String> reason = new ArrayList<String>();
 
 
-            // Item Material
+            // ItemStack Material
             Material itemMaterial = Material.matchMaterial(key);
             Material itemMaterial = Material.matchMaterial(key);
 
 
             if (itemMaterial == null) {
             if (itemMaterial == null) {
@@ -43,44 +63,36 @@ public class SalvageConfig extends ConfigLoader {
 
 
             // Salvage Material Type
             // Salvage Material Type
             MaterialType salvageMaterialType = MaterialType.OTHER;
             MaterialType salvageMaterialType = MaterialType.OTHER;
-            String salvageMaterialTypeString = config.getString("Salvageables." + key + ".MaterialType", "OTHER");
+            String salvageMaterialTypeString = getStringValue("Salvageables." + key + ".MaterialType", "OTHER");
 
 
             if (!config.contains("Salvageables." + key + ".MaterialType") && itemMaterial != null) {
             if (!config.contains("Salvageables." + key + ".MaterialType") && itemMaterial != null) {
                 ItemStack salvageItem = new ItemStack(itemMaterial);
                 ItemStack salvageItem = new ItemStack(itemMaterial);
 
 
                 if (ItemUtils.isWoodTool(salvageItem)) {
                 if (ItemUtils.isWoodTool(salvageItem)) {
                     salvageMaterialType = MaterialType.WOOD;
                     salvageMaterialType = MaterialType.WOOD;
-                }
-                else if (ItemUtils.isStoneTool(salvageItem)) {
+                } else if (ItemUtils.isStoneTool(salvageItem)) {
                     salvageMaterialType = MaterialType.STONE;
                     salvageMaterialType = MaterialType.STONE;
-                }
-                else if (ItemUtils.isStringTool(salvageItem)) {
+                } else if (ItemUtils.isStringTool(salvageItem)) {
                     salvageMaterialType = MaterialType.STRING;
                     salvageMaterialType = MaterialType.STRING;
-                }
-                else if (ItemUtils.isLeatherArmor(salvageItem)) {
+                } else if (ItemUtils.isLeatherArmor(salvageItem)) {
                     salvageMaterialType = MaterialType.LEATHER;
                     salvageMaterialType = MaterialType.LEATHER;
-                }
-                else if (ItemUtils.isIronArmor(salvageItem) || ItemUtils.isIronTool(salvageItem)) {
+                } else if (ItemUtils.isIronArmor(salvageItem) || ItemUtils.isIronTool(salvageItem)) {
                     salvageMaterialType = MaterialType.IRON;
                     salvageMaterialType = MaterialType.IRON;
-                }
-                else if (ItemUtils.isGoldArmor(salvageItem) || ItemUtils.isGoldTool(salvageItem)) {
+                } else if (ItemUtils.isGoldArmor(salvageItem) || ItemUtils.isGoldTool(salvageItem)) {
                     salvageMaterialType = MaterialType.GOLD;
                     salvageMaterialType = MaterialType.GOLD;
-                }
-                else if (ItemUtils.isDiamondArmor(salvageItem) || ItemUtils.isDiamondTool(salvageItem)) {
+                } else if (ItemUtils.isDiamondArmor(salvageItem) || ItemUtils.isDiamondTool(salvageItem)) {
                     salvageMaterialType = MaterialType.DIAMOND;
                     salvageMaterialType = MaterialType.DIAMOND;
                 }
                 }
-            }
-            else {
+            } else {
                 try {
                 try {
                     salvageMaterialType = MaterialType.valueOf(salvageMaterialTypeString.replace(" ", "_").toUpperCase());
                     salvageMaterialType = MaterialType.valueOf(salvageMaterialTypeString.replace(" ", "_").toUpperCase());
-                }
-                catch (IllegalArgumentException ex) {
+                } catch (IllegalArgumentException ex) {
                     reason.add(key + " has an invalid MaterialType of " + salvageMaterialTypeString);
                     reason.add(key + " has an invalid MaterialType of " + salvageMaterialTypeString);
                 }
                 }
             }
             }
 
 
             // Salvage Material
             // Salvage Material
-            String salvageMaterialName = config.getString("Salvageables." + key + ".SalvageMaterial");
+            String salvageMaterialName = getStringValue("Salvageables." + key + ".SalvageMaterial");
             Material salvageMaterial = (salvageMaterialName == null ? salvageMaterialType.getDefaultMaterial() : Material.matchMaterial(salvageMaterialName));
             Material salvageMaterial = (salvageMaterialName == null ? salvageMaterialType.getDefaultMaterial() : Material.matchMaterial(salvageMaterialName));
 
 
             if (salvageMaterial == null) {
             if (salvageMaterial == null) {
@@ -88,47 +100,44 @@ public class SalvageConfig extends ConfigLoader {
             }
             }
 
 
             // Maximum Durability
             // Maximum Durability
-            short maximumDurability = (itemMaterial != null ? itemMaterial.getMaxDurability() : (short) config.getInt("Salvageables." + key + ".MaximumDurability"));
+            short maximumDurability = (itemMaterial != null ? itemMaterial.getMaxDurability() : (short) getIntValue("Salvageables." + key + ".MaximumDurability"));
 
 
-            // Item Type
+            // ItemStack Type
             ItemType salvageItemType = ItemType.OTHER;
             ItemType salvageItemType = ItemType.OTHER;
-            String salvageItemTypeString = config.getString("Salvageables." + key + ".ItemType", "OTHER");
+            String salvageItemTypeString = getStringValue("Salvageables." + key + ".ItemType", "OTHER");
 
 
             if (!config.contains("Salvageables." + key + ".ItemType") && itemMaterial != null) {
             if (!config.contains("Salvageables." + key + ".ItemType") && itemMaterial != null) {
                 ItemStack salvageItem = new ItemStack(itemMaterial);
                 ItemStack salvageItem = new ItemStack(itemMaterial);
 
 
                 if (ItemUtils.isMinecraftTool(salvageItem)) {
                 if (ItemUtils.isMinecraftTool(salvageItem)) {
                     salvageItemType = ItemType.TOOL;
                     salvageItemType = ItemType.TOOL;
-                }
-                else if (ItemUtils.isArmor(salvageItem)) {
+                } else if (ItemUtils.isArmor(salvageItem)) {
                     salvageItemType = ItemType.ARMOR;
                     salvageItemType = ItemType.ARMOR;
                 }
                 }
-            }
-            else {
+            } else {
                 try {
                 try {
                     salvageItemType = ItemType.valueOf(salvageItemTypeString.replace(" ", "_").toUpperCase());
                     salvageItemType = ItemType.valueOf(salvageItemTypeString.replace(" ", "_").toUpperCase());
-                }
-                catch (IllegalArgumentException ex) {
+                } catch (IllegalArgumentException ex) {
                     reason.add(key + " has an invalid ItemType of " + salvageItemTypeString);
                     reason.add(key + " has an invalid ItemType of " + salvageItemTypeString);
                 }
                 }
             }
             }
 
 
-            byte salvageMetadata = (byte) config.getInt("Salvageables." + key + ".SalvageMaterialMetadata", -1);
-            int minimumLevel = config.getInt("Salvageables." + key + ".MinimumLevel");
-            double xpMultiplier = config.getDouble("Salvageables." + key + ".XpMultiplier", 1);
+            byte salvageMetadata = (byte) getIntValue("Salvageables." + key + ".SalvageMaterialMetadata", -1);
+            int minimumLevel = getIntValue("Salvageables." + key + ".MinimumLevel");
+            double xpMultiplier = getDoubleValue("Salvageables." + key + ".XpMultiplier", 1);
 
 
             if (minimumLevel < 0) {
             if (minimumLevel < 0) {
                 reason.add(key + " has an invalid MinimumLevel of " + minimumLevel);
                 reason.add(key + " has an invalid MinimumLevel of " + minimumLevel);
             }
             }
 
 
             // Maximum Quantity
             // Maximum Quantity
-            int maximumQuantity = (itemMaterial != null ? SkillUtils.getRepairAndSalvageQuantities(new ItemStack(itemMaterial), salvageMaterial, salvageMetadata) : config.getInt("Salvageables." + key + ".MaximumQuantity", 2));
+            int maximumQuantity = (itemMaterial != null ? SkillUtils.getRepairAndSalvageQuantities(new ItemStack(itemMaterial), salvageMaterial, salvageMetadata) : getIntValue("Salvageables." + key + ".MaximumQuantity", 2));
 
 
             if (maximumQuantity <= 0 && itemMaterial != null) {
             if (maximumQuantity <= 0 && itemMaterial != null) {
-                maximumQuantity = config.getInt("Salvageables." + key + ".MaximumQuantity", 1);
+                maximumQuantity = getIntValue("Salvageables." + key + ".MaximumQuantity", 1);
             }
             }
 
 
-            int configMaximumQuantity = config.getInt("Salvageables." + key + ".MaximumQuantity", -1);
+            int configMaximumQuantity = getIntValue("Salvageables." + key + ".MaximumQuantity", -1);
 
 
             if (configMaximumQuantity > 0) {
             if (configMaximumQuantity > 0) {
                 maximumQuantity = configMaximumQuantity;
                 maximumQuantity = configMaximumQuantity;
@@ -145,10 +154,6 @@ public class SalvageConfig extends ConfigLoader {
         }
         }
     }
     }
 
 
-    protected List<Salvageable> getLoadedSalvageables() {
-        return salvageables == null ? new ArrayList<Salvageable>() : salvageables;
-    }
-
     private boolean noErrorsInSalvageable(List<String> issues) {
     private boolean noErrorsInSalvageable(List<String> issues) {
         if (!issues.isEmpty()) {
         if (!issues.isEmpty()) {
             plugin.getLogger().warning("Errors have been found in: " + fileName);
             plugin.getLogger().warning("Errors have been found in: " + fileName);

+ 258 - 139
src/main/java/com/gmail/nossr50/config/experience/ExperienceConfig.java

@@ -1,13 +1,12 @@
 package com.gmail.nossr50.config.experience;
 package com.gmail.nossr50.config.experience;
 
 
-import com.gmail.nossr50.config.AutoUpdateConfigLoader;
+import com.gmail.nossr50.config.ConfigValidated;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.skills.MaterialType;
 import com.gmail.nossr50.datatypes.skills.MaterialType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
 import com.gmail.nossr50.datatypes.skills.alchemy.PotionStage;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
-import org.bukkit.Material;
-import org.bukkit.block.data.BlockData;
+import com.sk89q.worldedit.world.block.BlockType;
 import org.bukkit.boss.BarColor;
 import org.bukkit.boss.BarColor;
 import org.bukkit.boss.BarStyle;
 import org.bukkit.boss.BarStyle;
 import org.bukkit.entity.EntityType;
 import org.bukkit.entity.EntityType;
@@ -15,12 +14,70 @@ import org.bukkit.entity.EntityType;
 import java.util.ArrayList;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 
 
-public class ExperienceConfig extends AutoUpdateConfigLoader {
+public class ExperienceConfig extends ConfigValidated {
+    public static final String EXPLOIT_FIX = "ExploitFix";
+    public static final String ENDERMAN_ENDERMITE_FARMS = "EndermanEndermiteFarms";
+    public static final String EXPERIENCE = "Experience";
+    public static final String EXPERIENCE_FORMULA = EXPERIENCE + "_Formula";
+    public static final String CURVE = "Curve";
+    public static final String VALUES = "_Values";
+    public static final String MULTIPLIER = "multiplier";
+    public static final String BASE = "base";
+    public static final String EXPONENT = "exponent";
+    public static final String MULTIPLIER1 = "Multiplier";
+    public static final String GLOBAL = "Global";
+    public static final String MOBSPAWNERS = "Mobspawners";
+    public static final String BREEDING = "Breeding";
+    public static final String MODIFIER = "Modifier";
+    public static final String CUSTOM_XP_PERK = "Custom_XP_Perk";
+    public static final String BOOST = "Boost";
+    public static final String DIMISHED_RETURNS = "Dimished_Returns";
+    public static final String GUARANTEED_MINIMUM_PERCENTAGE = "Guaranteed_Minimum_Percentage";
+    public static final String DIMINISHED_RETURNS = "Diminished_Returns";
+    public static final String ENABLE = "Enable";
+    public static final String ENABLED = ENABLE + "d";
+    public static final String TIME_INTERVAL = "Time_Interval";
+    public static final String CONVERSION = "Conversion";
+    public static final String EXP = "Exp_";
+    public static final String PVP = "PVP";
+    public static final String REWARDS = "Rewards";
+    public static final String COMBAT = "Combat";
+    public static final String ANIMALS = "Animals";
+    public static final String BARS = "_Bars";
+    public static final String UPDATE = "Update";
+    public static final String PASSIVE = "Passive";
+    public static final String THIS_MAY_CAUSE_LAG = "ThisMayCauseLag";
+    public static final String ALWAYS = "Always";
+    public static final String TITLES_WHEN_XPIS_GAINED = "TitlesWhenXPIsGained";
+    public static final String EXTRA_DETAILS = "ExtraDetails";
+    public static final String COLOR = "Color";
+    public static final String BAR_STYLE = "BarStyle";
+    public static final String ACROBATICS = "Acrobatics";
+    public static final String DODGE = "Dodge";
+    public static final String ROLL = "Roll";
+    public static final String FALL = "Fall";
+    public static final String FEATHER = "Feather";
+    public static final String ALCHEMY = "Alchemy";
+    public static final String POTION_STAGE = "Potion_Stage_";
+    public static final String ARCHERY = "Archery";
+    public static final String DISTANCE = "Distance_";
+    public static final String FISHING = "Fishing";
+    public static final String SHAKE = "Shake";
+    public static final String REPAIR = "Repair";
+    public static final String BASE1 = "Base";
+    public static final String TAMING = "Taming";
+    public static final String ANIMAL_TAMING = "Animal_Taming";
+    public static final String PARTY = "Party";
+    public static final String THRESHOLD = "Threshold";
+    public static final String CUMULATIVE = "Cumulative_";
+    public static final String OCELOT = "Ocelot";
+    public static final String WOLF = "Wolf";
+    public static final String FEATHER_FALL_MULTIPLIER = "FeatherFall_Multiplier";
     private static ExperienceConfig instance;
     private static ExperienceConfig instance;
 
 
+    //TODO: Should merge be false? Seems okay to leave it as true..
     private ExperienceConfig() {
     private ExperienceConfig() {
-        super("experience.yml");
-        validate();
+        super(McmmoCore.getDataFolderPath().getAbsoluteFile(), "experience.yml", true);
     }
     }
 
 
     public static ExperienceConfig getInstance() {
     public static ExperienceConfig getInstance() {
@@ -31,11 +88,23 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
         return instance;
         return instance;
     }
     }
 
 
+    /**
+     * The version of this config
+     *
+     * @return
+     */
+    @Override
+    public double getConfigVersion() {
+        return 1;
+    }
+
     @Override
     @Override
-    protected void loadKeys() {}
+    public void unload() {
+        instance = null; //TODO: this might be a bit problematic
+    }
 
 
     @Override
     @Override
-    protected boolean validateKeys() {
+    public List<String> validateKeys() {
         List<String> reason = new ArrayList<String>();
         List<String> reason = new ArrayList<String>();
 
 
         /*
         /*
@@ -44,40 +113,40 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
 
 
         /* Curve values */
         /* Curve values */
         if (getMultiplier(FormulaType.EXPONENTIAL) <= 0) {
         if (getMultiplier(FormulaType.EXPONENTIAL) <= 0) {
-            reason.add("Experience_Formula.Exponential_Values.multiplier should be greater than 0!");
+            reason.add(EXPERIENCE_FORMULA + ".Exponential" + VALUES + "." + MULTIPLIER + " should be greater than 0!");
         }
         }
 
 
         if (getMultiplier(FormulaType.LINEAR) <= 0) {
         if (getMultiplier(FormulaType.LINEAR) <= 0) {
-            reason.add("Experience_Formula.Linear_Values.multiplier should be greater than 0!");
+            reason.add(EXPERIENCE_FORMULA + ".Linear" + VALUES + "." + MULTIPLIER + " should be greater than 0!");
         }
         }
 
 
         if (getExponent(FormulaType.EXPONENTIAL) <= 0) {
         if (getExponent(FormulaType.EXPONENTIAL) <= 0) {
-            reason.add("Experience_Formula.Exponential_Values.exponent should be greater than 0!");
+            reason.add(EXPERIENCE_FORMULA + ".Exponential" + VALUES + "." + EXPONENT + " should be greater than 0!");
         }
         }
 
 
         /* Global modifier */
         /* Global modifier */
         if (getExperienceGainsGlobalMultiplier() <= 0) {
         if (getExperienceGainsGlobalMultiplier() <= 0) {
-            reason.add("Experience_Formula.Multiplier.Global should be greater than 0!");
+            reason.add(EXPERIENCE_FORMULA + "." + MULTIPLIER1 + "." + GLOBAL + " should be greater than 0!");
         }
         }
 
 
         /* PVP modifier */
         /* PVP modifier */
         if (getPlayerVersusPlayerXP() < 0) {
         if (getPlayerVersusPlayerXP() < 0) {
-            reason.add("Experience_Formula.Multiplier.PVP should be at least 0!");
+            reason.add(EXPERIENCE_FORMULA + "." + MULTIPLIER1 + "." + PVP + " should be at least 0!");
         }
         }
 
 
         /* Spawned Mob modifier */
         /* Spawned Mob modifier */
         if (getSpawnedMobXpMultiplier() < 0) {
         if (getSpawnedMobXpMultiplier() < 0) {
-            reason.add("Experience_Formula.Mobspawners.Multiplier should be at least 0!");
+            reason.add(EXPERIENCE_FORMULA + "." + MOBSPAWNERS + "." + MULTIPLIER1 + " should be at least 0!");
         }
         }
 
 
         /* Bred Mob modifier */
         /* Bred Mob modifier */
         if (getBredMobXpMultiplier() < 0) {
         if (getBredMobXpMultiplier() < 0) {
-            reason.add("Experience_Formula.Breeding.Multiplier should be at least 0!");
+            reason.add(EXPERIENCE_FORMULA + "." + BREEDING + "." + MULTIPLIER1 + " should be at least 0!");
         }
         }
 
 
         /* Conversion */
         /* Conversion */
         if (getExpModifier() <= 0) {
         if (getExpModifier() <= 0) {
-            reason.add("Conversion.Exp_Modifier should be greater than 0!");
+            reason.add(CONVERSION + "." + EXP + MODIFIER + " should be greater than 0!");
         }
         }
 
 
         /*
         /*
@@ -87,54 +156,54 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
         /* Alchemy */
         /* Alchemy */
         for (PotionStage potionStage : PotionStage.values()) {
         for (PotionStage potionStage : PotionStage.values()) {
             if (getPotionXP(potionStage) < 0) {
             if (getPotionXP(potionStage) < 0) {
-                reason.add("Experience.Alchemy.Potion_Stage_" + potionStage.toNumerical() + " should be at least 0!");
+                reason.add(EXPERIENCE + "." + ALCHEMY + "." + POTION_STAGE + potionStage.toNumerical() + " should be at least 0!");
             }
             }
         }
         }
 
 
         /* Archery */
         /* Archery */
         if (getArcheryDistanceMultiplier() < 0) {
         if (getArcheryDistanceMultiplier() < 0) {
-            reason.add("Experience.Archery.Distance_Multiplier should be at least 0!");
+            reason.add(EXPERIENCE + "." + ARCHERY + "." + DISTANCE + MULTIPLIER1 + " should be at least 0!");
         }
         }
 
 
         /* Combat XP Multipliers */
         /* Combat XP Multipliers */
         if (getAnimalsXP() < 0) {
         if (getAnimalsXP() < 0) {
-            reason.add("Experience.Combat.Multiplier.Animals should be at least 0!");
+            reason.add(EXPERIENCE + "." + COMBAT + "." + MULTIPLIER1 + "." + ANIMALS + " should be at least 0!");
         }
         }
 
 
         if (getDodgeXPModifier() < 0) {
         if (getDodgeXPModifier() < 0) {
-            reason.add("Skills.Acrobatics.Dodge_XP_Modifier should be at least 0!");
+            reason.add("Skills." + ACROBATICS + "." + DODGE + "_XP_" + MODIFIER + " should be at least 0!");
         }
         }
 
 
         if (getRollXPModifier() < 0) {
         if (getRollXPModifier() < 0) {
-            reason.add("Skills.Acrobatics.Roll_XP_Modifier should be at least 0!");
+            reason.add("Skills." + ACROBATICS + "." + ROLL + "_XP_" + MODIFIER + " should be at least 0!");
         }
         }
 
 
         if (getFallXPModifier() < 0) {
         if (getFallXPModifier() < 0) {
-            reason.add("Skills.Acrobatics.Fall_XP_Modifier should be at least 0!");
+            reason.add("Skills." + ACROBATICS + "." + FALL + "_XP_" + MODIFIER + " should be at least 0!");
         }
         }
 
 
         /* Fishing */
         /* Fishing */
         // TODO: Add validation for each fish type once enum is available.
         // TODO: Add validation for each fish type once enum is available.
 
 
         if (getFishingShakeXP() <= 0) {
         if (getFishingShakeXP() <= 0) {
-            reason.add("Experience.Fishing.Shake should be greater than 0!");
+            reason.add(EXPERIENCE + "." + FISHING + "." + SHAKE + " should be greater than 0!");
         }
         }
 
 
         /* Repair */
         /* Repair */
         if (getRepairXPBase() <= 0) {
         if (getRepairXPBase() <= 0) {
-            reason.add("Experience.Repair.Base should be greater than 0!");
+            reason.add(EXPERIENCE + "." + REPAIR + "." + BASE1 + " should be greater than 0!");
         }
         }
 
 
         /* Taming */
         /* Taming */
         if (getTamingXP(EntityType.WOLF) <= 0) {
         if (getTamingXP(EntityType.WOLF) <= 0) {
-            reason.add("Experience.Taming.Animal_Taming.Wolf should be greater than 0!");
+            reason.add(EXPERIENCE + "." + TAMING + "." + ANIMAL_TAMING + "." + WOLF + " should be greater than 0!");
         }
         }
 
 
         if (getTamingXP(EntityType.OCELOT) <= 0) {
         if (getTamingXP(EntityType.OCELOT) <= 0) {
-            reason.add("Experience.Taming.Animal_Taming.Ocelot should be greater than 0!");
+            reason.add(EXPERIENCE + "." + TAMING + "." + ANIMAL_TAMING + "." + OCELOT + " should be greater than 0!");
         }
         }
 
 
-        return noErrorsInConfig(reason);
+        return reason;
     }
     }
 
 
     /*
     /*
@@ -142,145 +211,177 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
      */
      */
 
 
     /* EXPLOIT TOGGLES */
     /* EXPLOIT TOGGLES */
-    public boolean isEndermanEndermiteFarmingPrevented() { return config.getBoolean("ExploitFix.EndermanEndermiteFarms", true); }
+    public boolean isEndermanEndermiteFarmingPrevented() {
+        return getBooleanValue(EXPLOIT_FIX, ENDERMAN_ENDERMITE_FARMS);
+    }
 
 
     public boolean isFishingExploitingPrevented() { return config.getBoolean("ExploitFix.Fishing", true); }
     public boolean isFishingExploitingPrevented() { return config.getBoolean("ExploitFix.Fishing", true); }
     /* Curve settings */
     /* Curve settings */
-    public FormulaType getFormulaType() { return FormulaType.getFormulaType(config.getString("Experience_Formula.Curve")); }
-    public boolean getCumulativeCurveEnabled() { return config.getBoolean("Experience_Formula.Cumulative_Curve", false); }
+    public FormulaType getFormulaType() {
+        return FormulaType.getFormulaType(getStringValue(EXPERIENCE_FORMULA, CURVE));
+    }
+
+    public boolean getCumulativeCurveEnabled() {
+        return getBooleanValue(EXPERIENCE_FORMULA, CUMULATIVE + CURVE);
+    }
 
 
     /* Curve values */
     /* Curve values */
-    public double getMultiplier(FormulaType type) { return config.getDouble("Experience_Formula." + StringUtils.getCapitalized(type.toString()) + "_Values.multiplier"); }
-    public int getBase(FormulaType type) { return config.getInt("Experience_Formula." + StringUtils.getCapitalized(type.toString()) + "_Values.base"); }
-    public double getExponent(FormulaType type) { return config.getDouble("Experience_Formula." + StringUtils.getCapitalized(type.toString()) + "_Values.exponent"); }
+    public double getMultiplier(FormulaType type) {
+        return getDoubleValue(EXPERIENCE_FORMULA, StringUtils.getCapitalized(type.toString()) + VALUES, MULTIPLIER);
+    }
+
+    public int getBase(FormulaType type) {
+        return getIntValue(EXPERIENCE_FORMULA, StringUtils.getCapitalized(type.toString()) + VALUES, BASE);
+    }
+
+    public double getExponent(FormulaType type) {
+        return getDoubleValue(EXPERIENCE_FORMULA, StringUtils.getCapitalized(type.toString()) + VALUES, EXPONENT);
+    }
 
 
     /* Global modifier */
     /* Global modifier */
-    public double getExperienceGainsGlobalMultiplier() { return config.getDouble("Experience_Formula.Multiplier.Global", 1.0); }
-    public void setExperienceGainsGlobalMultiplier(double value) { config.set("Experience_Formula.Multiplier.Global", value); }
+    public double getExperienceGainsGlobalMultiplier() {
+        return getDoubleValue(EXPERIENCE_FORMULA, MULTIPLIER1, GLOBAL);
+    }
+
+    //TODO: Rewrite this
+    /*public void setExperienceGainsGlobalMultiplier(double value) {
+        config.set(EXPERIENCE_FORMULA, MULTIPLIER1, GLOBAL, value);
+    }*/
 
 
     /* PVP modifier */
     /* PVP modifier */
-    public double getPlayerVersusPlayerXP() { return config.getDouble("Experience_Formula.Multiplier.PVP", 1.0); }
+    public double getPlayerVersusPlayerXP() {
+        return getDoubleValue(EXPERIENCE_FORMULA, MULTIPLIER1, PVP);
+    }
 
 
     /* Spawned Mob modifier */
     /* Spawned Mob modifier */
-    public double getSpawnedMobXpMultiplier() { return config.getDouble("Experience_Formula.Mobspawners.Multiplier", 0.0); }
-    public double getBredMobXpMultiplier() { return config.getDouble("Experience_Formula.Breeding.Multiplier", 1.0); }
+    public double getSpawnedMobXpMultiplier() {
+        return getDoubleValue(EXPERIENCE_FORMULA, MOBSPAWNERS, MULTIPLIER1);
+    }
+
+    public double getBredMobXpMultiplier() {
+        return getDoubleValue(EXPERIENCE_FORMULA, BREEDING, MULTIPLIER1);
+    }
 
 
     /* Skill modifiers */
     /* Skill modifiers */
-    public double getFormulaSkillModifier(PrimarySkillType skill) { return config.getDouble("Experience_Formula.Modifier." + StringUtils.getCapitalized(skill.toString())); }
+    public double getFormulaSkillModifier(PrimarySkillType skill) {
+        return getDoubleValue(EXPERIENCE_FORMULA, MODIFIER, StringUtils.getCapitalized(skill.toString()));
+    }
 
 
     /* Custom XP perk */
     /* Custom XP perk */
-    public double getCustomXpPerkBoost() { return config.getDouble("Experience_Formula.Custom_XP_Perk.Boost", 1.25); }
+    public double getCustomXpPerkBoost() {
+        return getDoubleValue(EXPERIENCE_FORMULA, CUSTOM_XP_PERK, BOOST);
+    }
 
 
     /* Diminished Returns */
     /* Diminished Returns */
-    public float getDiminishedReturnsCap() { return (float) config.getDouble("Dimished_Returns.Guaranteed_Minimum_Percentage", 0.05D); }
-    public boolean getDiminishedReturnsEnabled() { return config.getBoolean("Diminished_Returns.Enabled", false); }
-    public int getDiminishedReturnsThreshold(PrimarySkillType skill) { return config.getInt("Diminished_Returns.Threshold." + StringUtils.getCapitalized(skill.toString()), 20000); }
-    public int getDiminishedReturnsTimeInterval() { return config.getInt("Diminished_Returns.Time_Interval", 10); }
+    public float getDiminishedReturnsCap() {
+        return (float) getDoubleValue(DIMISHED_RETURNS, GUARANTEED_MINIMUM_PERCENTAGE);
+    }
+
+    public boolean getDiminishedReturnsEnabled() {
+        return getBooleanValue(DIMINISHED_RETURNS, ENABLED);
+    }
+
+    public int getDiminishedReturnsThreshold(PrimarySkillType skill) {
+        return getIntValue(DIMINISHED_RETURNS, THRESHOLD, StringUtils.getCapitalized(skill.toString()));
+    }
+
+    public int getDiminishedReturnsTimeInterval() {
+        return getIntValue(DIMINISHED_RETURNS, TIME_INTERVAL);
+    }
 
 
     /* Conversion */
     /* Conversion */
-    public double getExpModifier() { return config.getDouble("Conversion.Exp_Modifier", 1); }
+    public double getExpModifier() {
+        return getDoubleValue(CONVERSION, EXP + MODIFIER);
+    }
 
 
     /*
     /*
      * XP SETTINGS
      * XP SETTINGS
      */
      */
 
 
     /* General Settings */
     /* General Settings */
-    public boolean getExperienceGainsPlayerVersusPlayerEnabled() { return config.getBoolean("Experience.PVP.Rewards", true); }
+    public boolean getExperienceGainsPlayerVersusPlayerEnabled() {
+        return getBooleanValue(EXPERIENCE, PVP, REWARDS);
+    }
 
 
     /* Combat XP Multipliers */
     /* Combat XP Multipliers */
-    public double getCombatXP(EntityType entity) { return config.getDouble("Experience.Combat.Multiplier." + StringUtils.getPrettyEntityTypeString(entity).replace(" ", "_")); }
-    public double getAnimalsXP(EntityType entity) { return config.getDouble("Experience.Combat.Multiplier." + StringUtils.getPrettyEntityTypeString(entity).replace(" ", "_"), getAnimalsXP()); }
-    public double getAnimalsXP() { return config.getDouble("Experience.Combat.Multiplier.Animals", 1.0); }
-    public boolean hasCombatXP(EntityType entity) {return config.contains("Experience.Combat.Multiplier." + StringUtils.getPrettyEntityTypeString(entity).replace(" ", "_")); }
+    public double getCombatXP(EntityType entity) {
+        return getDoubleValue(EXPERIENCE, COMBAT, MULTIPLIER1, entity.getConfigName());
+    }
 
 
-    /* Materials  */
-    public int getXp(PrimarySkillType skill, Material data)
-    {
-        String baseString = "Experience." + StringUtils.getCapitalized(skill.toString()) + ".";
-        String explicitString = baseString + StringUtils.getExplicitConfigMaterialString(data);
-        if (config.contains(explicitString))
-            return config.getInt(explicitString);
-        String friendlyString = baseString + StringUtils.getFriendlyConfigMaterialString(data);
-        if (config.contains(friendlyString))
-            return config.getInt(friendlyString);
-        String wildcardString = baseString + StringUtils.getWildcardConfigMaterialString(data);
-        if (config.contains(wildcardString))
-            return config.getInt(wildcardString);
-        return 0;
+    public double getAnimalsXP(EntityType entity) {
+        return getDoubleValue(EXPERIENCE, COMBAT, MULTIPLIER1, entity.getConfigName());
+    }
+
+    public double getAnimalsXP() {
+        return getDoubleValue(EXPERIENCE, COMBAT, MULTIPLIER1, ANIMALS);
+    }
+
+    public boolean hasCombatXP(EntityType entity) {
+        return hasNode(EXPERIENCE, COMBAT, MULTIPLIER1, entity.getConfigName());
     }
     }
 
 
     /* Materials  */
     /* Materials  */
-    public int getXp(PrimarySkillType skill, BlockData data)
-    {
-        String baseString = "Experience." + StringUtils.getCapitalized(skill.toString()) + ".";
-        String explicitString = baseString + StringUtils.getExplicitConfigBlockDataString(data);
-        if (config.contains(explicitString))
-            return config.getInt(explicitString);
-        String friendlyString = baseString + StringUtils.getFriendlyConfigBlockDataString(data);
-        if (config.contains(friendlyString))
-            return config.getInt(friendlyString);
-        String wildcardString = baseString + StringUtils.getWildcardConfigBlockDataString(data);
-        if (config.contains(wildcardString))
-            return config.getInt(wildcardString);
-        return 0;
-    }
-
-    public boolean doesBlockGiveSkillXP(PrimarySkillType skill, Material data)
-    {
-        String baseString = "Experience." + StringUtils.getCapitalized(skill.toString()) + ".";
-        String explicitString = baseString + StringUtils.getExplicitConfigMaterialString(data);
-        if (config.contains(explicitString))
-            return true;
-        String friendlyString = baseString + StringUtils.getFriendlyConfigMaterialString(data);
-        if (config.contains(friendlyString))
-            return true;
-        String wildcardString = baseString + StringUtils.getWildcardConfigMaterialString(data);
-        return config.contains(wildcardString);
-    }
-
-    public boolean doesBlockGiveSkillXP(PrimarySkillType skill, BlockData data)
-    {
-        String baseString = "Experience." + StringUtils.getCapitalized(skill.toString()) + ".";
-        String explicitString = baseString + StringUtils.getExplicitConfigBlockDataString(data);
-        if (config.contains(explicitString))
-            return true;
-        String friendlyString = baseString + StringUtils.getFriendlyConfigBlockDataString(data);
-        if (config.contains(friendlyString))
-            return true;
-        String wildcardString = baseString + StringUtils.getWildcardConfigBlockDataString(data);
-        return config.contains(wildcardString);
+
+    /**
+     * Gets the raw XP given for breaking this block, this does not include modifiers
+     * @param skill The skill to give XP for
+     * @param blockType the type of block
+     * @return the raw amount of XP for this block before modifiers
+     */
+    public int getXp(PrimarySkillType skill, BlockType blockType) {
+        //TODO: This is going to need to be changed, this code here is only placeholder
+        String[] path = new String[]{ EXPERIENCE, StringUtils.getCapitalized(skill.toString()), blockType.getConfigName() };
+        return getIntValue(path);
+    }
+
+    /**
+     * Checks if a block gives XP
+     * This is used to determine whether or not mcMMO should track a block that is placed by a user, among other things.
+     * Note: If the block has an entry in the config that will return true even if the XP is 0, this does not check the value of the XP
+     * @param skill The skill to check for
+     * @param blockType the type of block
+     * @return true if the block does give XP
+     */
+    public boolean doesBlockGiveSkillXP(PrimarySkillType skill, BlockType blockType) {
+        //TODO: This used to support wildcard characters, seems a bit unnecessary to do so.
+        //TODO: This is going to need to be changed, this code here is only placeholder
+        String[] path = new String[] {EXPERIENCE, StringUtils.getCapitalized(skill.toString()), blockType.getConfigName()};
+        return hasNode(path);
     }
     }
 
 
     /*
     /*
      * Experience Bar Stuff
      * Experience Bar Stuff
      */
      */
 
 
-    public boolean isPartyExperienceBarsEnabled()
-    {
-        return config.getBoolean("Experience_Bars.Update.Party", true);
+    public boolean isPartyExperienceBarsEnabled() {
+        return getBooleanValue(EXPERIENCE + BARS, UPDATE, PARTY);
     }
     }
 
 
-    public boolean isPassiveGainsExperienceBarsEnabled()
-    {
-        return config.getBoolean("Experience_Bars.Update.Passive", true);
+    public boolean isPassiveGainsExperienceBarsEnabled() {
+        return getBooleanValue(EXPERIENCE + BARS, UPDATE, PASSIVE);
     }
     }
 
 
-    public boolean getDoExperienceBarsAlwaysUpdateTitle()
-    {
-        return config.getBoolean("Experience_Bars.ThisMayCauseLag.AlwaysUpdateTitlesWhenXPIsGained.Enable", false) || getAddExtraDetails();
+    public boolean getDoExperienceBarsAlwaysUpdateTitle() {
+        return getBooleanValue(EXPERIENCE + BARS, THIS_MAY_CAUSE_LAG, ALWAYS + UPDATE + TITLES_WHEN_XPIS_GAINED, ENABLE) || getAddExtraDetails();
     }
     }
 
 
-    public boolean getAddExtraDetails() { return config.getBoolean("Experience_Bars.ThisMayCauseLag.AlwaysUpdateTitlesWhenXPIsGained.ExtraDetails", false);}
-    public boolean isExperienceBarsEnabled() { return config.getBoolean("Experience_Bars.Enable", true); }
-    public boolean isExperienceBarEnabled(PrimarySkillType primarySkillType) { return config.getBoolean("Experience_Bars."+StringUtils.getCapitalized(primarySkillType.toString())+".Enable", true);}
+    public boolean getAddExtraDetails() {
+        return getBooleanValue(EXPERIENCE + BARS, THIS_MAY_CAUSE_LAG, ALWAYS + UPDATE + TITLES_WHEN_XPIS_GAINED, EXTRA_DETAILS);
+    }
 
 
-    public BarColor getExperienceBarColor(PrimarySkillType primarySkillType)
-    {
-        String colorValueFromConfig = config.getString("Experience_Bars."+StringUtils.getCapitalized(primarySkillType.toString())+".Color");
+    public boolean isExperienceBarsEnabled() {
+        return getBooleanValue(EXPERIENCE + BARS, ENABLE);
+    }
 
 
-        for(BarColor barColor : BarColor.values())
-        {
-            if(barColor.toString().equalsIgnoreCase(colorValueFromConfig))
+    public boolean isExperienceBarEnabled(PrimarySkillType primarySkillType) {
+        return getBooleanValue(EXPERIENCE + BARS, StringUtils.getCapitalized(primarySkillType.toString()), ENABLE);
+    }
+
+    public BarColor getExperienceBarColor(PrimarySkillType primarySkillType) {
+        String colorValueFromConfig = getStringValue(EXPERIENCE + BARS, StringUtils.getCapitalized(primarySkillType.toString()), COLOR);
+
+        for (BarColor barColor : BarColor.values()) {
+            if (barColor.toString().equalsIgnoreCase(colorValueFromConfig))
                 return barColor;
                 return barColor;
         }
         }
 
 
@@ -288,13 +389,11 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
         return BarColor.WHITE;
         return BarColor.WHITE;
     }
     }
 
 
-    public BarStyle getExperienceBarStyle(PrimarySkillType primarySkillType)
-    {
-        String colorValueFromConfig = config.getString("Experience_Bars."+StringUtils.getCapitalized(primarySkillType.toString())+".BarStyle");
+    public BarStyle getExperienceBarStyle(PrimarySkillType primarySkillType) {
+        String colorValueFromConfig = getStringValue(EXPERIENCE + BARS, StringUtils.getCapitalized(primarySkillType.toString()), BAR_STYLE);
 
 
-        for(BarStyle barStyle : BarStyle.values())
-        {
-            if(barStyle.toString().equalsIgnoreCase(colorValueFromConfig))
+        for (BarStyle barStyle : BarStyle.values()) {
+            if (barStyle.toString().equalsIgnoreCase(colorValueFromConfig))
                 return barStyle;
                 return barStyle;
         }
         }
 
 
@@ -303,27 +402,47 @@ public class ExperienceConfig extends AutoUpdateConfigLoader {
     }
     }
 
 
     /* Acrobatics */
     /* Acrobatics */
-    public int getDodgeXPModifier() { return config.getInt("Experience.Acrobatics.Dodge", 120); }
-    public int getRollXPModifier() { return config.getInt("Experience.Acrobatics.Roll", 80); }
-    public int getFallXPModifier() { return config.getInt("Experience.Acrobatics.Fall", 120); }
+    public int getDodgeXPModifier() {
+        return getIntValue(EXPERIENCE, ACROBATICS, DODGE);
+    }
+
+    public int getRollXPModifier() {
+        return getIntValue(EXPERIENCE, ACROBATICS, ROLL);
+    }
+
+    public int getFallXPModifier() {
+        return getIntValue(EXPERIENCE, ACROBATICS, FALL);
+    }
 
 
-    public double getFeatherFallXPModifier() { return config.getDouble("Experience.Acrobatics.FeatherFall_Multiplier", 2.0); }
+    public double getFeatherFallXPModifier() {
+        return getDoubleValue(EXPERIENCE, ACROBATICS, FEATHER_FALL_MULTIPLIER);
+    }
 
 
     /* Alchemy */
     /* Alchemy */
-    public double getPotionXP(PotionStage stage) { return config.getDouble("Experience.Alchemy.Potion_Stage_" + stage.toNumerical(), 10D); }
+    public double getPotionXP(PotionStage stage) {
+        return getDoubleValue(EXPERIENCE, ALCHEMY, POTION_STAGE + stage.toNumerical());
+    }
 
 
     /* Archery */
     /* Archery */
-    public double getArcheryDistanceMultiplier() { return config.getDouble("Experience.Archery.Distance_Multiplier", 0.025); }
+    public double getArcheryDistanceMultiplier() {
+        return getDoubleValue(EXPERIENCE, ARCHERY, DISTANCE + MULTIPLIER1);
+    }
 
 
-    public int getFishingShakeXP() { return config.getInt("Experience.Fishing.Shake", 50); }
+    public int getFishingShakeXP() {
+        return getIntValue(EXPERIENCE, FISHING, SHAKE);
+    }
 
 
     /* Repair */
     /* Repair */
-    public double getRepairXPBase() { return config.getDouble("Experience.Repair.Base", 1000.0); }
-    public double getRepairXP(MaterialType repairMaterialType) { return config.getDouble("Experience.Repair." + StringUtils.getCapitalized(repairMaterialType.toString())); }
+    public double getRepairXPBase() {
+        return getDoubleValue(EXPERIENCE, REPAIR, BASE1);
+    }
+
+    public double getRepairXP(MaterialType repairMaterialType) {
+        return getDoubleValue(EXPERIENCE, REPAIR, StringUtils.getCapitalized(repairMaterialType.toString()));
+    }
 
 
     /* Taming */
     /* Taming */
-    public int getTamingXP(EntityType type)
-    {
-        return config.getInt("Experience.Taming.Animal_Taming." + StringUtils.getPrettyEntityTypeString(type));
+    public int getTamingXP(EntityType type) {
+        return getIntValue(EXPERIENCE, TAMING, ANIMAL_TAMING, type.getConfigName());
     }
     }
 }
 }

+ 4 - 3
src/main/java/com/gmail/nossr50/config/mods/ArmorConfigManager.java

@@ -7,15 +7,16 @@ import java.io.File;
 import java.util.regex.Pattern;
 import java.util.regex.Pattern;
 
 
 public class ArmorConfigManager {
 public class ArmorConfigManager {
-    public ArmorConfigManager(mcMMO plugin) {
+    public ArmorConfigManager() {
         Pattern middlePattern = Pattern.compile("armor\\.(?:.+)\\.yml");
         Pattern middlePattern = Pattern.compile("armor\\.(?:.+)\\.yml");
         Pattern startPattern = Pattern.compile("(?:.+)\\.armor\\.yml");
         Pattern startPattern = Pattern.compile("(?:.+)\\.armor\\.yml");
-        File dataFolder = new File(mcMMO.getModDirectory());
+        //File dataFolder = new File(McmmoCore.getModDataFolderPath());
+        File dataFolder = new File(mcMMO.p.getModDirectory());
         File vanilla = new File(dataFolder, "armor.default.yml");
         File vanilla = new File(dataFolder, "armor.default.yml");
         ModManager modManager = mcMMO.getModManager();
         ModManager modManager = mcMMO.getModManager();
 
 
         if (!vanilla.exists()) {
         if (!vanilla.exists()) {
-            plugin.saveResource(vanilla.getParentFile().getName() + File.separator + "armor.default.yml", false);
+            mcMMO.p.saveResource(vanilla.getParentFile().getName() + File.separator + "armor.default.yml", false);
         }
         }
 
 
         for (String fileName : dataFolder.list()) {
         for (String fileName : dataFolder.list()) {

+ 3 - 2
src/main/java/com/gmail/nossr50/config/mods/BlockConfigManager.java

@@ -7,15 +7,16 @@ import java.io.File;
 import java.util.regex.Pattern;
 import java.util.regex.Pattern;
 
 
 public class BlockConfigManager {
 public class BlockConfigManager {
-    public BlockConfigManager(mcMMO plugin) {
+    public BlockConfigManager() {
         Pattern middlePattern = Pattern.compile("blocks\\.(?:.+)\\.yml");
         Pattern middlePattern = Pattern.compile("blocks\\.(?:.+)\\.yml");
         Pattern startPattern = Pattern.compile("(?:.+)\\.blocks\\.yml");
         Pattern startPattern = Pattern.compile("(?:.+)\\.blocks\\.yml");
+        //File dataFolder = new File(McmmoCore.getModDataFolderPath());
         File dataFolder = new File(mcMMO.getModDirectory());
         File dataFolder = new File(mcMMO.getModDirectory());
         File vanilla = new File(dataFolder, "blocks.default.yml");
         File vanilla = new File(dataFolder, "blocks.default.yml");
         ModManager modManager = mcMMO.getModManager();
         ModManager modManager = mcMMO.getModManager();
 
 
         if (!vanilla.exists()) {
         if (!vanilla.exists()) {
-            plugin.saveResource(vanilla.getParentFile().getName() + File.separator + "blocks.default.yml", false);
+            mcMMO.p.saveResource(vanilla.getParentFile().getName() + File.separator + "blocks.default.yml", false);
         }
         }
 
 
         for (String fileName : dataFolder.list()) {
         for (String fileName : dataFolder.list()) {

+ 29 - 21
src/main/java/com/gmail/nossr50/config/mods/CustomArmorConfig.java

@@ -1,8 +1,8 @@
 package com.gmail.nossr50.config.mods;
 package com.gmail.nossr50.config.mods;
 
 
-import com.gmail.nossr50.config.ConfigLoader;
-import com.gmail.nossr50.datatypes.skills.ItemType;
+import com.gmail.nossr50.config.ConfigCollections;
 import com.gmail.nossr50.datatypes.skills.MaterialType;
 import com.gmail.nossr50.datatypes.skills.MaterialType;
+import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.skills.repair.repairables.Repairable;
 import com.gmail.nossr50.skills.repair.repairables.Repairable;
 import com.gmail.nossr50.skills.repair.repairables.RepairableFactory;
 import com.gmail.nossr50.skills.repair.repairables.RepairableFactory;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
@@ -14,23 +14,31 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.List;
 import java.util.Set;
 import java.util.Set;
 
 
-public class CustomArmorConfig extends ConfigLoader {
-    private boolean needsUpdate = false;
-
-    public List<Material> customBoots       = new ArrayList<Material>();
+public class CustomArmorConfig extends ConfigCollections {
+    public List<Material> customBoots = new ArrayList<Material>();
     public List<Material> customChestplates = new ArrayList<Material>();
     public List<Material> customChestplates = new ArrayList<Material>();
-    public List<Material> customHelmets     = new ArrayList<Material>();
-    public List<Material> customLeggings    = new ArrayList<Material>();
-
+    public List<Material> customHelmets = new ArrayList<Material>();
+    public List<Material> customLeggings = new ArrayList<Material>();
     public List<Repairable> repairables = new ArrayList<Repairable>();
     public List<Repairable> repairables = new ArrayList<Repairable>();
+    private boolean needsUpdate = false;
 
 
     protected CustomArmorConfig(String fileName) {
     protected CustomArmorConfig(String fileName) {
-        super("mods", fileName);
-        loadKeys();
+        //super(McmmoCore.getDataFolderPath().getPath() + "mods", fileName, false);
+        super(mcMMO.p.getDataFolder().getPath() + "mods", fileName, false);        loadKeys();
+    }
+
+    /**
+     * The version of this config
+     *
+     * @return
+     */
+    @Override
+    public double getConfigVersion() {
+        return 1;
     }
     }
 
 
     @Override
     @Override
-    protected void loadKeys() {
+    public void loadKeys() {
         loadArmor("Boots", customBoots);
         loadArmor("Boots", customBoots);
         loadArmor("Chestplates", customChestplates);
         loadArmor("Chestplates", customChestplates);
         loadArmor("Helmets", customHelmets);
         loadArmor("Helmets", customHelmets);
@@ -68,8 +76,8 @@ public class CustomArmorConfig extends ConfigLoader {
                 continue;
                 continue;
             }
             }
 
 
-            boolean repairable = config.getBoolean(armorType + "." + armorName + ".Repairable");
-            Material repairMaterial = Material.matchMaterial(config.getString(armorType + "." + armorName + ".Repair_Material", ""));
+            boolean repairable = getBooleanValue(armorType + "." + armorName + ".Repairable");
+            Material repairMaterial = Material.matchMaterial(getStringValue(armorType + "." + armorName + ".Repair_Material", ""));
 
 
             if (repairable && (repairMaterial == null)) {
             if (repairable && (repairMaterial == null)) {
                 plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + armorName);
                 plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + armorName);
@@ -77,24 +85,24 @@ public class CustomArmorConfig extends ConfigLoader {
             }
             }
 
 
             if (repairable) {
             if (repairable) {
-                byte repairData = (byte) config.getInt(armorType + "." + armorName + ".Repair_Material_Data_Value", -1);
+                byte repairData = (byte) getIntValue(armorType + "." + armorName + ".Repair_Material_Data_Value", -1);
                 int repairQuantity = SkillUtils.getRepairAndSalvageQuantities(new ItemStack(armorMaterial), repairMaterial, repairData);
                 int repairQuantity = SkillUtils.getRepairAndSalvageQuantities(new ItemStack(armorMaterial), repairMaterial, repairData);
 
 
                 if (repairQuantity == 0) {
                 if (repairQuantity == 0) {
-                    repairQuantity = config.getInt(armorType + "." + armorName + ".Repair_Material_Quantity", 2);
+                    repairQuantity = getIntValue(armorType + "." + armorName + ".Repair_Material_Quantity", 2);
                 }
                 }
 
 
-                String repairItemName = config.getString(armorType + "." + armorName + ".Repair_Material_Pretty_Name");
-                int repairMinimumLevel = config.getInt(armorType + "." + armorName + ".Repair_MinimumLevel", 0);
-                double repairXpMultiplier = config.getDouble(armorType + "." + armorName + ".Repair_XpMultiplier", 1);
+                String repairItemName = getStringValue(armorType + "." + armorName + ".Repair_Material_Pretty_Name");
+                int repairMinimumLevel = getIntValue(armorType + "." + armorName + ".Repair_MinimumLevel", 0);
+                double repairXpMultiplier = getDoubleValue(armorType + "." + armorName + ".Repair_XpMultiplier", 1);
 
 
                 short durability = armorMaterial.getMaxDurability();
                 short durability = armorMaterial.getMaxDurability();
 
 
                 if (durability == 0) {
                 if (durability == 0) {
-                    durability = (short) config.getInt(armorType + "." + armorName + ".Durability", 70);
+                    durability = (short) getIntValue(armorType + "." + armorName + ".Durability", 70);
                 }
                 }
 
 
-                repairables.add(RepairableFactory.getRepairable(armorMaterial, repairMaterial, repairData, repairItemName, repairMinimumLevel, repairQuantity, durability, ItemType.ARMOR, MaterialType.OTHER, repairXpMultiplier));
+                repairables.add(RepairableFactory.getRepairable(armorMaterial, repairMaterial, repairData, repairItemName, repairMinimumLevel, repairQuantity, durability, ConfigItemCategory.ARMOR, MaterialType.OTHER, repairXpMultiplier));
             }
             }
 
 
             materialList.add(armorMaterial);
             materialList.add(armorMaterial);

+ 20 - 22
src/main/java/com/gmail/nossr50/config/mods/CustomBlockConfig.java

@@ -1,7 +1,8 @@
 package com.gmail.nossr50.config.mods;
 package com.gmail.nossr50.config.mods;
 
 
-import com.gmail.nossr50.config.ConfigLoader;
+import com.gmail.nossr50.config.ConfigCollections;
 import com.gmail.nossr50.datatypes.mods.CustomBlock;
 import com.gmail.nossr50.datatypes.mods.CustomBlock;
+import com.gmail.nossr50.mcMMO;
 import org.bukkit.Material;
 import org.bukkit.Material;
 import org.bukkit.configuration.ConfigurationSection;
 import org.bukkit.configuration.ConfigurationSection;
 
 
@@ -10,21 +11,20 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Set;
 import java.util.Set;
 
 
-public class CustomBlockConfig extends ConfigLoader {
-    private boolean needsUpdate = false;
-
-    public List<Material> customExcavationBlocks  = new ArrayList<>();
-    public List<Material> customHerbalismBlocks   = new ArrayList<>();
-    public List<Material> customMiningBlocks      = new ArrayList<>();
-    public List<Material> customOres              = new ArrayList<>();
-    public List<Material> customLogs              = new ArrayList<>();
-    public List<Material> customLeaves            = new ArrayList<>();
-    public List<Material> customAbilityBlocks     = new ArrayList<>();
-
+public class CustomBlockConfig extends ConfigCollections {
+    public List<Material> customExcavationBlocks = new ArrayList<>();
+    public List<Material> customHerbalismBlocks = new ArrayList<>();
+    public List<Material> customMiningBlocks = new ArrayList<>();
+    public List<Material> customOres = new ArrayList<>();
+    public List<Material> customLogs = new ArrayList<>();
+    public List<Material> customLeaves = new ArrayList<>();
+    public List<Material> customAbilityBlocks = new ArrayList<>();
     public HashMap<Material, CustomBlock> customBlockMap = new HashMap<>();
     public HashMap<Material, CustomBlock> customBlockMap = new HashMap<>();
+    private boolean needsUpdate = false;
 
 
     protected CustomBlockConfig(String fileName) {
     protected CustomBlockConfig(String fileName) {
-        super("mods", fileName);
+        //super(McmmoCore.getDataFolderPath().getPath() + "mods", fileName, false);
+        super(mcMMO.p.getDataFolder().getPath() + "mods", fileName, false);
         loadKeys();
         loadKeys();
     }
     }
 
 
@@ -78,24 +78,22 @@ public class CustomBlockConfig extends ConfigLoader {
                 continue;
                 continue;
             }
             }
 
 
-            int xp = config.getInt(skillType + "." + blockName + ".XP_Gain");
+            int xp = getIntValue(skillType + "." + blockName + ".XP_Gain");
             int smeltingXp = 0;
             int smeltingXp = 0;
 
 
-            if (skillType.equals("Mining") && config.getBoolean(skillType + "." + blockName + ".Is_Ore")) {
+            if (skillType.equals("Mining") && getBooleanValue(skillType + "." + blockName + ".Is_Ore")) {
                 customOres.add(blockMaterial);
                 customOres.add(blockMaterial);
-                smeltingXp = config.getInt(skillType + "." + blockName + ".Smelting_XP_Gain", xp / 10);
-            }
-            else if (skillType.equals("Woodcutting")) {
-                if (config.getBoolean(skillType + "." + blockName + ".Is_Log")) {
+                smeltingXp = getIntValue(skillType + "." + blockName + ".Smelting_XP_Gain", xp / 10);
+            } else if (skillType.equals("Woodcutting")) {
+                if (getBooleanValue(skillType + "." + blockName + ".Is_Log")) {
                     customLogs.add(blockMaterial);
                     customLogs.add(blockMaterial);
-                }
-                else {
+                } else {
                     customLeaves.add(blockMaterial);
                     customLeaves.add(blockMaterial);
                     xp = 0; // Leaves don't grant XP
                     xp = 0; // Leaves don't grant XP
                 }
                 }
             }
             }
 
 
-            customBlockMap.put(blockMaterial, new CustomBlock(xp, config.getBoolean(skillType + "." + blockName + ".Double_Drops_Enabled"), smeltingXp));
+            customBlockMap.put(blockMaterial, new CustomBlock(xp, getBooleanValue(skillType + "." + blockName + ".Double_Drops_Enabled"), smeltingXp));
         }
         }
     }
     }
 }
 }

+ 15 - 15
src/main/java/com/gmail/nossr50/config/mods/CustomEntityConfig.java

@@ -1,20 +1,21 @@
 package com.gmail.nossr50.config.mods;
 package com.gmail.nossr50.config.mods;
 
 
-import com.gmail.nossr50.config.ConfigLoader;
+import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.datatypes.mods.CustomEntity;
 import com.gmail.nossr50.datatypes.mods.CustomEntity;
+import com.gmail.nossr50.mcMMO;
 import org.apache.commons.lang.ClassUtils;
 import org.apache.commons.lang.ClassUtils;
 import org.bukkit.Material;
 import org.bukkit.Material;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
 
 
 import java.util.HashMap;
 import java.util.HashMap;
 
 
-public class CustomEntityConfig extends ConfigLoader {
+public class CustomEntityConfig extends Config {
     public HashMap<String, CustomEntity> customEntityClassMap = new HashMap<String, CustomEntity>();
     public HashMap<String, CustomEntity> customEntityClassMap = new HashMap<String, CustomEntity>();
-    public HashMap<String, CustomEntity> customEntityTypeMap  = new HashMap<String, CustomEntity>();
+    public HashMap<String, CustomEntity> customEntityTypeMap = new HashMap<String, CustomEntity>();
 
 
     protected CustomEntityConfig(String fileName) {
     protected CustomEntityConfig(String fileName) {
-        super("mods", fileName);
-        loadKeys();
+        //super(McmmoCore.getDataFolderPath().getPath() + "mods", fileName, false);
+        super(mcMMO.p.getDataFolder().getPath() + "mods", fileName, false);
     }
     }
 
 
     @Override
     @Override
@@ -26,26 +27,25 @@ public class CustomEntityConfig extends ConfigLoader {
 
 
         for (String entityName : config.getKeys(false)) {
         for (String entityName : config.getKeys(false)) {
             Class<?> clazz = null;
             Class<?> clazz = null;
-            String className = config.getString(entityName + ".Class", "");
+            String className = getStringValue(entityName + ".Class", "");
 
 
             try {
             try {
                 clazz = ClassUtils.getClass(className);
                 clazz = ClassUtils.getClass(className);
-            }
-            catch (ClassNotFoundException e) {
+            } catch (ClassNotFoundException e) {
                 plugin.getLogger().warning("Invalid class (" + className + ") detected for " + entityName + ".");
                 plugin.getLogger().warning("Invalid class (" + className + ") detected for " + entityName + ".");
                 plugin.getLogger().warning("This custom entity may not function properly.");
                 plugin.getLogger().warning("This custom entity may not function properly.");
             }
             }
 
 
             String entityTypeName = entityName.replace("_", ".");
             String entityTypeName = entityName.replace("_", ".");
-            double xpMultiplier = config.getDouble(entityName + ".XP_Multiplier", 1.0D);
+            double xpMultiplier = getDoubleValue(entityName + ".XP_Multiplier", 1.0D);
 
 
-            boolean canBeTamed = config.getBoolean(entityName + ".Tameable");
-            int tamingXp = config.getInt(entityName + ".Taming_XP");
+            boolean canBeTamed = getBooleanValue(entityName + ".Tameable");
+            int tamingXp = getIntValue(entityName + ".Taming_XP");
 
 
-            boolean canBeSummoned = config.getBoolean(entityName + ".CanBeSummoned");
-            Material callOfTheWildMaterial = Material.matchMaterial(config.getString(entityName + ".COTW_Material", ""));
-            byte callOfTheWildData = (byte) config.getInt(entityName + ".COTW_Material_Data");
-            int callOfTheWildAmount = config.getInt(entityName + ".COTW_Material_Amount");
+            boolean canBeSummoned = getBooleanValue(entityName + ".CanBeSummoned");
+            Material callOfTheWildMaterial = Material.matchMaterial(getStringValue(entityName + ".COTW_Material", ""));
+            byte callOfTheWildData = (byte) getIntValue(entityName + ".COTW_Material_Data");
+            int callOfTheWildAmount = getIntValue(entityName + ".COTW_Material_Amount");
 
 
             if (canBeSummoned && (callOfTheWildMaterial == null || callOfTheWildAmount == 0)) {
             if (canBeSummoned && (callOfTheWildMaterial == null || callOfTheWildAmount == 0)) {
                 plugin.getLogger().warning("Incomplete Call of the Wild information. This entity will not be able to be summoned by Call of the Wild.");
                 plugin.getLogger().warning("Incomplete Call of the Wild information. This entity will not be able to be summoned by Call of the Wild.");

+ 22 - 23
src/main/java/com/gmail/nossr50/config/mods/CustomToolConfig.java

@@ -1,9 +1,10 @@
 package com.gmail.nossr50.config.mods;
 package com.gmail.nossr50.config.mods;
 
 
-import com.gmail.nossr50.config.ConfigLoader;
+import com.gmail.nossr50.config.Config;
 import com.gmail.nossr50.datatypes.mods.CustomTool;
 import com.gmail.nossr50.datatypes.mods.CustomTool;
 import com.gmail.nossr50.datatypes.skills.ItemType;
 import com.gmail.nossr50.datatypes.skills.ItemType;
 import com.gmail.nossr50.datatypes.skills.MaterialType;
 import com.gmail.nossr50.datatypes.skills.MaterialType;
+import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.skills.repair.repairables.Repairable;
 import com.gmail.nossr50.skills.repair.repairables.Repairable;
 import com.gmail.nossr50.skills.repair.repairables.RepairableFactory;
 import com.gmail.nossr50.skills.repair.repairables.RepairableFactory;
 import com.gmail.nossr50.util.skills.SkillUtils;
 import com.gmail.nossr50.util.skills.SkillUtils;
@@ -16,22 +17,20 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Set;
 import java.util.Set;
 
 
-public class CustomToolConfig extends ConfigLoader {
-    private boolean needsUpdate = false;
-
-    public List<Material> customAxes     = new ArrayList<Material>();
-    public List<Material> customBows     = new ArrayList<Material>();
-    public List<Material> customHoes     = new ArrayList<Material>();
+public class CustomToolConfig extends Config {
+    public List<Material> customAxes = new ArrayList<Material>();
+    public List<Material> customBows = new ArrayList<Material>();
+    public List<Material> customHoes = new ArrayList<Material>();
     public List<Material> customPickaxes = new ArrayList<Material>();
     public List<Material> customPickaxes = new ArrayList<Material>();
-    public List<Material> customShovels  = new ArrayList<Material>();
-    public List<Material> customSwords   = new ArrayList<Material>();
-
+    public List<Material> customShovels = new ArrayList<Material>();
+    public List<Material> customSwords = new ArrayList<Material>();
     public HashMap<Material, CustomTool> customToolMap = new HashMap<Material, CustomTool>();
     public HashMap<Material, CustomTool> customToolMap = new HashMap<Material, CustomTool>();
-
     public List<Repairable> repairables = new ArrayList<Repairable>();
     public List<Repairable> repairables = new ArrayList<Repairable>();
+    private boolean needsUpdate = false;
 
 
     protected CustomToolConfig(String fileName) {
     protected CustomToolConfig(String fileName) {
-        super("mods", fileName);
+        //super(McmmoCore.getDataFolderPath().getPath() + "mods", fileName, false);
+        super(mcMMO.p.getDataFolder().getPath() + "mods", fileName, false);
         loadKeys();
         loadKeys();
     }
     }
 
 
@@ -76,8 +75,8 @@ public class CustomToolConfig extends ConfigLoader {
                 continue;
                 continue;
             }
             }
 
 
-            boolean repairable = config.getBoolean(toolType + "." + toolName + ".Repairable");
-            Material repairMaterial = Material.matchMaterial(config.getString(toolType + "." + toolName + ".Repair_Material", ""));
+            boolean repairable = getBooleanValue(toolType + "." + toolName + ".Repairable");
+            Material repairMaterial = Material.matchMaterial(getStringValue(toolType + "." + toolName + ".Repair_Material", ""));
 
 
             if (repairable && (repairMaterial == null)) {
             if (repairable && (repairMaterial == null)) {
                 plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + toolName);
                 plugin.getLogger().warning("Incomplete repair information. This item will be unrepairable. - " + toolName);
@@ -85,29 +84,29 @@ public class CustomToolConfig extends ConfigLoader {
             }
             }
 
 
             if (repairable) {
             if (repairable) {
-                byte repairData = (byte) config.getInt(toolType + "." + toolName + ".Repair_Material_Data_Value", -1);
+                byte repairData = (byte) getIntValue(toolType + "." + toolName + ".Repair_Material_Data_Value", -1);
                 int repairQuantity = SkillUtils.getRepairAndSalvageQuantities(new ItemStack(toolMaterial), repairMaterial, repairData);
                 int repairQuantity = SkillUtils.getRepairAndSalvageQuantities(new ItemStack(toolMaterial), repairMaterial, repairData);
 
 
                 if (repairQuantity == 0) {
                 if (repairQuantity == 0) {
-                    repairQuantity = config.getInt(toolType + "." + toolName + ".Repair_Material_Quantity", 2);
+                    repairQuantity = getIntValue(toolType + "." + toolName + ".Repair_Material_Quantity", 2);
                 }
                 }
 
 
-                String repairItemName = config.getString(toolType + "." + toolName + ".Repair_Material_Pretty_Name");
-                int repairMinimumLevel = config.getInt(toolType + "." + toolName + ".Repair_MinimumLevel", 0);
-                double repairXpMultiplier = config.getDouble(toolType + "." + toolName + ".Repair_XpMultiplier", 1);
+                String repairItemName = getStringValue(toolType + "." + toolName + ".Repair_Material_Pretty_Name");
+                int repairMinimumLevel = getIntValue(toolType + "." + toolName + ".Repair_MinimumLevel", 0);
+                double repairXpMultiplier = getDoubleValue(toolType + "." + toolName + ".Repair_XpMultiplier", 1);
 
 
                 short durability = toolMaterial.getMaxDurability();
                 short durability = toolMaterial.getMaxDurability();
 
 
                 if (durability == 0) {
                 if (durability == 0) {
-                    durability = (short) config.getInt(toolType + "." + toolName + ".Durability", 60);
+                    durability = (short) getIntValue(toolType + "." + toolName + ".Durability", 60);
                 }
                 }
 
 
                 repairables.add(RepairableFactory.getRepairable(toolMaterial, repairMaterial, repairData, repairItemName, repairMinimumLevel, repairQuantity, durability, ItemType.TOOL, MaterialType.OTHER, repairXpMultiplier));
                 repairables.add(RepairableFactory.getRepairable(toolMaterial, repairMaterial, repairData, repairItemName, repairMinimumLevel, repairQuantity, durability, ItemType.TOOL, MaterialType.OTHER, repairXpMultiplier));
             }
             }
 
 
-            double multiplier = config.getDouble(toolType + "." + toolName + ".XP_Modifier", 1.0);
-            boolean abilityEnabled = config.getBoolean(toolType + "." + toolName + ".Ability_Enabled", true);
-            int tier = config.getInt(toolType + "." + toolName + ".Tier", 1);
+            double multiplier = getDoubleValue(toolType + "." + toolName + ".XP_Modifier", 1.0);
+            boolean abilityEnabled = getBooleanValue(toolType + "." + toolName + ".Ability_Enabled", true);
+            int tier = getIntValue(toolType + "." + toolName + ".Tier", 1);
 
 
             CustomTool tool = new CustomTool(tier, abilityEnabled, multiplier);
             CustomTool tool = new CustomTool(tier, abilityEnabled, multiplier);
 
 

+ 1 - 0
src/main/java/com/gmail/nossr50/config/mods/EntityConfigManager.java

@@ -1,5 +1,6 @@
 package com.gmail.nossr50.config.mods;
 package com.gmail.nossr50.config.mods;
 
 
+
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.ModManager;
 import com.gmail.nossr50.util.ModManager;
 
 

+ 1 - 0
src/main/java/com/gmail/nossr50/config/mods/ToolConfigManager.java

@@ -1,5 +1,6 @@
 package com.gmail.nossr50.config.mods;
 package com.gmail.nossr50.config.mods;
 
 
+
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.ModManager;
 import com.gmail.nossr50.util.ModManager;
 
 

+ 9 - 6
src/main/java/com/gmail/nossr50/config/party/ItemWeightConfig.java

@@ -1,16 +1,18 @@
 package com.gmail.nossr50.config.party;
 package com.gmail.nossr50.config.party;
 
 
-import com.gmail.nossr50.config.ConfigLoader;
+import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
 import org.bukkit.Material;
 import org.bukkit.Material;
 
 
 import java.util.HashSet;
 import java.util.HashSet;
 
 
-public class ItemWeightConfig extends ConfigLoader {
+public class ItemWeightConfig extends Config {
     private static ItemWeightConfig instance;
     private static ItemWeightConfig instance;
 
 
     private ItemWeightConfig() {
     private ItemWeightConfig() {
-        super("itemweights.yml");
+        //super(McmmoCore.getDataFolderPath().getAbsoluteFile(), "itemweights.yml");
+        super(mcMMO.p.getDataFolder().getAbsoluteFile(), "itemweights.yml");
     }
     }
 
 
     public static ItemWeightConfig getInstance() {
     public static ItemWeightConfig getInstance() {
@@ -22,13 +24,13 @@ public class ItemWeightConfig extends ConfigLoader {
     }
     }
 
 
     public int getItemWeight(Material material) {
     public int getItemWeight(Material material) {
-        return config.getInt("Item_Weights." + StringUtils.getPrettyItemString(material).replace(" ", "_"), config.getInt("Item_Weights.Default"));
+        return getIntValue("Item_Weights." + StringUtils.getPrettyItemString(material).replace(" ", "_"), getIntValue("Item_Weights.Default"));
     }
     }
 
 
     public HashSet<Material> getMiscItems() {
     public HashSet<Material> getMiscItems() {
         HashSet<Material> miscItems = new HashSet<Material>();
         HashSet<Material> miscItems = new HashSet<Material>();
 
 
-        for (String item : config.getStringList("Party_Shareables.Misc_Items")) {
+        for (String item : getStringValueList("Party_Shareables.Misc_Items")) {
             Material material = Material.getMaterial(item.toUpperCase());
             Material material = Material.getMaterial(item.toUpperCase());
 
 
             if (material != null) {
             if (material != null) {
@@ -39,5 +41,6 @@ public class ItemWeightConfig extends ConfigLoader {
     }
     }
 
 
     @Override
     @Override
-    protected void loadKeys() {}
+    protected void loadKeys() {
+    }
 }
 }

+ 17 - 25
src/main/java/com/gmail/nossr50/config/skills/alchemy/PotionConfig.java

@@ -1,9 +1,8 @@
 package com.gmail.nossr50.config.skills.alchemy;
 package com.gmail.nossr50.config.skills.alchemy;
 
 
-import com.gmail.nossr50.config.ConfigLoader;
+import com.gmail.nossr50.config.ConfigCollections;
 import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
 import com.gmail.nossr50.datatypes.skills.alchemy.AlchemyPotion;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
-import org.bukkit.ChatColor;
 import org.bukkit.Color;
 import org.bukkit.Color;
 import org.bukkit.Material;
 import org.bukkit.Material;
 import org.bukkit.configuration.ConfigurationSection;
 import org.bukkit.configuration.ConfigurationSection;
@@ -15,7 +14,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 import java.util.Map;
 import java.util.Map;
 
 
-public class PotionConfig extends ConfigLoader {
+public class PotionConfig extends ConfigCollections {
     private static PotionConfig instance;
     private static PotionConfig instance;
 
 
     private List<ItemStack> concoctionsIngredientsTierOne = new ArrayList<ItemStack>();
     private List<ItemStack> concoctionsIngredientsTierOne = new ArrayList<ItemStack>();
@@ -30,7 +29,7 @@ public class PotionConfig extends ConfigLoader {
     private Map<String, AlchemyPotion> potionMap = new HashMap<String, AlchemyPotion>();
     private Map<String, AlchemyPotion> potionMap = new HashMap<String, AlchemyPotion>();
 
 
     private PotionConfig() {
     private PotionConfig() {
-        super("potions.yml");
+        super(McmmoCore.getDataFolderPath().getAbsoluteFile(),"potions.yml");
         loadKeys();
         loadKeys();
     }
     }
 
 
@@ -95,8 +94,7 @@ public class PotionConfig extends ConfigLoader {
             if (potion != null) {
             if (potion != null) {
                 potionMap.put(potionName, potion);
                 potionMap.put(potionName, potion);
                 pass++;
                 pass++;
-            }
-            else {
+            } else {
                 fail++;
                 fail++;
             }
             }
         }
         }
@@ -109,18 +107,17 @@ public class PotionConfig extends ConfigLoader {
      * Returns null if input cannot be parsed.
      * Returns null if input cannot be parsed.
      *
      *
      * @param potion_section ConfigurationSection to be parsed.
      * @param potion_section ConfigurationSection to be parsed.
-     *
      * @return Parsed AlchemyPotion.
      * @return Parsed AlchemyPotion.
      */
      */
     private AlchemyPotion loadPotion(ConfigurationSection potion_section) {
     private AlchemyPotion loadPotion(ConfigurationSection potion_section) {
         try {
         try {
-            
+
 
 
             String name = potion_section.getString("Name");
             String name = potion_section.getString("Name");
             if (name != null) {
             if (name != null) {
                 name = ChatColor.translateAlternateColorCodes('&', name);
                 name = ChatColor.translateAlternateColorCodes('&', name);
             }
             }
-            
+
             PotionData data;
             PotionData data;
             if (!potion_section.contains("PotionData")) { // Backwards config compatability
             if (!potion_section.contains("PotionData")) { // Backwards config compatability
                 short dataValue = Short.parseShort(potion_section.getName());
                 short dataValue = Short.parseShort(potion_section.getName());
@@ -130,7 +127,7 @@ public class PotionConfig extends ConfigLoader {
                 ConfigurationSection potionData = potion_section.getConfigurationSection("PotionData");
                 ConfigurationSection potionData = potion_section.getConfigurationSection("PotionData");
                 data = new PotionData(PotionType.valueOf(potionData.getString("PotionType", "WATER")), potionData.getBoolean("Extended", false), potionData.getBoolean("Upgraded", false));
                 data = new PotionData(PotionType.valueOf(potionData.getString("PotionType", "WATER")), potionData.getBoolean("Extended", false), potionData.getBoolean("Upgraded", false));
             }
             }
-            
+
             Material material = Material.POTION;
             Material material = Material.POTION;
             String mat = potion_section.getString("Material", null);
             String mat = potion_section.getString("Material", null);
             if (mat != null) {
             if (mat != null) {
@@ -155,18 +152,16 @@ public class PotionConfig extends ConfigLoader {
 
 
                     if (type != null) {
                     if (type != null) {
                         effects.add(new PotionEffect(type, duration, amplifier));
                         effects.add(new PotionEffect(type, duration, amplifier));
-                    }
-                    else {
+                    } else {
                         mcMMO.p.getLogger().warning("Failed to parse effect for potion " + name + ": " + effect);
                         mcMMO.p.getLogger().warning("Failed to parse effect for potion " + name + ": " + effect);
                     }
                     }
                 }
                 }
             }
             }
-            
+
             Color color = null;
             Color color = null;
             if (potion_section.contains("Color")) {
             if (potion_section.contains("Color")) {
                 color = Color.fromRGB(potion_section.getInt("Color"));
                 color = Color.fromRGB(potion_section.getInt("Color"));
-            }
-            else {
+            } else {
                 color = this.generateColor(effects);
                 color = this.generateColor(effects);
             }
             }
 
 
@@ -176,16 +171,14 @@ public class PotionConfig extends ConfigLoader {
                     ItemStack ingredient = loadIngredient(child);
                     ItemStack ingredient = loadIngredient(child);
                     if (ingredient != null) {
                     if (ingredient != null) {
                         children.put(ingredient, potion_section.getConfigurationSection("Children").getString(child));
                         children.put(ingredient, potion_section.getConfigurationSection("Children").getString(child));
-                    }
-                    else {
+                    } else {
                         mcMMO.p.getLogger().warning("Failed to parse child for potion " + name + ": " + child);
                         mcMMO.p.getLogger().warning("Failed to parse child for potion " + name + ": " + child);
                     }
                     }
                 }
                 }
             }
             }
 
 
             return new AlchemyPotion(material, data, name, lore, effects, color, children);
             return new AlchemyPotion(material, data, name, lore, effects, color, children);
-        }
-        catch (Exception e) {
+        } catch (Exception e) {
             mcMMO.p.getLogger().warning("Failed to load Alchemy potion: " + potion_section.getName());
             mcMMO.p.getLogger().warning("Failed to load Alchemy potion: " + potion_section.getName());
             return null;
             return null;
         }
         }
@@ -197,7 +190,6 @@ public class PotionConfig extends ConfigLoader {
      * Returns null if input cannot be parsed.
      * Returns null if input cannot be parsed.
      *
      *
      * @param ingredient String representing an ingredient.
      * @param ingredient String representing an ingredient.
-     *
      * @return Parsed ingredient.
      * @return Parsed ingredient.
      */
      */
     private ItemStack loadIngredient(String ingredient) {
     private ItemStack loadIngredient(String ingredient) {
@@ -243,7 +235,7 @@ public class PotionConfig extends ConfigLoader {
     public AlchemyPotion getPotion(String name) {
     public AlchemyPotion getPotion(String name) {
         return potionMap.get(name);
         return potionMap.get(name);
     }
     }
-    
+
     public AlchemyPotion getPotion(ItemStack item) {
     public AlchemyPotion getPotion(ItemStack item) {
         for (AlchemyPotion potion : potionMap.values()) {
         for (AlchemyPotion potion : potionMap.values()) {
             if (potion.isSimilar(item)) {
             if (potion.isSimilar(item)) {
@@ -252,7 +244,7 @@ public class PotionConfig extends ConfigLoader {
         }
         }
         return null;
         return null;
     }
     }
-    
+
     public Color generateColor(List<PotionEffect> effects) {
     public Color generateColor(List<PotionEffect> effects) {
         if (effects != null && !effects.isEmpty()) {
         if (effects != null && !effects.isEmpty()) {
             List<Color> colors = new ArrayList<Color>();
             List<Color> colors = new ArrayList<Color>();
@@ -270,7 +262,7 @@ public class PotionConfig extends ConfigLoader {
         }
         }
         return null;
         return null;
     }
     }
-    
+
     public Color calculateAverageColor(List<Color> colors) {
     public Color calculateAverageColor(List<Color> colors) {
         int red = 0;
         int red = 0;
         int green = 0;
         int green = 0;
@@ -280,8 +272,8 @@ public class PotionConfig extends ConfigLoader {
             green += color.getGreen();
             green += color.getGreen();
             blue += color.getBlue();
             blue += color.getBlue();
         }
         }
-        Color color = Color.fromRGB(red/colors.size(), green/colors.size(), blue/colors.size());
+        Color color = Color.fromRGB(red / colors.size(), green / colors.size(), blue / colors.size());
         return color;
         return color;
     }
     }
-    
+
 }
 }

+ 0 - 166
src/main/java/com/gmail/nossr50/config/skills/repair/RepairConfig.java

@@ -1,166 +0,0 @@
-package com.gmail.nossr50.config.skills.repair;
-
-import com.gmail.nossr50.config.ConfigLoader;
-import com.gmail.nossr50.datatypes.skills.ItemType;
-import com.gmail.nossr50.datatypes.skills.MaterialType;
-import com.gmail.nossr50.skills.repair.repairables.Repairable;
-import com.gmail.nossr50.skills.repair.repairables.RepairableFactory;
-import com.gmail.nossr50.util.ItemUtils;
-import com.gmail.nossr50.util.skills.SkillUtils;
-import org.bukkit.Material;
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.inventory.ItemStack;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-public class RepairConfig extends ConfigLoader {
-    private List<Repairable> repairables;
-
-    public RepairConfig(String fileName) {
-        super(fileName);
-        loadKeys();
-    }
-
-    @Override
-    protected void loadKeys() {
-        repairables = new ArrayList<Repairable>();
-
-        ConfigurationSection section = config.getConfigurationSection("Repairables");
-        Set<String> keys = section.getKeys(false);
-
-        for (String key : keys) {
-            if (config.contains("Repairables." + key + ".ItemId")) {
-                backup();
-                return;
-            }
-
-            // Validate all the things!
-            List<String> reason = new ArrayList<String>();
-
-            // Item Material
-            Material itemMaterial = Material.matchMaterial(key);
-
-            if (itemMaterial == null) {
-                reason.add("Invalid material: " + key);
-            }
-
-            // Repair Material Type
-            MaterialType repairMaterialType = MaterialType.OTHER;
-            String repairMaterialTypeString = config.getString("Repairables." + key + ".MaterialType", "OTHER");
-
-            if (!config.contains("Repairables." + key + ".MaterialType") && itemMaterial != null) {
-                ItemStack repairItem = new ItemStack(itemMaterial);
-
-                if (ItemUtils.isWoodTool(repairItem)) {
-                    repairMaterialType = MaterialType.WOOD;
-                }
-                else if (ItemUtils.isStoneTool(repairItem)) {
-                    repairMaterialType = MaterialType.STONE;
-                }
-                else if (ItemUtils.isStringTool(repairItem)) {
-                    repairMaterialType = MaterialType.STRING;
-                }
-                else if (ItemUtils.isLeatherArmor(repairItem)) {
-                    repairMaterialType = MaterialType.LEATHER;
-                }
-                else if (ItemUtils.isIronArmor(repairItem) || ItemUtils.isIronTool(repairItem)) {
-                    repairMaterialType = MaterialType.IRON;
-                }
-                else if (ItemUtils.isGoldArmor(repairItem) || ItemUtils.isGoldTool(repairItem)) {
-                    repairMaterialType = MaterialType.GOLD;
-                }
-                else if (ItemUtils.isDiamondArmor(repairItem) || ItemUtils.isDiamondTool(repairItem)) {
-                    repairMaterialType = MaterialType.DIAMOND;
-                }
-            }
-            else {
-                try {
-                    repairMaterialType = MaterialType.valueOf(repairMaterialTypeString);
-                }
-                catch (IllegalArgumentException ex) {
-                    reason.add(key + " has an invalid MaterialType of " + repairMaterialTypeString);
-                }
-            }
-
-            // Repair Material
-            String repairMaterialName = config.getString("Repairables." + key + ".RepairMaterial");
-            Material repairMaterial = (repairMaterialName == null ? repairMaterialType.getDefaultMaterial() : Material.matchMaterial(repairMaterialName));
-
-            if (repairMaterial == null) {
-                reason.add(key + " has an invalid repair material: " + repairMaterialName);
-            }
-
-            // Maximum Durability
-            short maximumDurability = (itemMaterial != null ? itemMaterial.getMaxDurability() : (short) config.getInt("Repairables." + key + ".MaximumDurability"));
-
-            if (maximumDurability <= 0) {
-                maximumDurability = (short) config.getInt("Repairables." + key + ".MaximumDurability");
-            }
-
-            if (maximumDurability <= 0) {
-                reason.add("Maximum durability of " + key + " must be greater than 0!");
-            }
-
-            // Item Type
-            ItemType repairItemType = ItemType.OTHER;
-            String repairItemTypeString = config.getString("Repairables." + key + ".ItemType", "OTHER");
-
-            if (!config.contains("Repairables." + key + ".ItemType") && itemMaterial != null) {
-                ItemStack repairItem = new ItemStack(itemMaterial);
-
-                if (ItemUtils.isMinecraftTool(repairItem)) {
-                    repairItemType = ItemType.TOOL;
-                }
-                else if (ItemUtils.isArmor(repairItem)) {
-                    repairItemType = ItemType.ARMOR;
-                }
-            }
-            else {
-                try {
-                    repairItemType = ItemType.valueOf(repairItemTypeString);
-                }
-                catch (IllegalArgumentException ex) {
-                    reason.add(key + " has an invalid ItemType of " + repairItemTypeString);
-                }
-            }
-
-            byte repairMetadata = (byte) config.getInt("Repairables." + key + ".RepairMaterialMetadata", -1);
-            int minimumLevel = config.getInt("Repairables." + key + ".MinimumLevel");
-            double xpMultiplier = config.getDouble("Repairables." + key + ".XpMultiplier", 1);
-
-            if (minimumLevel < 0) {
-                reason.add(key + " has an invalid MinimumLevel of " + minimumLevel);
-            }
-
-            // Minimum Quantity
-            int minimumQuantity = (itemMaterial != null ? SkillUtils.getRepairAndSalvageQuantities(new ItemStack(itemMaterial), repairMaterial, repairMetadata) : config.getInt("Repairables." + key + ".MinimumQuantity", 2));
-
-            if (minimumQuantity <= 0 && itemMaterial != null) {
-                minimumQuantity = config.getInt("Repairables." + key + ".MinimumQuantity", 2);
-            }
-
-            if (minimumQuantity <= 0) {
-                reason.add("Minimum quantity of " + key + " must be greater than 0!");
-            }
-
-            if (noErrorsInRepairable(reason)) {
-                Repairable repairable = RepairableFactory.getRepairable(itemMaterial, repairMaterial, repairMetadata, minimumLevel, minimumQuantity, maximumDurability, repairItemType, repairMaterialType, xpMultiplier);
-                repairables.add(repairable);
-            }
-        }
-    }
-
-    protected List<Repairable> getLoadedRepairables() {
-        return repairables == null ? new ArrayList<Repairable>() : repairables;
-    }
-
-    private boolean noErrorsInRepairable(List<String> issues) {
-        for (String issue : issues) {
-            plugin.getLogger().warning(issue);
-        }
-
-        return issues.isEmpty();
-    }
-}

+ 0 - 42
src/main/java/com/gmail/nossr50/config/skills/repair/RepairConfigManager.java

@@ -1,42 +0,0 @@
-package com.gmail.nossr50.config.skills.repair;
-
-import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.skills.repair.repairables.Repairable;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-
-public class RepairConfigManager {
-    private final List<Repairable> repairables = new ArrayList<Repairable>();
-
-    public RepairConfigManager(mcMMO plugin) {
-        Pattern pattern = Pattern.compile("repair\\.(?:.+)\\.yml");
-        File dataFolder = plugin.getDataFolder();
-        File vanilla = new File(dataFolder, "repair.vanilla.yml");
-
-        if (!vanilla.exists()) {
-            plugin.saveResource("repair.vanilla.yml", false);
-        }
-
-        for (String fileName : dataFolder.list()) {
-            if (!pattern.matcher(fileName).matches()) {
-                continue;
-            }
-
-            File file = new File(dataFolder, fileName);
-
-            if (file.isDirectory()) {
-                continue;
-            }
-
-            RepairConfig rConfig = new RepairConfig(fileName);
-            repairables.addAll(rConfig.getLoadedRepairables());
-        }
-    }
-
-    public List<Repairable> getLoadedRepairables() {
-        return repairables;
-    }
-}

+ 0 - 42
src/main/java/com/gmail/nossr50/config/skills/salvage/SalvageConfigManager.java

@@ -1,42 +0,0 @@
-package com.gmail.nossr50.config.skills.salvage;
-
-import com.gmail.nossr50.mcMMO;
-import com.gmail.nossr50.skills.salvage.salvageables.Salvageable;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Pattern;
-
-public class SalvageConfigManager {
-    private final List<Salvageable> salvageables = new ArrayList<Salvageable>();
-
-    public SalvageConfigManager(mcMMO plugin) {
-        Pattern pattern = Pattern.compile("salvage\\.(?:.+)\\.yml");
-        File dataFolder = plugin.getDataFolder();
-        File vanilla = new File(dataFolder, "salvage.vanilla.yml");
-
-        if (!vanilla.exists()) {
-            plugin.saveResource("salvage.vanilla.yml", false);
-        }
-
-        for (String fileName : dataFolder.list()) {
-            if (!pattern.matcher(fileName).matches()) {
-                continue;
-            }
-
-            File file = new File(dataFolder, fileName);
-
-            if (file.isDirectory()) {
-                continue;
-            }
-
-            SalvageConfig salvageConfig = new SalvageConfig(fileName);
-            salvageables.addAll(salvageConfig.getLoadedSalvageables());
-        }
-    }
-
-    public List<Salvageable> getLoadedSalvageables() {
-        return salvageables;
-    }
-}

+ 32 - 33
src/main/java/com/gmail/nossr50/config/treasure/TreasureConfig.java

@@ -1,10 +1,10 @@
 package com.gmail.nossr50.config.treasure;
 package com.gmail.nossr50.config.treasure;
 
 
-import com.gmail.nossr50.config.ConfigLoader;
+import com.gmail.nossr50.config.ConfigCollections;
 import com.gmail.nossr50.datatypes.treasure.*;
 import com.gmail.nossr50.datatypes.treasure.*;
+import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.util.EnchantmentUtils;
 import com.gmail.nossr50.util.EnchantmentUtils;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
-import org.bukkit.ChatColor;
 import org.bukkit.Material;
 import org.bukkit.Material;
 import org.bukkit.Tag;
 import org.bukkit.Tag;
 import org.bukkit.configuration.ConfigurationSection;
 import org.bukkit.configuration.ConfigurationSection;
@@ -20,22 +20,21 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.List;
 
 
-public class TreasureConfig extends ConfigLoader {
+public class TreasureConfig extends ConfigCollections {
 
 
     private static TreasureConfig instance;
     private static TreasureConfig instance;
 
 
     public HashMap<String, List<ExcavationTreasure>> excavationMap = new HashMap<String, List<ExcavationTreasure>>();
     public HashMap<String, List<ExcavationTreasure>> excavationMap = new HashMap<String, List<ExcavationTreasure>>();
 
 
-    public HashMap<EntityType, List<ShakeTreasure>> shakeMap  = new HashMap<EntityType, List<ShakeTreasure>>();
-    public HashMap<String, List<HylianTreasure>>    hylianMap = new HashMap<String, List<HylianTreasure>>();
+    public HashMap<EntityType, List<ShakeTreasure>> shakeMap = new HashMap<EntityType, List<ShakeTreasure>>();
+    public HashMap<String, List<HylianTreasure>> hylianMap = new HashMap<String, List<HylianTreasure>>();
 
 
-    public HashMap<Rarity, List<FishingTreasure>>     fishingRewards      = new HashMap<Rarity, List<FishingTreasure>>();
+    public HashMap<Rarity, List<FishingTreasure>> fishingRewards = new HashMap<Rarity, List<FishingTreasure>>();
     public HashMap<Rarity, List<EnchantmentTreasure>> fishingEnchantments = new HashMap<Rarity, List<EnchantmentTreasure>>();
     public HashMap<Rarity, List<EnchantmentTreasure>> fishingEnchantments = new HashMap<Rarity, List<EnchantmentTreasure>>();
 
 
     private TreasureConfig() {
     private TreasureConfig() {
-        super("treasures.yml");
-        loadKeys();
-        validate();
+        //super(McmmoCore.getDataFolderPath().getAbsoluteFile(),"treasures.yml");
+        super(mcMMO.p.getDataFolder().getAbsoluteFile(), "treasures.yml");
     }
     }
 
 
     public static TreasureConfig getInstance() {
     public static TreasureConfig getInstance() {
@@ -55,8 +54,8 @@ public class TreasureConfig extends ConfigLoader {
             double totalItemDropRate = 0;
             double totalItemDropRate = 0;
 
 
             for (Rarity rarity : Rarity.values()) {
             for (Rarity rarity : Rarity.values()) {
-                double enchantDropRate = config.getDouble("Enchantment_Drop_Rates." + tier + "." + rarity.toString());
-                double itemDropRate = config.getDouble("Item_Drop_Rates." + tier + "." + rarity.toString());
+                double enchantDropRate = getDoubleValue("Enchantment_Drop_Rates." + tier + "." + rarity.toString());
+                double itemDropRate = getDoubleValue("Item_Drop_Rates." + tier + "." + rarity.toString());
 
 
                 if ((enchantDropRate < 0.0 || enchantDropRate > 100.0) && rarity != Rarity.RECORD) {
                 if ((enchantDropRate < 0.0 || enchantDropRate > 100.0) && rarity != Rarity.RECORD) {
                     reason.add("The enchant drop rate for " + tier + " items that are " + rarity.toString() + "should be between 0.0 and 100.0!");
                     reason.add("The enchant drop rate for " + tier + " items that are " + rarity.toString() + "should be between 0.0 and 100.0!");
@@ -142,8 +141,8 @@ public class TreasureConfig extends ConfigLoader {
                 material = Material.matchMaterial(materialName);
                 material = Material.matchMaterial(materialName);
             }
             }
 
 
-            int amount = config.getInt(type + "." + treasureName + ".Amount");
-            short data = (treasureInfo.length == 2) ? Short.parseShort(treasureInfo[1]) : (short) config.getInt(type + "." + treasureName + ".Data");
+            int amount = getIntValue(type + "." + treasureName + ".Amount");
+            short data = (treasureInfo.length == 2) ? Short.parseShort(treasureInfo[1]) : (short) getIntValue(type + "." + treasureName + ".Data");
 
 
             if (material == null) {
             if (material == null) {
                 reason.add("Invalid material: " + materialName);
                 reason.add("Invalid material: " + materialName);
@@ -161,9 +160,9 @@ public class TreasureConfig extends ConfigLoader {
              * XP, Drop Chance, and Drop Level
              * XP, Drop Chance, and Drop Level
              */
              */
 
 
-            int xp = config.getInt(type + "." + treasureName + ".XP");
-            double dropChance = config.getDouble(type + "." + treasureName + ".Drop_Chance");
-            int dropLevel = config.getInt(type + "." + treasureName + ".Drop_Level");
+            int xp = getIntValue(type + "." + treasureName + ".XP");
+            double dropChance = getDoubleValue(type + "." + treasureName + ".Drop_Chance");
+            int dropLevel = getIntValue(type + "." + treasureName + ".Drop_Level");
 
 
             if (xp < 0) {
             if (xp < 0) {
                 reason.add(treasureName + " has an invalid XP value: " + xp);
                 reason.add(treasureName + " has an invalid XP value: " + xp);
@@ -183,7 +182,7 @@ public class TreasureConfig extends ConfigLoader {
             Rarity rarity = null;
             Rarity rarity = null;
 
 
             if (isFishing) {
             if (isFishing) {
-                rarity = Rarity.getRarity(config.getString(type + "." + treasureName + ".Rarity"));
+                rarity = Rarity.getRarity(getStringValue(type + "." + treasureName + ".Rarity"));
 
 
                 if (rarity == null) {
                 if (rarity == null) {
                     reason.add("Invalid Rarity for item: " + treasureName);
                     reason.add("Invalid Rarity for item: " + treasureName);
@@ -205,21 +204,21 @@ public class TreasureConfig extends ConfigLoader {
 
 
                     PotionType potionType = null;
                     PotionType potionType = null;
                     try {
                     try {
-                        potionType = PotionType.valueOf(config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
+                        potionType = PotionType.valueOf(getStringValue(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
                     } catch (IllegalArgumentException ex) {
                     } catch (IllegalArgumentException ex) {
-                        reason.add("Invalid Potion_Type: " + config.getString(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
+                        reason.add("Invalid Potion_Type: " + getStringValue(type + "." + treasureName + ".PotionData.PotionType", "WATER"));
                     }
                     }
-                    boolean extended = config.getBoolean(type + "." + treasureName + ".PotionData.Extended", false);
-                    boolean upgraded = config.getBoolean(type + "." + treasureName + ".PotionData.Upgraded", false);
+                    boolean extended = getBooleanValue(type + "." + treasureName + ".PotionData.Extended", false);
+                    boolean upgraded = getBooleanValue(type + "." + treasureName + ".PotionData.Upgraded", false);
                     itemMeta.setBasePotionData(new PotionData(potionType, extended, upgraded));
                     itemMeta.setBasePotionData(new PotionData(potionType, extended, upgraded));
 
 
                     if (config.contains(type + "." + treasureName + ".Custom_Name")) {
                     if (config.contains(type + "." + treasureName + ".Custom_Name")) {
-                        itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', config.getString(type + "." + treasureName + ".Custom_Name")));
+                        itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', getStringValue(type + "." + treasureName + ".Custom_Name")));
                     }
                     }
 
 
                     if (config.contains(type + "." + treasureName + ".Lore")) {
                     if (config.contains(type + "." + treasureName + ".Lore")) {
                         List<String> lore = new ArrayList<String>();
                         List<String> lore = new ArrayList<String>();
-                        for (String s : config.getStringList(type + "." + treasureName + ".Lore")) {
+                        for (String s : getStringValueList(type + "." + treasureName + ".Lore")) {
                             lore.add(ChatColor.translateAlternateColorCodes('&', s));
                             lore.add(ChatColor.translateAlternateColorCodes('&', s));
                         }
                         }
                         itemMeta.setLore(lore);
                         itemMeta.setLore(lore);
@@ -231,14 +230,14 @@ public class TreasureConfig extends ConfigLoader {
 
 
                 if (config.contains(type + "." + treasureName + ".Custom_Name")) {
                 if (config.contains(type + "." + treasureName + ".Custom_Name")) {
                     ItemMeta itemMeta = item.getItemMeta();
                     ItemMeta itemMeta = item.getItemMeta();
-                    itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', config.getString(type + "." + treasureName + ".Custom_Name")));
+                    itemMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', getStringValue(type + "." + treasureName + ".Custom_Name")));
                     item.setItemMeta(itemMeta);
                     item.setItemMeta(itemMeta);
                 }
                 }
 
 
                 if (config.contains(type + "." + treasureName + ".Lore")) {
                 if (config.contains(type + "." + treasureName + ".Lore")) {
                     ItemMeta itemMeta = item.getItemMeta();
                     ItemMeta itemMeta = item.getItemMeta();
                     List<String> lore = new ArrayList<String>();
                     List<String> lore = new ArrayList<String>();
-                    for (String s : config.getStringList(type + "." + treasureName + ".Lore")) {
+                    for (String s : getStringValueList(type + "." + treasureName + ".Lore")) {
                         lore.add(ChatColor.translateAlternateColorCodes('&', s));
                         lore.add(ChatColor.translateAlternateColorCodes('&', s));
                     }
                     }
                     itemMeta.setLore(lore);
                     itemMeta.setLore(lore);
@@ -258,7 +257,7 @@ public class TreasureConfig extends ConfigLoader {
                     shakeMap.get(entityType).add(shakeTreasure);
                     shakeMap.get(entityType).add(shakeTreasure);
                 } else if (isExcavation) {
                 } else if (isExcavation) {
                     ExcavationTreasure excavationTreasure = new ExcavationTreasure(item, xp, dropChance, dropLevel);
                     ExcavationTreasure excavationTreasure = new ExcavationTreasure(item, xp, dropChance, dropLevel);
-                    List<String> dropList = config.getStringList(type + "." + treasureName + ".Drops_From");
+                    List<String> dropList = getStringValueList(type + "." + treasureName + ".Drops_From");
 
 
                     for (String blockType : dropList) {
                     for (String blockType : dropList) {
                         if (!excavationMap.containsKey(blockType))
                         if (!excavationMap.containsKey(blockType))
@@ -267,7 +266,7 @@ public class TreasureConfig extends ConfigLoader {
                     }
                     }
                 } else if (isHylian) {
                 } else if (isHylian) {
                     HylianTreasure hylianTreasure = new HylianTreasure(item, xp, dropChance, dropLevel);
                     HylianTreasure hylianTreasure = new HylianTreasure(item, xp, dropChance, dropLevel);
-                    List<String> dropList = config.getStringList(type + "." + treasureName + ".Drops_From");
+                    List<String> dropList = getStringValueList(type + "." + treasureName + ".Drops_From");
 
 
                     for (String dropper : dropList) {
                     for (String dropper : dropList) {
                         if (dropper.equals("Bushes")) {
                         if (dropper.equals("Bushes")) {
@@ -326,7 +325,7 @@ public class TreasureConfig extends ConfigLoader {
             }
             }
 
 
             for (String enchantmentName : enchantmentSection.getKeys(false)) {
             for (String enchantmentName : enchantmentSection.getKeys(false)) {
-                int level = config.getInt("Enchantments_Rarity." + rarity.toString() + "." + enchantmentName);
+                int level = getIntValue("Enchantments_Rarity." + rarity.toString() + "." + enchantmentName);
                 Enchantment enchantment = EnchantmentUtils.getByName(enchantmentName);
                 Enchantment enchantment = EnchantmentUtils.getByName(enchantmentName);
 
 
                 if (enchantment == null) {
                 if (enchantment == null) {
@@ -344,22 +343,22 @@ public class TreasureConfig extends ConfigLoader {
     }
     }
 
 
     public boolean getInventoryStealStacks() {
     public boolean getInventoryStealStacks() {
-        return config.getBoolean("Shake.PLAYER.INVENTORY.Whole_Stacks");
+        return getBooleanValue("Shake.PLAYER.INVENTORY.Whole_Stacks");
     }
     }
 
 
     public double getInventoryStealDropChance() {
     public double getInventoryStealDropChance() {
-        return config.getDouble("Shake.PLAYER.INVENTORY.Drop_Chance");
+        return getDoubleValue("Shake.PLAYER.INVENTORY.Drop_Chance");
     }
     }
 
 
     public int getInventoryStealDropLevel() {
     public int getInventoryStealDropLevel() {
-        return config.getInt("Shake.PLAYER.INVENTORY.Drop_Level");
+        return getIntValue("Shake.PLAYER.INVENTORY.Drop_Level");
     }
     }
 
 
     public double getItemDropRate(int tier, Rarity rarity) {
     public double getItemDropRate(int tier, Rarity rarity) {
-        return config.getDouble("Item_Drop_Rates.Tier_" + tier + "." + rarity.toString());
+        return getDoubleValue("Item_Drop_Rates.Tier_" + tier + "." + rarity.toString());
     }
     }
 
 
     public double getEnchantmentDropRate(int tier, Rarity rarity) {
     public double getEnchantmentDropRate(int tier, Rarity rarity) {
-        return config.getDouble("Enchantment_Drop_Rates.Tier_" + tier + "." + rarity.toString());
+        return getDoubleValue("Enchantment_Drop_Rates.Tier_" + tier + "." + rarity.toString());
     }
     }
 }
 }

+ 2 - 2
src/main/java/com/gmail/nossr50/database/DatabaseManager.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.database;
 package com.gmail.nossr50.database;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.database.DatabaseType;
 import com.gmail.nossr50.datatypes.database.DatabaseType;
 import com.gmail.nossr50.datatypes.database.PlayerStat;
 import com.gmail.nossr50.datatypes.database.PlayerStat;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
 import com.gmail.nossr50.datatypes.player.PlayerProfile;
@@ -12,7 +12,7 @@ import java.util.UUID;
 
 
 public interface DatabaseManager {
 public interface DatabaseManager {
     // One month in milliseconds
     // One month in milliseconds
-    public final long PURGE_TIME = 2630000000L * Config.getInstance().getOldUsersCutoff();
+    public final long PURGE_TIME = 2630000000L * MainConfig.getInstance().getOldUsersCutoff();
     // During convertUsers, how often to output a status
     // During convertUsers, how often to output a status
     public final int progressInterval = 200;
     public final int progressInterval = 200;
 
 

+ 3 - 3
src/main/java/com/gmail/nossr50/database/DatabaseManagerFactory.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.database;
 package com.gmail.nossr50.database;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.database.DatabaseType;
 import com.gmail.nossr50.datatypes.database.DatabaseType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 
 
@@ -20,10 +20,10 @@ public class DatabaseManagerFactory {
                 mcMMO.p.debug("Failed to create custom database manager");
                 mcMMO.p.debug("Failed to create custom database manager");
                 e.printStackTrace();
                 e.printStackTrace();
             }
             }
-            mcMMO.p.debug("Falling back on " + (Config.getInstance().getUseMySQL() ? "SQL" : "Flatfile") + " database");
+            mcMMO.p.debug("Falling back on " + (MainConfig.getInstance().getUseMySQL() ? "SQL" : "Flatfile") + " database");
         }
         }
 
 
-        return Config.getInstance().getUseMySQL() ? new SQLDatabaseManager() : new FlatfileDatabaseManager();
+        return MainConfig.getInstance().getUseMySQL() ? new SQLDatabaseManager() : new FlatfileDatabaseManager();
     }
     }
 
 
     /**
     /**

+ 12 - 13
src/main/java/com/gmail/nossr50/database/FlatfileDatabaseManager.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.database;
 package com.gmail.nossr50.database;
 
 
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.MobHealthbarType;
 import com.gmail.nossr50.datatypes.MobHealthbarType;
 import com.gmail.nossr50.datatypes.database.DatabaseType;
 import com.gmail.nossr50.datatypes.database.DatabaseType;
 import com.gmail.nossr50.datatypes.database.PlayerStat;
 import com.gmail.nossr50.datatypes.database.PlayerStat;
@@ -348,7 +347,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
         writer.append((int) profile.getAbilityDATS(SuperAbilityType.BLAST_MINING)).append(":");
         writer.append((int) profile.getAbilityDATS(SuperAbilityType.BLAST_MINING)).append(":");
         writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":");
         writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":");
         MobHealthbarType mobHealthbarType = profile.getMobHealthbarType();
         MobHealthbarType mobHealthbarType = profile.getMobHealthbarType();
-        writer.append(mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString()).append(":");
+        writer.append(mobHealthbarType == null ? MainConfig.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString()).append(":");
         writer.append(profile.getSkillLevel(PrimarySkillType.ALCHEMY)).append(":");
         writer.append(profile.getSkillLevel(PrimarySkillType.ALCHEMY)).append(":");
         writer.append(profile.getSkillXpLevel(PrimarySkillType.ALCHEMY)).append(":");
         writer.append(profile.getSkillXpLevel(PrimarySkillType.ALCHEMY)).append(":");
         writer.append(uuid != null ? uuid.toString() : "NULL").append(":");
         writer.append(uuid != null ? uuid.toString() : "NULL").append(":");
@@ -427,7 +426,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
                 out.append("0:"); // FishingXp
                 out.append("0:"); // FishingXp
                 out.append("0:"); // Blast Mining
                 out.append("0:"); // Blast Mining
                 out.append(String.valueOf(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)).append(":"); // LastLogin
                 out.append(String.valueOf(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)).append(":"); // LastLogin
-                out.append(Config.getInstance().getMobHealthbarDefault().toString()).append(":"); // Mob Healthbar HUD
+                out.append(MainConfig.getInstance().getMobHealthbarDefault().toString()).append(":"); // Mob Healthbar HUD
                 out.append(startingLevel); // Alchemy
                 out.append(startingLevel); // Alchemy
                 out.append("0:"); // AlchemyXp
                 out.append("0:"); // AlchemyXp
                 out.append(uuid != null ? uuid.toString() : "NULL").append(":"); // UUID
                 out.append(uuid != null ? uuid.toString() : "NULL").append(":"); // UUID
@@ -896,13 +895,13 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
                             updated = true;
                             updated = true;
                         }
                         }
 
 
-                        if (Config.getInstance().getTruncateSkills()) {
+                        if (MainConfig.getInstance().getTruncateSkills()) {
                             for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
                             for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
                                 int index = getSkillIndex(skill);
                                 int index = getSkillIndex(skill);
                                 if (index >= character.length) {
                                 if (index >= character.length) {
                                     continue;
                                     continue;
                                 }
                                 }
-                                int cap = Config.getInstance().getLevelCap(skill);
+                                int cap = MainConfig.getInstance().getLevelCap(skill);
                                 if (Integer.valueOf(character[index]) > cap) {
                                 if (Integer.valueOf(character[index]) > cap) {
                                     mcMMO.p.getLogger().warning("Truncating " + skill.getName() + " to configured max level for player " + character[USERNAME]);
                                     mcMMO.p.getLogger().warning("Truncating " + skill.getName() + " to configured max level for player " + character[USERNAME]);
                                     character[index] = cap + "";
                                     character[index] = cap + "";
@@ -963,7 +962,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
                             // Version 1.4.06
                             // Version 1.4.06
                             // commit da29185b7dc7e0d992754bba555576d48fa08aa6
                             // commit da29185b7dc7e0d992754bba555576d48fa08aa6
                             character = Arrays.copyOf(character, character.length + 1);
                             character = Arrays.copyOf(character, character.length + 1);
-                            character[character.length - 1] = Config.getInstance().getMobHealthbarDefault().toString();
+                            character[character.length - 1] = MainConfig.getInstance().getMobHealthbarDefault().toString();
                             if (oldVersion == null) {
                             if (oldVersion == null) {
                                 oldVersion = "1.4.06";
                                 oldVersion = "1.4.06";
                             }
                             }
@@ -1007,7 +1006,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
                                     character[i] = String.valueOf(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
                                     character[i] = String.valueOf(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
                                 }
                                 }
                                 else if (i == 38) {
                                 else if (i == 38) {
-                                    character[i] = Config.getInstance().getMobHealthbarDefault().toString();
+                                    character[i] = MainConfig.getInstance().getMobHealthbarDefault().toString();
                                 }
                                 }
                                 else {
                                 else {
                                     character[i] = "0";
                                     character[i] = "0";
@@ -1016,7 +1015,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
 
 
                             if (StringUtils.isInt(character[i]) && i == 38) {
                             if (StringUtils.isInt(character[i]) && i == 38) {
                                 corrupted = true;
                                 corrupted = true;
-                                character[i] = Config.getInstance().getMobHealthbarDefault().toString();
+                                character[i] = MainConfig.getInstance().getMobHealthbarDefault().toString();
                             }
                             }
 
 
                             if (!StringUtils.isInt(character[i]) && !(i == 0 || i == 2 || i == 3 || i == 23 || i == 33 || i == 38 || i == 41)) {
                             if (!StringUtils.isInt(character[i]) && !(i == 0 || i == 2 || i == 3 || i == 23 || i == 33 || i == 38 || i == 41)) {
@@ -1036,10 +1035,10 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
                         updated |= corrupted;
                         updated |= corrupted;
                         updated |= oldVersion != null;
                         updated |= oldVersion != null;
 
 
-                        if (Config.getInstance().getTruncateSkills()) {
+                        if (MainConfig.getInstance().getTruncateSkills()) {
                             Map<PrimarySkillType, Integer> skills = getSkillMapFromLine(character);
                             Map<PrimarySkillType, Integer> skills = getSkillMapFromLine(character);
                             for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
                             for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
-                                int cap = Config.getInstance().getLevelCap(skill);
+                                int cap = MainConfig.getInstance().getLevelCap(skill);
                                 if (skills.get(skill) > cap) {
                                 if (skills.get(skill) > cap) {
                                     updated = true;
                                     updated = true;
                                 }
                                 }
@@ -1172,7 +1171,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
             mobHealthbarType = MobHealthbarType.valueOf(character[HEALTHBAR]);
             mobHealthbarType = MobHealthbarType.valueOf(character[HEALTHBAR]);
         }
         }
         catch (Exception e) {
         catch (Exception e) {
-            mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
+            mobHealthbarType = MainConfig.getInstance().getMobHealthbarDefault();
         }
         }
 
 
         UUID uuid;
         UUID uuid;
@@ -1320,7 +1319,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
                     }
                     }
                     String[] character = line.split(":");
                     String[] character = line.split(":");
                     
                     
-                    character[HEALTHBAR] = Config.getInstance().getMobHealthbarDefault().toString();
+                    character[HEALTHBAR] = MainConfig.getInstance().getMobHealthbarDefault().toString();
                     
                     
                     line = new StringBuilder(org.apache.commons.lang.StringUtils.join(character, ":")).append(":").toString();
                     line = new StringBuilder(org.apache.commons.lang.StringUtils.join(character, ":")).append(":").toString();
 
 

+ 30 - 31
src/main/java/com/gmail/nossr50/database/SQLDatabaseManager.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.database;
 package com.gmail.nossr50.database;
 
 
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.MobHealthbarType;
 import com.gmail.nossr50.datatypes.MobHealthbarType;
 import com.gmail.nossr50.datatypes.database.DatabaseType;
 import com.gmail.nossr50.datatypes.database.DatabaseType;
 import com.gmail.nossr50.datatypes.database.PlayerStat;
 import com.gmail.nossr50.datatypes.database.PlayerStat;
@@ -23,7 +22,7 @@ import java.util.concurrent.locks.ReentrantLock;
 
 
 public final class SQLDatabaseManager implements DatabaseManager {
 public final class SQLDatabaseManager implements DatabaseManager {
     private static final String ALL_QUERY_VERSION = "total";
     private static final String ALL_QUERY_VERSION = "total";
-    private String tablePrefix = Config.getInstance().getMySQLTablePrefix();
+    private String tablePrefix = MainConfig.getInstance().getMySQLTablePrefix();
 
 
     private final Map<UUID, Integer> cachedUserIDs = new HashMap<UUID, Integer>();
     private final Map<UUID, Integer> cachedUserIDs = new HashMap<UUID, Integer>();
 
 
@@ -34,10 +33,10 @@ public final class SQLDatabaseManager implements DatabaseManager {
     private ReentrantLock massUpdateLock = new ReentrantLock();
     private ReentrantLock massUpdateLock = new ReentrantLock();
 
 
     protected SQLDatabaseManager() {
     protected SQLDatabaseManager() {
-        String connectionString = "jdbc:mysql://" + Config.getInstance().getMySQLServerName()
-                + ":" + Config.getInstance().getMySQLServerPort() + "/" + Config.getInstance().getMySQLDatabaseName();
+        String connectionString = "jdbc:mysql://" + MainConfig.getInstance().getMySQLServerName()
+                + ":" + MainConfig.getInstance().getMySQLServerPort() + "/" + MainConfig.getInstance().getMySQLDatabaseName();
 
 
-        if(Config.getInstance().getMySQLSSL())
+        if(MainConfig.getInstance().getMySQLSSL())
             connectionString +=
             connectionString +=
                     "?verifyServerCertificate=false"+
                     "?verifyServerCertificate=false"+
                     "&useSSL=true"+
                     "&useSSL=true"+
@@ -60,10 +59,10 @@ public final class SQLDatabaseManager implements DatabaseManager {
         PoolProperties poolProperties = new PoolProperties();
         PoolProperties poolProperties = new PoolProperties();
         poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
         poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
         poolProperties.setUrl(connectionString);
         poolProperties.setUrl(connectionString);
-        poolProperties.setUsername(Config.getInstance().getMySQLUserName());
-        poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
-        poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.MISC));
-        poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.MISC));
+        poolProperties.setUsername(MainConfig.getInstance().getMySQLUserName());
+        poolProperties.setPassword(MainConfig.getInstance().getMySQLUserPassword());
+        poolProperties.setMaxIdle(MainConfig.getInstance().getMySQLMaxPoolSize(PoolIdentifier.MISC));
+        poolProperties.setMaxActive(MainConfig.getInstance().getMySQLMaxConnections(PoolIdentifier.MISC));
         poolProperties.setInitialSize(0);
         poolProperties.setInitialSize(0);
         poolProperties.setMaxWait(-1);
         poolProperties.setMaxWait(-1);
         poolProperties.setRemoveAbandoned(true);
         poolProperties.setRemoveAbandoned(true);
@@ -75,11 +74,11 @@ public final class SQLDatabaseManager implements DatabaseManager {
         poolProperties = new PoolProperties();
         poolProperties = new PoolProperties();
         poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
         poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
         poolProperties.setUrl(connectionString);
         poolProperties.setUrl(connectionString);
-        poolProperties.setUsername(Config.getInstance().getMySQLUserName());
-        poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
+        poolProperties.setUsername(MainConfig.getInstance().getMySQLUserName());
+        poolProperties.setPassword(MainConfig.getInstance().getMySQLUserPassword());
         poolProperties.setInitialSize(0);
         poolProperties.setInitialSize(0);
-        poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.SAVE));
-        poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.SAVE));
+        poolProperties.setMaxIdle(MainConfig.getInstance().getMySQLMaxPoolSize(PoolIdentifier.SAVE));
+        poolProperties.setMaxActive(MainConfig.getInstance().getMySQLMaxConnections(PoolIdentifier.SAVE));
         poolProperties.setMaxWait(-1);
         poolProperties.setMaxWait(-1);
         poolProperties.setRemoveAbandoned(true);
         poolProperties.setRemoveAbandoned(true);
         poolProperties.setRemoveAbandonedTimeout(60);
         poolProperties.setRemoveAbandonedTimeout(60);
@@ -90,11 +89,11 @@ public final class SQLDatabaseManager implements DatabaseManager {
         poolProperties = new PoolProperties();
         poolProperties = new PoolProperties();
         poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
         poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
         poolProperties.setUrl(connectionString);
         poolProperties.setUrl(connectionString);
-        poolProperties.setUsername(Config.getInstance().getMySQLUserName());
-        poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
+        poolProperties.setUsername(MainConfig.getInstance().getMySQLUserName());
+        poolProperties.setPassword(MainConfig.getInstance().getMySQLUserPassword());
         poolProperties.setInitialSize(0);
         poolProperties.setInitialSize(0);
-        poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.LOAD));
-        poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.LOAD));
+        poolProperties.setMaxIdle(MainConfig.getInstance().getMySQLMaxPoolSize(PoolIdentifier.LOAD));
+        poolProperties.setMaxActive(MainConfig.getInstance().getMySQLMaxConnections(PoolIdentifier.LOAD));
         poolProperties.setMaxWait(-1);
         poolProperties.setMaxWait(-1);
         poolProperties.setRemoveAbandoned(true);
         poolProperties.setRemoveAbandoned(true);
         poolProperties.setRemoveAbandonedTimeout(60);
         poolProperties.setRemoveAbandonedTimeout(60);
@@ -311,7 +310,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
             }
             }
 
 
             statement = connection.prepareStatement("UPDATE " + tablePrefix + "huds SET mobhealthbar = ?, scoreboardtips = ? WHERE user_id = ?");
             statement = connection.prepareStatement("UPDATE " + tablePrefix + "huds SET mobhealthbar = ?, scoreboardtips = ? WHERE user_id = ?");
-            statement.setString(1, profile.getMobHealthbarType() == null ? Config.getInstance().getMobHealthbarDefault().name() : profile.getMobHealthbarType().name());
+            statement.setString(1, profile.getMobHealthbarType() == null ? MainConfig.getInstance().getMobHealthbarDefault().name() : profile.getMobHealthbarType().name());
             statement.setInt(2, profile.getScoreboardTipsShown());
             statement.setInt(2, profile.getScoreboardTipsShown());
             statement.setInt(3, id);
             statement.setInt(3, id);
             success = (statement.executeUpdate() != 0);
             success = (statement.executeUpdate() != 0);
@@ -781,7 +780,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
             statement = connection.prepareStatement("SELECT table_name FROM INFORMATION_SCHEMA.TABLES"
             statement = connection.prepareStatement("SELECT table_name FROM INFORMATION_SCHEMA.TABLES"
                     + " WHERE table_schema = ?"
                     + " WHERE table_schema = ?"
                     + " AND table_name = ?");
                     + " AND table_name = ?");
-            statement.setString(1, Config.getInstance().getMySQLDatabaseName());
+            statement.setString(1, MainConfig.getInstance().getMySQLDatabaseName());
             statement.setString(2, tablePrefix + "users");
             statement.setString(2, tablePrefix + "users");
             resultSet = statement.executeQuery();
             resultSet = statement.executeQuery();
             if (!resultSet.next()) {
             if (!resultSet.next()) {
@@ -797,21 +796,21 @@ public final class SQLDatabaseManager implements DatabaseManager {
                 tryClose(createStatement);
                 tryClose(createStatement);
             }
             }
             tryClose(resultSet);
             tryClose(resultSet);
-            statement.setString(1, Config.getInstance().getMySQLDatabaseName());
+            statement.setString(1, MainConfig.getInstance().getMySQLDatabaseName());
             statement.setString(2, tablePrefix + "huds");
             statement.setString(2, tablePrefix + "huds");
             resultSet = statement.executeQuery();
             resultSet = statement.executeQuery();
             if (!resultSet.next()) {
             if (!resultSet.next()) {
                 createStatement = connection.createStatement();
                 createStatement = connection.createStatement();
                 createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "huds` ("
                 createStatement.executeUpdate("CREATE TABLE IF NOT EXISTS `" + tablePrefix + "huds` ("
                         + "`user_id` int(10) unsigned NOT NULL,"
                         + "`user_id` int(10) unsigned NOT NULL,"
-                        + "`mobhealthbar` varchar(50) NOT NULL DEFAULT '" + Config.getInstance().getMobHealthbarDefault() + "',"
+                        + "`mobhealthbar` varchar(50) NOT NULL DEFAULT '" + MainConfig.getInstance().getMobHealthbarDefault() + "',"
                         + "`scoreboardtips` int(10) NOT NULL DEFAULT '0',"
                         + "`scoreboardtips` int(10) NOT NULL DEFAULT '0',"
                         + "PRIMARY KEY (`user_id`)) "
                         + "PRIMARY KEY (`user_id`)) "
                         + "DEFAULT CHARSET=latin1;");
                         + "DEFAULT CHARSET=latin1;");
                 tryClose(createStatement);
                 tryClose(createStatement);
             }
             }
             tryClose(resultSet);
             tryClose(resultSet);
-            statement.setString(1, Config.getInstance().getMySQLDatabaseName());
+            statement.setString(1, MainConfig.getInstance().getMySQLDatabaseName());
             statement.setString(2, tablePrefix + "cooldowns");
             statement.setString(2, tablePrefix + "cooldowns");
             resultSet = statement.executeQuery();
             resultSet = statement.executeQuery();
             if (!resultSet.next()) {
             if (!resultSet.next()) {
@@ -836,7 +835,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
                 tryClose(createStatement);
                 tryClose(createStatement);
             }
             }
             tryClose(resultSet);
             tryClose(resultSet);
-            statement.setString(1, Config.getInstance().getMySQLDatabaseName());
+            statement.setString(1, MainConfig.getInstance().getMySQLDatabaseName());
             statement.setString(2, tablePrefix + "skills");
             statement.setString(2, tablePrefix + "skills");
             resultSet = statement.executeQuery();
             resultSet = statement.executeQuery();
             if (!resultSet.next()) {
             if (!resultSet.next()) {
@@ -864,7 +863,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
                 tryClose(createStatement);
                 tryClose(createStatement);
             }
             }
             tryClose(resultSet);
             tryClose(resultSet);
-            statement.setString(1, Config.getInstance().getMySQLDatabaseName());
+            statement.setString(1, MainConfig.getInstance().getMySQLDatabaseName());
             statement.setString(2, tablePrefix + "experience");
             statement.setString(2, tablePrefix + "experience");
             resultSet = statement.executeQuery();
             resultSet = statement.executeQuery();
             if (!resultSet.next()) {
             if (!resultSet.next()) {
@@ -895,9 +894,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
                 checkDatabaseStructure(connection, updateType);
                 checkDatabaseStructure(connection, updateType);
             }
             }
 
 
-            if (Config.getInstance().getTruncateSkills()) {
+            if (MainConfig.getInstance().getTruncateSkills()) {
                 for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
                 for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
-                    int cap = Config.getInstance().getLevelCap(skill);
+                    int cap = MainConfig.getInstance().getLevelCap(skill);
                     if (cap != Integer.MAX_VALUE) {
                     if (cap != Integer.MAX_VALUE) {
                         statement = connection.prepareStatement("UPDATE `" + tablePrefix + "skills` SET `" + skill.name().toLowerCase() + "` = " + cap + " WHERE `" + skill.name().toLowerCase() + "` > " + cap);
                         statement = connection.prepareStatement("UPDATE `" + tablePrefix + "skills` SET `" + skill.name().toLowerCase() + "` = " + cap + " WHERE `" + skill.name().toLowerCase() + "` > " + cap);
                         statement.executeUpdate();
                         statement.executeUpdate();
@@ -1044,7 +1043,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
 
 
             statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "huds (user_id, mobhealthbar, scoreboardtips) VALUES (?, ?, ?)");
             statement = connection.prepareStatement("INSERT IGNORE INTO " + tablePrefix + "huds (user_id, mobhealthbar, scoreboardtips) VALUES (?, ?, ?)");
             statement.setInt(1, id);
             statement.setInt(1, id);
-            statement.setString(2, Config.getInstance().getMobHealthbarDefault().name());
+            statement.setString(2, MainConfig.getInstance().getMobHealthbarDefault().name());
             statement.setInt(3, 0);
             statement.setInt(3, 0);
             statement.execute();
             statement.execute();
             statement.close();
             statement.close();
@@ -1119,7 +1118,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
             mobHealthbarType = MobHealthbarType.valueOf(result.getString(OFFSET_OTHER + 1));
             mobHealthbarType = MobHealthbarType.valueOf(result.getString(OFFSET_OTHER + 1));
         }
         }
         catch (Exception e) {
         catch (Exception e) {
-            mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
+            mobHealthbarType = MainConfig.getInstance().getMobHealthbarDefault();
         }
         }
 
 
         try {
         try {
@@ -1221,7 +1220,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
         }
         }
         catch (SQLException ex) {
         catch (SQLException ex) {
             mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars...");
             mcMMO.p.getLogger().info("Updating mcMMO MySQL tables for mob healthbars...");
-            statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT '" + Config.getInstance().getMobHealthbarDefault() + "'");
+            statement.executeUpdate("ALTER TABLE `" + tablePrefix + "huds` ADD `mobhealthbar` varchar(50) NOT NULL DEFAULT '" + MainConfig.getInstance().getMobHealthbarDefault() + "'");
         }
         }
     }
     }
 
 
@@ -1518,7 +1517,7 @@ public final class SQLDatabaseManager implements DatabaseManager {
         try {
         try {
             connection = getConnection(PoolIdentifier.MISC);
             connection = getConnection(PoolIdentifier.MISC);
             statement = connection.prepareStatement("UPDATE " + tablePrefix + "huds SET mobhealthbar = ?");
             statement = connection.prepareStatement("UPDATE " + tablePrefix + "huds SET mobhealthbar = ?");
-            statement.setString(1, Config.getInstance().getMobHealthbarDefault().toString());
+            statement.setString(1, MainConfig.getInstance().getMobHealthbarDefault().toString());
             statement.executeUpdate();
             statement.executeUpdate();
         }
         }
         catch (SQLException ex) {
         catch (SQLException ex) {

+ 0 - 1
src/main/java/com/gmail/nossr50/datatypes/experience/SkillXpGain.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.datatypes.experience;
 package com.gmail.nossr50.datatypes.experience;
 
 
-import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 
 
 import java.util.concurrent.Delayed;
 import java.util.concurrent.Delayed;

+ 5 - 6
src/main/java/com/gmail/nossr50/datatypes/party/Party.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.datatypes.party;
 package com.gmail.nossr50.datatypes.party;
 
 
-import com.gmail.nossr50.config.Config;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -192,7 +191,7 @@ public class Party {
 
 
     public int getXpToLevel() {
     public int getXpToLevel() {
         FormulaType formulaType = ExperienceConfig.getInstance().getFormulaType();
         FormulaType formulaType = ExperienceConfig.getInstance().getFormulaType();
-        return (mcMMO.getFormulaManager().getCachedXpToLevel(level, formulaType)) * (getOnlineMembers().size() + Config.getInstance().getPartyXpCurveMultiplier());
+        return (mcMMO.getFormulaManager().getCachedXpToLevel(level, formulaType)) * (getOnlineMembers().size() + MainConfig.getInstance().getPartyXpCurveMultiplier());
     }
     }
 
 
     public String getXpToLevelPercentage() {
     public String getXpToLevelPercentage() {
@@ -231,13 +230,13 @@ public class Party {
             return;
             return;
         }
         }
 
 
-        if (!Config.getInstance().getPartyInformAllMembers()) {
+        if (!MainConfig.getInstance().getPartyInformAllMembers()) {
             Player leader = mcMMO.p.getServer().getPlayer(this.leader.getUniqueId());
             Player leader = mcMMO.p.getServer().getPlayer(this.leader.getUniqueId());
 
 
             if (leader != null) {
             if (leader != null) {
                 leader.sendMessage(LocaleLoader.getString("Party.LevelUp", levelsGained, getLevel()));
                 leader.sendMessage(LocaleLoader.getString("Party.LevelUp", levelsGained, getLevel()));
 
 
-                if (Config.getInstance().getLevelUpSoundsEnabled()) {
+                if (MainConfig.getInstance().getLevelUpSoundsEnabled()) {
                     SoundManager.sendSound(leader, leader.getLocation(), SoundType.LEVEL_UP);
                     SoundManager.sendSound(leader, leader.getLocation(), SoundType.LEVEL_UP);
                 }
                 }
             }
             }
@@ -248,7 +247,7 @@ public class Party {
     }
     }
 
 
     public boolean hasReachedLevelCap() {
     public boolean hasReachedLevelCap() {
-        return Config.getInstance().getPartyLevelCap() < getLevel() + 1;
+        return MainConfig.getInstance().getPartyLevelCap() < getLevel() + 1;
     }
     }
 
 
     public void setXpShareMode(ShareMode xpShareMode) {
     public void setXpShareMode(ShareMode xpShareMode) {

+ 2 - 2
src/main/java/com/gmail/nossr50/datatypes/party/PartyFeature.java

@@ -1,7 +1,7 @@
 package com.gmail.nossr50.datatypes.party;
 package com.gmail.nossr50.datatypes.party;
 
 
 import com.gmail.nossr50.commands.party.PartySubcommandType;
 import com.gmail.nossr50.commands.party.PartySubcommandType;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
@@ -19,7 +19,7 @@ public enum PartyFeature {
     }
     }
 
 
     public String getFeatureLockedLocaleString() {
     public String getFeatureLockedLocaleString() {
-        return LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Party.Feature.Locked." + StringUtils.getPrettyPartyFeatureString(this).replace(" ", ""), Config.getInstance().getPartyFeatureUnlockLevel(this)));
+        return LocaleLoader.getString("Ability.Generic.Template.Lock", LocaleLoader.getString("Party.Feature.Locked." + StringUtils.getPrettyPartyFeatureString(this).replace(" ", ""), MainConfig.getInstance().getPartyFeatureUnlockLevel(this)));
     }
     }
 
 
     public boolean hasPermission(Player player) {
     public boolean hasPermission(Player player) {

+ 2 - 2
src/main/java/com/gmail/nossr50/datatypes/party/PartyTeleportRecord.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.datatypes.party;
 package com.gmail.nossr50.datatypes.party;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.util.Misc;
 import com.gmail.nossr50.util.Misc;
 import org.bukkit.entity.Player;
 import org.bukkit.entity.Player;
 
 
@@ -12,7 +12,7 @@ public class PartyTeleportRecord {
     public PartyTeleportRecord() {
     public PartyTeleportRecord() {
         requestor = null;
         requestor = null;
         enabled = true;
         enabled = true;
-        confirmRequired = Config.getInstance().getPTPCommandConfirmRequired();
+        confirmRequired = MainConfig.getInstance().getPTPCommandConfirmRequired();
         timeout = 0;
         timeout = 0;
         lastUse = 0;
         lastUse = 0;
     }
     }

+ 9 - 11
src/main/java/com/gmail/nossr50/datatypes/player/McMMOPlayer.java

@@ -1,9 +1,7 @@
 package com.gmail.nossr50.datatypes.player;
 package com.gmail.nossr50.datatypes.player;
 
 
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.config.WorldBlacklist;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.experience.XPGainSource;
 import com.gmail.nossr50.datatypes.experience.XPGainSource;
@@ -501,7 +499,7 @@ public class McMMOPlayer {
             return;
             return;
         }
         }
 
 
-        if (!Config.getInstance().getPartyXpNearMembersNeeded() || !PartyManager.getNearMembers(this).isEmpty()) {
+        if (!MainConfig.getInstance().getPartyXpNearMembersNeeded() || !PartyManager.getNearMembers(this).isEmpty()) {
             party.applyXpGain(modifyXpGain(skill, xp));
             party.applyXpGain(modifyXpGain(skill, xp));
         }
         }
     }
     }
@@ -564,7 +562,7 @@ public class McMMOPlayer {
             return;
             return;
         }
         }
 
 
-        if (Config.getInstance().getLevelUpSoundsEnabled()) {
+        if (MainConfig.getInstance().getLevelUpSoundsEnabled()) {
             SoundManager.sendSound(player, player.getLocation(), SoundType.LEVEL_UP);
             SoundManager.sendSound(player, player.getLocation(), SoundType.LEVEL_UP);
         }
         }
 
 
@@ -750,13 +748,13 @@ public class McMMOPlayer {
      * @return Modified experience
      * @return Modified experience
      */
      */
     private float modifyXpGain(PrimarySkillType primarySkillType, float xp) {
     private float modifyXpGain(PrimarySkillType primarySkillType, float xp) {
-        if (player.getGameMode() == GameMode.CREATIVE || (primarySkillType.getMaxLevel() <= getSkillLevel(primarySkillType)) || (Config.getInstance().getPowerLevelCap() <= getPowerLevel())) {
+        if (player.getGameMode() == GameMode.CREATIVE || (primarySkillType.getMaxLevel() <= getSkillLevel(primarySkillType)) || (MainConfig.getInstance().getPowerLevelCap() <= getPowerLevel())) {
             return 0;
             return 0;
         }
         }
 
 
         xp = (float) (xp / primarySkillType.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
         xp = (float) (xp / primarySkillType.getXpModifier() * ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier());
 
 
-        if (Config.getInstance().getToolModsEnabled()) {
+        if (MainConfig.getInstance().getToolModsEnabled()) {
             CustomTool tool = mcMMO.getModManager().getTool(player.getInventory().getItemInMainHand());
             CustomTool tool = mcMMO.getModManager().getTool(player.getInventory().getItemInMainHand());
 
 
             if (tool != null) {
             if (tool != null) {
@@ -867,7 +865,7 @@ public class McMMOPlayer {
     }
     }
 
 
     public void processAbilityActivation(PrimarySkillType skill) {
     public void processAbilityActivation(PrimarySkillType skill) {
-        if (Config.getInstance().getAbilitiesOnlyActivateWhenSneaking() && !player.isSneaking()) {
+        if (MainConfig.getInstance().getAbilitiesOnlyActivateWhenSneaking() && !player.isSneaking()) {
             return;
             return;
         }
         }
 
 
@@ -904,7 +902,7 @@ public class McMMOPlayer {
                 }
                 }
             }
             }
 
 
-            if (Config.getInstance().getAbilityMessagesEnabled()) {
+            if (MainConfig.getInstance().getAbilityMessagesEnabled()) {
                 NotificationManager.sendPlayerInformation(player, NotificationType.TOOL, tool.getRaiseTool());
                 NotificationManager.sendPlayerInformation(player, NotificationType.TOOL, tool.getRaiseTool());
                 SoundManager.sendSound(player, player.getLocation(), SoundType.TOOL_READY);
                 SoundManager.sendSound(player, player.getLocation(), SoundType.TOOL_READY);
             }
             }
@@ -927,7 +925,7 @@ public class McMMOPlayer {
     }
     }
 
 
     private boolean hasReachedLevelCap(PrimarySkillType skill) {
     private boolean hasReachedLevelCap(PrimarySkillType skill) {
-        return (skill.getMaxLevel() < getSkillLevel(skill) + 1) || (Config.getInstance().getPowerLevelCap() < getPowerLevel() + 1);
+        return (skill.getMaxLevel() < getSkillLevel(skill) + 1) || (MainConfig.getInstance().getPowerLevelCap() < getPowerLevel() + 1);
     }
     }
 
 
     /*
     /*
@@ -999,7 +997,7 @@ public class McMMOPlayer {
 
 
         UserManager.remove(thisPlayer);
         UserManager.remove(thisPlayer);
 
 
-        if(Config.getInstance().getScoreboardsEnabled())
+        if(MainConfig.getInstance().getScoreboardsEnabled())
             ScoreboardManager.teardownPlayer(thisPlayer);
             ScoreboardManager.teardownPlayer(thisPlayer);
 
 
         if (inParty()) {
         if (inParty()) {

+ 2 - 4
src/main/java/com/gmail/nossr50/datatypes/player/PlayerProfile.java

@@ -1,8 +1,6 @@
 package com.gmail.nossr50.datatypes.player;
 package com.gmail.nossr50.datatypes.player;
 
 
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.MobHealthbarType;
 import com.gmail.nossr50.datatypes.MobHealthbarType;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.experience.SkillXpGain;
 import com.gmail.nossr50.datatypes.experience.SkillXpGain;
@@ -49,7 +47,7 @@ public class PlayerProfile {
         this.uuid = uuid;
         this.uuid = uuid;
         this.playerName = playerName;
         this.playerName = playerName;
 
 
-        mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
+        mobHealthbarType = MainConfig.getInstance().getMobHealthbarDefault();
         scoreboardTipsShown = 0;
         scoreboardTipsShown = 0;
 
 
         for (SuperAbilityType superAbilityType : SuperAbilityType.values()) {
         for (SuperAbilityType superAbilityType : SuperAbilityType.values()) {

+ 11 - 12
src/main/java/com/gmail/nossr50/datatypes/skills/PrimarySkillType.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.datatypes.skills;
 package com.gmail.nossr50.datatypes.skills;
 
 
-import com.gmail.nossr50.config.Config;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.skills.SkillManager;
 import com.gmail.nossr50.skills.SkillManager;
@@ -137,37 +136,37 @@ public enum PrimarySkillType {
      * @return the max level of this skill
      * @return the max level of this skill
      */
      */
     public int getMaxLevel() {
     public int getMaxLevel() {
-        return Config.getInstance().getLevelCap(this);
+        return MainConfig.getInstance().getLevelCap(this);
     }
     }
 
 
     public boolean isSuperAbilityUnlocked(Player player) { return RankUtils.getRank(player, getAbility().getSubSkillTypeDefinition()) >= 1; }
     public boolean isSuperAbilityUnlocked(Player player) { return RankUtils.getRank(player, getAbility().getSubSkillTypeDefinition()) >= 1; }
 
 
     public boolean getPVPEnabled() {
     public boolean getPVPEnabled() {
-        return Config.getInstance().getPVPEnabled(this);
+        return MainConfig.getInstance().getPVPEnabled(this);
     }
     }
 
 
     public boolean getPVEEnabled() {
     public boolean getPVEEnabled() {
-        return Config.getInstance().getPVEEnabled(this);
+        return MainConfig.getInstance().getPVEEnabled(this);
     }
     }
 
 
     public boolean getDoubleDropsDisabled() {
     public boolean getDoubleDropsDisabled() {
-        return Config.getInstance().getDoubleDropsDisabled(this);
+        return MainConfig.getInstance().getDoubleDropsDisabled(this);
     }
     }
 
 
     public boolean getHardcoreStatLossEnabled() {
     public boolean getHardcoreStatLossEnabled() {
-        return Config.getInstance().getHardcoreStatLossEnabled(this);
+        return MainConfig.getInstance().getHardcoreStatLossEnabled(this);
     }
     }
 
 
     public void setHardcoreStatLossEnabled(boolean enable) {
     public void setHardcoreStatLossEnabled(boolean enable) {
-        Config.getInstance().setHardcoreStatLossEnabled(this, enable);
+        MainConfig.getInstance().setHardcoreStatLossEnabled(this, enable);
     }
     }
 
 
     public boolean getHardcoreVampirismEnabled() {
     public boolean getHardcoreVampirismEnabled() {
-        return Config.getInstance().getHardcoreVampirismEnabled(this);
+        return MainConfig.getInstance().getHardcoreVampirismEnabled(this);
     }
     }
 
 
     public void setHardcoreVampirismEnabled(boolean enable) {
     public void setHardcoreVampirismEnabled(boolean enable) {
-        Config.getInstance().setHardcoreVampirismEnabled(this, enable);
+        MainConfig.getInstance().setHardcoreVampirismEnabled(this, enable);
     }
     }
 
 
     public ToolType getTool() {
     public ToolType getTool() {
@@ -183,7 +182,7 @@ public enum PrimarySkillType {
     }
     }
 
 
     public static PrimarySkillType getSkill(String skillName) {
     public static PrimarySkillType getSkill(String skillName) {
-        if (!Config.getInstance().getLocale().equalsIgnoreCase("en_US")) {
+        if (!MainConfig.getInstance().getLocale().equalsIgnoreCase("en_US")) {
             for (PrimarySkillType type : values()) {
             for (PrimarySkillType type : values()) {
                 if (skillName.equalsIgnoreCase(LocaleLoader.getString(StringUtils.getCapitalized(type.name()) + ".SkillName"))) {
                 if (skillName.equalsIgnoreCase(LocaleLoader.getString(StringUtils.getCapitalized(type.name()) + ".SkillName"))) {
                     return type;
                     return type;
@@ -236,7 +235,7 @@ public enum PrimarySkillType {
     }
     }
 
 
     public String getName() {
     public String getName() {
-        return Config.getInstance().getLocale().equalsIgnoreCase("en_US") ? StringUtils.getCapitalized(this.toString()) : StringUtils.getCapitalized(LocaleLoader.getString(StringUtils.getCapitalized(this.toString()) + ".SkillName"));
+        return MainConfig.getInstance().getLocale().equalsIgnoreCase("en_US") ? StringUtils.getCapitalized(this.toString()) : StringUtils.getCapitalized(LocaleLoader.getString(StringUtils.getCapitalized(this.toString()) + ".SkillName"));
     }
     }
 
 
     public boolean getPermissions(Player player) {
     public boolean getPermissions(Player player) {

+ 3 - 3
src/main/java/com/gmail/nossr50/datatypes/skills/SuperAbilityType.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.datatypes.skills;
 package com.gmail.nossr50.datatypes.skills;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.util.BlockUtils;
 import com.gmail.nossr50.util.BlockUtils;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.Permissions;
 import com.gmail.nossr50.util.StringUtils;
 import com.gmail.nossr50.util.StringUtils;
@@ -100,11 +100,11 @@ public enum SuperAbilityType {
     }
     }
 
 
     public int getCooldown() {
     public int getCooldown() {
-        return Config.getInstance().getCooldown(this);
+        return MainConfig.getInstance().getCooldown(this);
     }
     }
 
 
     public int getMaxLength() {
     public int getMaxLength() {
-        return Config.getInstance().getMaxLength(this);
+        return MainConfig.getInstance().getMaxLength(this);
     }
     }
 
 
     public String getAbilityOn() {
     public String getAbilityOn() {

+ 1 - 2
src/main/java/com/gmail/nossr50/datatypes/skills/alchemy/AlchemyPotion.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.datatypes.skills.alchemy;
 package com.gmail.nossr50.datatypes.skills.alchemy;
 
 
-import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
 import org.bukkit.Color;
 import org.bukkit.Color;
 import org.bukkit.Material;
 import org.bukkit.Material;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
@@ -123,7 +122,7 @@ public class AlchemyPotion {
         if (!children.isEmpty()) {
         if (!children.isEmpty()) {
             for (Entry<ItemStack, String> child : children.entrySet()) {
             for (Entry<ItemStack, String> child : children.entrySet()) {
                 if (ingredient.isSimilar(child.getKey())) {
                 if (ingredient.isSimilar(child.getKey())) {
-                    return PotionConfig.getInstance().getPotion(child.getValue());
+                    return PotionMainConfig.getInstance().getPotion(child.getValue());
                 }
                 }
             }
             }
         }
         }

+ 1 - 2
src/main/java/com/gmail/nossr50/datatypes/skills/subskills/AbstractSubSkill.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.datatypes.skills.subskills;
 package com.gmail.nossr50.datatypes.skills.subskills;
 
 
-import com.gmail.nossr50.config.CoreSkillsConfig;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Interaction;
 import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Interaction;
 import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Rank;
 import com.gmail.nossr50.datatypes.skills.subskills.interfaces.Rank;
@@ -42,7 +41,7 @@ public abstract class AbstractSubSkill implements SubSkill, Interaction, Rank, S
     @Override @Deprecated
     @Override @Deprecated
     public boolean isEnabled() {
     public boolean isEnabled() {
         //TODO: This might be troublesome...
         //TODO: This might be troublesome...
-        return CoreSkillsConfig.getInstance().isSkillEnabled(this);
+        return CoreSkillsMainConfig.getInstance().isSkillEnabled(this);
     }
     }
 
 
     /**
     /**

+ 3 - 3
src/main/java/com/gmail/nossr50/datatypes/skills/subskills/acrobatics/Roll.java

@@ -1,7 +1,7 @@
 package com.gmail.nossr50.datatypes.skills.subskills.acrobatics;
 package com.gmail.nossr50.datatypes.skills.subskills.acrobatics;
 
 
 import com.gmail.nossr50.config.AdvancedConfig;
 import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.LimitedSizeList;
 import com.gmail.nossr50.datatypes.LimitedSizeList;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
@@ -272,7 +272,7 @@ public class Roll extends AcrobaticsSubSkill {
      * @return true if exploits are detected, false otherwise
      * @return true if exploits are detected, false otherwise
      */
      */
     private boolean isExploiting(Player player) {
     private boolean isExploiting(Player player) {
-        if (!Config.getInstance().getAcrobaticsPreventAFK()) {
+        if (!MainConfig.getInstance().getAcrobaticsPreventAFK()) {
             return false;
             return false;
         }
         }
 
 
@@ -291,7 +291,7 @@ public class Roll extends AcrobaticsSubSkill {
         return false; //NOT EXPLOITING
         return false; //NOT EXPLOITING
 /*
 /*
         Location fallLocation = player.getLocation();
         Location fallLocation = player.getLocation();
-        int maxTries = Config.getInstance().getAcrobaticsAFKMaxTries();
+        int maxTries = MainConfig.getInstance().getAcrobaticsAFKMaxTries();
 
 
         boolean sameLocation = (lastFallLocation != null && Misc.isNear(lastFallLocation, fallLocation, 2));
         boolean sameLocation = (lastFallLocation != null && Misc.isNear(lastFallLocation, fallLocation, 2));
 
 

+ 2 - 2
src/main/java/com/gmail/nossr50/datatypes/treasure/Treasure.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.datatypes.treasure;
 package com.gmail.nossr50.datatypes.treasure;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import org.bukkit.inventory.ItemStack;
 import org.bukkit.inventory.ItemStack;
 
 
 public abstract class Treasure {
 public abstract class Treasure {
@@ -42,7 +42,7 @@ public abstract class Treasure {
 
 
     public int getDropLevel() {
     public int getDropLevel() {
         //If they are in retro mode all requirements are scaled up by 10
         //If they are in retro mode all requirements are scaled up by 10
-        if(Config.getInstance().getIsRetroMode())
+        if(MainConfig.getInstance().getIsRetroMode())
             return dropLevel * 10;
             return dropLevel * 10;
 
 
         return dropLevel;
         return dropLevel;

+ 3 - 5
src/main/java/com/gmail/nossr50/listeners/BlockListener.java

@@ -1,9 +1,7 @@
 package com.gmail.nossr50.listeners;
 package com.gmail.nossr50.listeners;
 
 
-import com.gmail.nossr50.config.Config;
-import com.gmail.nossr50.config.HiddenConfig;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.config.WorldBlacklist;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
 import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
@@ -479,7 +477,7 @@ public class BlockListener implements Listener {
          *
          *
          * We don't need to check permissions here because they've already been checked for the ability to even activate.
          * We don't need to check permissions here because they've already been checked for the ability to even activate.
          */
          */
-        if (mcMMOPlayer.getAbilityMode(SuperAbilityType.TREE_FELLER) && BlockUtils.isLog(blockState) && Config.getInstance().getTreeFellerSoundsEnabled()) {
+        if (mcMMOPlayer.getAbilityMode(SuperAbilityType.TREE_FELLER) && BlockUtils.isLog(blockState) && MainConfig.getInstance().getTreeFellerSoundsEnabled()) {
             SoundManager.sendSound(player, blockState.getLocation(), SoundType.FIZZ);
             SoundManager.sendSound(player, blockState.getLocation(), SoundType.FIZZ);
         }
         }
     }
     }
@@ -613,7 +611,7 @@ public class BlockListener implements Listener {
     }
     }
 
 
     public void cleanupAbilityTools(Player player, McMMOPlayer mcMMOPlayer, BlockState blockState, ItemStack heldItem) {
     public void cleanupAbilityTools(Player player, McMMOPlayer mcMMOPlayer, BlockState blockState, ItemStack heldItem) {
-        if (HiddenConfig.getInstance().useEnchantmentBuffs()) {
+        if (HiddenMainConfig.getInstance().useEnchantmentBuffs()) {
             if ((ItemUtils.isPickaxe(heldItem) && !mcMMOPlayer.getAbilityMode(SuperAbilityType.SUPER_BREAKER)) || (ItemUtils.isShovel(heldItem) && !mcMMOPlayer.getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER))) {
             if ((ItemUtils.isPickaxe(heldItem) && !mcMMOPlayer.getAbilityMode(SuperAbilityType.SUPER_BREAKER)) || (ItemUtils.isShovel(heldItem) && !mcMMOPlayer.getAbilityMode(SuperAbilityType.GIGA_DRILL_BREAKER))) {
                 SkillUtils.removeAbilityBuff(heldItem);
                 SkillUtils.removeAbilityBuff(heldItem);
             }
             }

+ 3 - 5
src/main/java/com/gmail/nossr50/listeners/EntityListener.java

@@ -1,9 +1,7 @@
 package com.gmail.nossr50.listeners;
 package com.gmail.nossr50.listeners;
 
 
-import com.gmail.nossr50.config.AdvancedConfig;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.config.WorldBlacklist;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.meta.OldName;
 import com.gmail.nossr50.datatypes.meta.OldName;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
@@ -304,7 +302,7 @@ public class EntityListener implements Listener {
                 Player attackingPlayer = (Player) attacker;
                 Player attackingPlayer = (Player) attacker;
                 if (event.getDamage(DamageModifier.ABSORPTION) > 0) {
                 if (event.getDamage(DamageModifier.ABSORPTION) > 0) {
                     //If friendly fire is off don't allow players to hurt one another
                     //If friendly fire is off don't allow players to hurt one another
-                    if(!Config.getInstance().getPartyFriendlyFire())
+                    if(!MainConfig.getInstance().getPartyFriendlyFire())
                         if ((PartyManager.inSameParty(defendingPlayer, attackingPlayer) || PartyManager.areAllies(defendingPlayer, attackingPlayer)) && !(Permissions.friendlyFire(attackingPlayer) && Permissions.friendlyFire(defendingPlayer))) {
                         if ((PartyManager.inSameParty(defendingPlayer, attackingPlayer) || PartyManager.areAllies(defendingPlayer, attackingPlayer)) && !(Permissions.friendlyFire(attackingPlayer) && Permissions.friendlyFire(defendingPlayer))) {
                             event.setCancelled(true);
                             event.setCancelled(true);
                             return;
                             return;
@@ -373,7 +371,7 @@ public class EntityListener implements Listener {
             }
             }
 
 
             //Party Friendly Fire
             //Party Friendly Fire
-            if(!Config.getInstance().getPartyFriendlyFire())
+            if(!MainConfig.getInstance().getPartyFriendlyFire())
                 if ((PartyManager.inSameParty(defendingPlayer, attackingPlayer) || PartyManager.areAllies(defendingPlayer, attackingPlayer)) && !(Permissions.friendlyFire(attackingPlayer) && Permissions.friendlyFire(defendingPlayer))) {
                 if ((PartyManager.inSameParty(defendingPlayer, attackingPlayer) || PartyManager.areAllies(defendingPlayer, attackingPlayer)) && !(Permissions.friendlyFire(attackingPlayer) && Permissions.friendlyFire(defendingPlayer))) {
                     event.setCancelled(true);
                     event.setCancelled(true);
                     return;
                     return;

+ 4 - 4
src/main/java/com/gmail/nossr50/listeners/InventoryListener.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.listeners;
 package com.gmail.nossr50.listeners;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
 import com.gmail.nossr50.datatypes.skills.SubSkillType;
@@ -384,17 +384,17 @@ public class InventoryListener implements Listener {
 
 
         ItemStack item = event.getItem();
         ItemStack item = event.getItem();
 
 
-        if (Config.getInstance().getPreventHopperTransferIngredients() && item.getType() != Material.POTION && item.getType() != Material.SPLASH_POTION && item.getType() != Material.LINGERING_POTION) {
+        if (MainConfig.getInstance().getPreventHopperTransferIngredients() && item.getType() != Material.POTION && item.getType() != Material.SPLASH_POTION && item.getType() != Material.LINGERING_POTION) {
             event.setCancelled(true);
             event.setCancelled(true);
             return;
             return;
         }
         }
 
 
-        if (Config.getInstance().getPreventHopperTransferBottles() && (item.getType() == Material.POTION || item.getType() == Material.SPLASH_POTION || item.getType() == Material.LINGERING_POTION)) {
+        if (MainConfig.getInstance().getPreventHopperTransferBottles() && (item.getType() == Material.POTION || item.getType() == Material.SPLASH_POTION || item.getType() == Material.LINGERING_POTION)) {
             event.setCancelled(true);
             event.setCancelled(true);
             return;
             return;
         }
         }
 
 
-        if (Config.getInstance().getEnabledForHoppers() && AlchemyPotionBrewer.isValidIngredient(null, item)) {
+        if (MainConfig.getInstance().getEnabledForHoppers() && AlchemyPotionBrewer.isValidIngredient(null, item)) {
             AlchemyPotionBrewer.scheduleCheck(null, (BrewingStand) holder);
             AlchemyPotionBrewer.scheduleCheck(null, (BrewingStand) holder);
         }
         }
     }
     }

+ 13 - 14
src/main/java/com/gmail/nossr50/listeners/PlayerListener.java

@@ -3,9 +3,8 @@ package com.gmail.nossr50.listeners;
 import com.gmail.nossr50.chat.ChatManager;
 import com.gmail.nossr50.chat.ChatManager;
 import com.gmail.nossr50.chat.ChatManagerFactory;
 import com.gmail.nossr50.chat.ChatManagerFactory;
 import com.gmail.nossr50.chat.PartyChatManager;
 import com.gmail.nossr50.chat.PartyChatManager;
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.config.WorldBlacklist;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.party.Party;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
@@ -76,7 +75,7 @@ public class PlayerListener implements Listener {
                 return;
                 return;
         }
         }
 
 
-        if (!UserManager.hasPlayerDataKey(player) || Config.getInstance().getXPAfterTeleportCooldown() <= 0 || event.getFrom().equals(event.getTo())) {
+        if (!UserManager.hasPlayerDataKey(player) || MainConfig.getInstance().getXPAfterTeleportCooldown() <= 0 || event.getFrom().equals(event.getTo())) {
             return;
             return;
         }
         }
 
 
@@ -257,7 +256,7 @@ public class PlayerListener implements Listener {
                 //TODO Update to new API once available! Waiting for case CAUGHT_TREASURE:
                 //TODO Update to new API once available! Waiting for case CAUGHT_TREASURE:
                 Item fishingCatch = (Item) event.getCaught();
                 Item fishingCatch = (Item) event.getCaught();
 
 
-                if (Config.getInstance().getFishingOverrideTreasures() &&
+                if (MainConfig.getInstance().getFishingOverrideTreasures() &&
                         fishingCatch.getItemStack().getType() != Material.SALMON &&
                         fishingCatch.getItemStack().getType() != Material.SALMON &&
                         fishingCatch.getItemStack().getType() != Material.COD &&
                         fishingCatch.getItemStack().getType() != Material.COD &&
                         fishingCatch.getItemStack().getType() != Material.TROPICAL_FISH &&
                         fishingCatch.getItemStack().getType() != Material.TROPICAL_FISH &&
@@ -435,7 +434,7 @@ public class PlayerListener implements Listener {
 
 
             /*if (player.getInventory().getItemInMainHand().getType() == Material.AIR) {
             /*if (player.getInventory().getItemInMainHand().getType() == Material.AIR) {
                 Unarmed.handleItemPickup(player, event);
                 Unarmed.handleItemPickup(player, event);
-                *//*boolean cancel = Config.getInstance().getUnarmedItemPickupDisabled() || pickupSuccess;
+                *//*boolean cancel = MainConfig.getInstance().getUnarmedItemPickupDisabled() || pickupSuccess;
                 event.setCancelled(cancel);
                 event.setCancelled(cancel);
 
 
                 if (pickupSuccess) {
                 if (pickupSuccess) {
@@ -486,7 +485,7 @@ public class PlayerListener implements Listener {
 
 
         new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
         new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 1); // 1 Tick delay to ensure the player is marked as online before we begin loading
 
 
-        if (Config.getInstance().getMOTDEnabled() && Permissions.motd(player)) {
+        if (MainConfig.getInstance().getMOTDEnabled() && Permissions.motd(player)) {
             Motd.displayAll(player);
             Motd.displayAll(player);
         }
         }
 
 
@@ -548,7 +547,7 @@ public class PlayerListener implements Listener {
             case RIGHT_CLICK_BLOCK:
             case RIGHT_CLICK_BLOCK:
                 Material type = block.getType();
                 Material type = block.getType();
 
 
-                if (!Config.getInstance().getAbilitiesOnlyActivateWhenSneaking() || player.isSneaking()) {
+                if (!MainConfig.getInstance().getAbilitiesOnlyActivateWhenSneaking() || player.isSneaking()) {
                     /* REPAIR CHECKS */
                     /* REPAIR CHECKS */
                     if (type == Repair.anvilMaterial && PrimarySkillType.REPAIR.getPermissions(player) && mcMMO.getRepairableManager().isRepairable(heldItem)) {
                     if (type == Repair.anvilMaterial && PrimarySkillType.REPAIR.getPermissions(player) && mcMMO.getRepairableManager().isRepairable(heldItem)) {
                         RepairManager repairManager = mcMMOPlayer.getRepairManager();
                         RepairManager repairManager = mcMMOPlayer.getRepairManager();
@@ -588,7 +587,7 @@ public class PlayerListener implements Listener {
             case LEFT_CLICK_BLOCK:
             case LEFT_CLICK_BLOCK:
                 type = block.getType();
                 type = block.getType();
 
 
-                if (!Config.getInstance().getAbilitiesOnlyActivateWhenSneaking() || player.isSneaking()) {
+                if (!MainConfig.getInstance().getAbilitiesOnlyActivateWhenSneaking() || player.isSneaking()) {
                     /* REPAIR CHECKS */
                     /* REPAIR CHECKS */
                     if (type == Repair.anvilMaterial && PrimarySkillType.REPAIR.getPermissions(player) && mcMMO.getRepairableManager().isRepairable(heldItem)) {
                     if (type == Repair.anvilMaterial && PrimarySkillType.REPAIR.getPermissions(player) && mcMMO.getRepairableManager().isRepairable(heldItem)) {
                         RepairManager repairManager = mcMMOPlayer.getRepairManager();
                         RepairManager repairManager = mcMMOPlayer.getRepairManager();
@@ -671,7 +670,7 @@ public class PlayerListener implements Listener {
 
 
                 /* ACTIVATION & ITEM CHECKS */
                 /* ACTIVATION & ITEM CHECKS */
                 if (BlockUtils.canActivateTools(blockState)) {
                 if (BlockUtils.canActivateTools(blockState)) {
-                    if (Config.getInstance().getAbilitiesEnabled()) {
+                    if (MainConfig.getInstance().getAbilitiesEnabled()) {
                         if (BlockUtils.canActivateHerbalism(blockState)) {
                         if (BlockUtils.canActivateHerbalism(blockState)) {
                             mcMMOPlayer.processAbilityActivation(PrimarySkillType.HERBALISM);
                             mcMMOPlayer.processAbilityActivation(PrimarySkillType.HERBALISM);
                         }
                         }
@@ -725,7 +724,7 @@ public class PlayerListener implements Listener {
                 }
                 }
                 
                 
                 /* ACTIVATION CHECKS */
                 /* ACTIVATION CHECKS */
-                if (Config.getInstance().getAbilitiesEnabled()) {
+                if (MainConfig.getInstance().getAbilitiesEnabled()) {
                     mcMMOPlayer.processAbilityActivation(PrimarySkillType.AXES);
                     mcMMOPlayer.processAbilityActivation(PrimarySkillType.AXES);
                     mcMMOPlayer.processAbilityActivation(PrimarySkillType.EXCAVATION);
                     mcMMOPlayer.processAbilityActivation(PrimarySkillType.EXCAVATION);
                     mcMMOPlayer.processAbilityActivation(PrimarySkillType.HERBALISM);
                     mcMMOPlayer.processAbilityActivation(PrimarySkillType.HERBALISM);
@@ -757,13 +756,13 @@ public class PlayerListener implements Listener {
                 Material type = heldItem.getType();
                 Material type = heldItem.getType();
                 TamingManager tamingManager = mcMMOPlayer.getTamingManager();
                 TamingManager tamingManager = mcMMOPlayer.getTamingManager();
 
 
-                if (type == Config.getInstance().getTamingCOTWMaterial(EntityType.WOLF)) {
+                if (type == MainConfig.getInstance().getTamingCOTWMaterial(EntityType.WOLF)) {
                     tamingManager.summonWolf();
                     tamingManager.summonWolf();
                 }
                 }
-                else if (type == Config.getInstance().getTamingCOTWMaterial(EntityType.OCELOT)) {
+                else if (type == MainConfig.getInstance().getTamingCOTWMaterial(EntityType.OCELOT)) {
                     tamingManager.summonOcelot();
                     tamingManager.summonOcelot();
                 }
                 }
-                else if (type == Config.getInstance().getTamingCOTWMaterial(EntityType.HORSE)) {
+                else if (type == MainConfig.getInstance().getTamingCOTWMaterial(EntityType.HORSE)) {
                     tamingManager.summonHorse();
                     tamingManager.summonHorse();
                 }
                 }
 
 
@@ -826,7 +825,7 @@ public class PlayerListener implements Listener {
      */
      */
     @EventHandler(priority = EventPriority.LOWEST)
     @EventHandler(priority = EventPriority.LOWEST)
     public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
     public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
-        if (!Config.getInstance().getLocale().equalsIgnoreCase("en_US")) {
+        if (!MainConfig.getInstance().getLocale().equalsIgnoreCase("en_US")) {
             String message = event.getMessage();
             String message = event.getMessage();
             String command = message.substring(1).split(" ")[0];
             String command = message.substring(1).split(" ")[0];
             String lowerCaseCommand = command.toLowerCase();
             String lowerCaseCommand = command.toLowerCase();

+ 6 - 7
src/main/java/com/gmail/nossr50/listeners/SelfListener.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.listeners;
 package com.gmail.nossr50.listeners;
 
 
-import com.gmail.nossr50.config.Config;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -40,27 +39,27 @@ public class SelfListener implements Listener {
             UserManager.getPlayer(player).processUnlockNotifications(plugin, event.getSkill(), previousLevelGained);
             UserManager.getPlayer(player).processUnlockNotifications(plugin, event.getSkill(), previousLevelGained);
         }
         }
 
 
-        if(Config.getInstance().getScoreboardsEnabled())
+        if(MainConfig.getInstance().getScoreboardsEnabled())
             ScoreboardManager.handleLevelUp(player, skill);
             ScoreboardManager.handleLevelUp(player, skill);
 
 
-        if (!Config.getInstance().getLevelUpEffectsEnabled()) {
+        if (!MainConfig.getInstance().getLevelUpEffectsEnabled()) {
             return;
             return;
         }
         }
 
 
-        if ((event.getSkillLevel() % Config.getInstance().getLevelUpEffectsTier()) == 0) {
+        if ((event.getSkillLevel() % MainConfig.getInstance().getLevelUpEffectsTier()) == 0) {
             skill.celebrateLevelUp(player);
             skill.celebrateLevelUp(player);
         }
         }
     }
     }
 
 
     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
     public void onPlayerXp(McMMOPlayerXpGainEvent event) {
     public void onPlayerXp(McMMOPlayerXpGainEvent event) {
-        if(Config.getInstance().getScoreboardsEnabled())
+        if(MainConfig.getInstance().getScoreboardsEnabled())
             ScoreboardManager.handleXp(event.getPlayer(), event.getSkill());
             ScoreboardManager.handleXp(event.getPlayer(), event.getSkill());
     }
     }
 
 
     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
     public void onAbility(McMMOPlayerAbilityActivateEvent event) {
     public void onAbility(McMMOPlayerAbilityActivateEvent event) {
-        if(Config.getInstance().getScoreboardsEnabled())
+        if(MainConfig.getInstance().getScoreboardsEnabled())
             ScoreboardManager.cooldownUpdate(event.getPlayer(), event.getSkill());
             ScoreboardManager.cooldownUpdate(event.getPlayer(), event.getSkill());
     }
     }
 
 

+ 2 - 2
src/main/java/com/gmail/nossr50/locale/LocaleLoader.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.locale;
 package com.gmail.nossr50.locale;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import org.bukkit.ChatColor;
 import org.bukkit.ChatColor;
 
 
@@ -76,7 +76,7 @@ public final class LocaleLoader {
         if (bundle == null) {
         if (bundle == null) {
             Locale.setDefault(new Locale("en", "US"));
             Locale.setDefault(new Locale("en", "US"));
             Locale locale = null;
             Locale locale = null;
-            String[] myLocale = Config.getInstance().getLocale().split("[-_ ]");
+            String[] myLocale = MainConfig.getInstance().getLocale().split("[-_ ]");
 
 
             if (myLocale.length == 1) {
             if (myLocale.length == 1) {
                 locale = new Locale(myLocale[0]);
                 locale = new Locale(myLocale[0]);

+ 27 - 29
src/main/java/com/gmail/nossr50/mcMMO.java

@@ -1,15 +1,13 @@
 package com.gmail.nossr50;
 package com.gmail.nossr50;
 
 
-import com.gmail.nossr50.config.*;
-import com.gmail.nossr50.config.experience.ExperienceConfig;
+import com.gmail.nossr50.config.MainConfig;
+import com.gmail.nossr50.config.WorldBlacklist;
 import com.gmail.nossr50.config.mods.ArmorConfigManager;
 import com.gmail.nossr50.config.mods.ArmorConfigManager;
 import com.gmail.nossr50.config.mods.BlockConfigManager;
 import com.gmail.nossr50.config.mods.BlockConfigManager;
 import com.gmail.nossr50.config.mods.EntityConfigManager;
 import com.gmail.nossr50.config.mods.EntityConfigManager;
 import com.gmail.nossr50.config.mods.ToolConfigManager;
 import com.gmail.nossr50.config.mods.ToolConfigManager;
-import com.gmail.nossr50.config.skills.alchemy.PotionConfig;
 import com.gmail.nossr50.config.skills.repair.RepairConfigManager;
 import com.gmail.nossr50.config.skills.repair.RepairConfigManager;
 import com.gmail.nossr50.config.skills.salvage.SalvageConfigManager;
 import com.gmail.nossr50.config.skills.salvage.SalvageConfigManager;
-import com.gmail.nossr50.config.treasure.TreasureConfig;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.database.DatabaseManagerFactory;
 import com.gmail.nossr50.database.DatabaseManagerFactory;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
@@ -147,7 +145,7 @@ public class mcMMO extends JavaPlugin {
             }
             }
 
 
             //Store this value so other plugins can check it
             //Store this value so other plugins can check it
-            isRetroModeEnabled = Config.getInstance().getIsRetroMode();
+            isRetroModeEnabled = MainConfig.getInstance().getIsRetroMode();
 
 
             if (getServer().getName().equals("Cauldron") || getServer().getName().equals("MCPC+")) {
             if (getServer().getName().equals("Cauldron") || getServer().getName().equals("MCPC+")) {
                 checkModConfigs();
                 checkModConfigs();
@@ -184,7 +182,7 @@ public class mcMMO extends JavaPlugin {
 
 
             placeStore = ChunkManagerFactory.getChunkManager(); // Get our ChunkletManager
             placeStore = ChunkManagerFactory.getChunkManager(); // Get our ChunkletManager
 
 
-            if (Config.getInstance().getPTPCommandWorldPermissions()) {
+            if (MainConfig.getInstance().getPTPCommandWorldPermissions()) {
                 Permissions.generateWorldTeleportPermissions();
                 Permissions.generateWorldTeleportPermissions();
             }
             }
 
 
@@ -195,11 +193,11 @@ public class mcMMO extends JavaPlugin {
 
 
             Metrics metrics;
             Metrics metrics;
 
 
-            if(Config.getInstance().getIsMetricsEnabled()) {
+            if(MainConfig.getInstance().getIsMetricsEnabled()) {
                 metrics = new Metrics(this);
                 metrics = new Metrics(this);
                 metrics.addCustomChart(new Metrics.SimplePie("version", () -> getDescription().getVersion()));
                 metrics.addCustomChart(new Metrics.SimplePie("version", () -> getDescription().getVersion()));
 
 
-                if(Config.getInstance().getIsRetroMode())
+                if(MainConfig.getInstance().getIsRetroMode())
                     metrics.addCustomChart(new Metrics.SimplePie("scaling", () -> "Standard"));
                     metrics.addCustomChart(new Metrics.SimplePie("scaling", () -> "Standard"));
                 else
                 else
                     metrics.addCustomChart(new Metrics.SimplePie("scaling", () -> "Retro"));
                     metrics.addCustomChart(new Metrics.SimplePie("scaling", () -> "Retro"));
@@ -241,7 +239,7 @@ public class mcMMO extends JavaPlugin {
             PartyManager.saveParties(); // Save our parties
             PartyManager.saveParties(); // Save our parties
 
 
             //TODO: Needed?
             //TODO: Needed?
-            if(Config.getInstance().getScoreboardsEnabled())
+            if(MainConfig.getInstance().getScoreboardsEnabled())
                 ScoreboardManager.teardownAll();
                 ScoreboardManager.teardownAll();
 
 
             formulaManager.saveFormula();
             formulaManager.saveFormula();
@@ -256,7 +254,7 @@ public class mcMMO extends JavaPlugin {
         debug("Unregister all events...");
         debug("Unregister all events...");
         HandlerList.unregisterAll(this); // Cancel event registrations
         HandlerList.unregisterAll(this); // Cancel event registrations
 
 
-        if (Config.getInstance().getBackupsEnabled()) {
+        if (MainConfig.getInstance().getBackupsEnabled()) {
             // Remove other tasks BEFORE starting the Backup, or we just cancel it straight away.
             // Remove other tasks BEFORE starting the Backup, or we just cancel it straight away.
             try {
             try {
                 ZipLibrary.mcMMOBackup();
                 ZipLibrary.mcMMOBackup();
@@ -422,12 +420,12 @@ public class mcMMO extends JavaPlugin {
 
 
 
 
         // Force the loading of config files
         // Force the loading of config files
-        TreasureConfig.getInstance();
-        HiddenConfig.getInstance();
+        TreasureMainConfig.getInstance();
+        HiddenMainConfig.getInstance();
         AdvancedConfig.getInstance();
         AdvancedConfig.getInstance();
-        PotionConfig.getInstance();
-        CoreSkillsConfig.getInstance();
-        SoundConfig.getInstance();
+        PotionMainConfig.getInstance();
+        CoreSkillsMainConfig.getInstance();
+        SoundMainConfig.getInstance();
         RankConfig.getInstance();
         RankConfig.getInstance();
 
 
         new ChildConfig();
         new ChildConfig();
@@ -435,19 +433,19 @@ public class mcMMO extends JavaPlugin {
         List<Repairable> repairables = new ArrayList<Repairable>();
         List<Repairable> repairables = new ArrayList<Repairable>();
         List<Salvageable> salvageables = new ArrayList<Salvageable>();
         List<Salvageable> salvageables = new ArrayList<Salvageable>();
 
 
-        if (Config.getInstance().getToolModsEnabled()) {
+        if (MainConfig.getInstance().getToolModsEnabled()) {
             new ToolConfigManager(this);
             new ToolConfigManager(this);
         }
         }
 
 
-        if (Config.getInstance().getArmorModsEnabled()) {
+        if (MainConfig.getInstance().getArmorModsEnabled()) {
             new ArmorConfigManager(this);
             new ArmorConfigManager(this);
         }
         }
 
 
-        if (Config.getInstance().getBlockModsEnabled()) {
+        if (MainConfig.getInstance().getBlockModsEnabled()) {
             new BlockConfigManager(this);
             new BlockConfigManager(this);
         }
         }
 
 
-        if (Config.getInstance().getEntityModsEnabled()) {
+        if (MainConfig.getInstance().getEntityModsEnabled()) {
             new EntityConfigManager(this);
             new EntityConfigManager(this);
         }
         }
 
 
@@ -485,20 +483,20 @@ public class mcMMO extends JavaPlugin {
          * Acrobatics skills
          * Acrobatics skills
          */
          */
 
 
-        if(CoreSkillsConfig.getInstance().isPrimarySkillEnabled(PrimarySkillType.ACROBATICS))
+        if(CoreSkillsMainConfig.getInstance().isPrimarySkillEnabled(PrimarySkillType.ACROBATICS))
         {
         {
             System.out.println("[mcMMO]" + " enabling Acrobatics Skills");
             System.out.println("[mcMMO]" + " enabling Acrobatics Skills");
 
 
             //TODO: Should do this differently
             //TODO: Should do this differently
             Roll roll = new Roll();
             Roll roll = new Roll();
-            CoreSkillsConfig.getInstance().isSkillEnabled(roll);
+            CoreSkillsMainConfig.getInstance().isSkillEnabled(roll);
             InteractionManager.registerSubSkill(new Roll());
             InteractionManager.registerSubSkill(new Roll());
         }
         }
     }
     }
 
 
     private void registerCustomRecipes() {
     private void registerCustomRecipes() {
         getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
         getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
-            if (Config.getInstance().getChimaeraEnabled()) {
+            if (MainConfig.getInstance().getChimaeraEnabled()) {
                 getServer().addRecipe(ChimaeraWing.getChimaeraWingRecipe());
                 getServer().addRecipe(ChimaeraWing.getChimaeraWingRecipe());
             }
             }
         }, 40);
         }, 40);
@@ -506,7 +504,7 @@ public class mcMMO extends JavaPlugin {
 
 
     private void scheduleTasks() {
     private void scheduleTasks() {
         // Periodic save timer (Saves every 10 minutes by default)
         // Periodic save timer (Saves every 10 minutes by default)
-        long saveIntervalTicks = Config.getInstance().getSaveInterval() * 1200;
+        long saveIntervalTicks = MainConfig.getInstance().getSaveInterval() * 1200;
         new SaveTimerTask().runTaskTimer(this, saveIntervalTicks, saveIntervalTicks);
         new SaveTimerTask().runTaskTimer(this, saveIntervalTicks, saveIntervalTicks);
 
 
         // Cleanup the backups folder
         // Cleanup the backups folder
@@ -516,7 +514,7 @@ public class mcMMO extends JavaPlugin {
         new BleedTimerTask().runTaskTimer(this, 1 * Misc.TICK_CONVERSION_FACTOR, 1 * (Misc.TICK_CONVERSION_FACTOR / 2));
         new BleedTimerTask().runTaskTimer(this, 1 * Misc.TICK_CONVERSION_FACTOR, 1 * (Misc.TICK_CONVERSION_FACTOR / 2));
 
 
         // Old & Powerless User remover
         // Old & Powerless User remover
-        long purgeIntervalTicks = Config.getInstance().getPurgeInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
+        long purgeIntervalTicks = MainConfig.getInstance().getPurgeInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
 
 
         if (purgeIntervalTicks == 0) {
         if (purgeIntervalTicks == 0) {
             new UserPurgeTask().runTaskLaterAsynchronously(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
             new UserPurgeTask().runTaskLaterAsynchronously(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
@@ -526,7 +524,7 @@ public class mcMMO extends JavaPlugin {
         }
         }
 
 
         // Automatically remove old members from parties
         // Automatically remove old members from parties
-        long kickIntervalTicks = Config.getInstance().getAutoPartyKickInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
+        long kickIntervalTicks = MainConfig.getInstance().getAutoPartyKickInterval() * 60L * 60L * Misc.TICK_CONVERSION_FACTOR;
 
 
         if (kickIntervalTicks == 0) {
         if (kickIntervalTicks == 0) {
             new PartyAutoKickTask().runTaskLater(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
             new PartyAutoKickTask().runTaskLater(this, 2 * Misc.TICK_CONVERSION_FACTOR); // Start 2 seconds after startup.
@@ -549,22 +547,22 @@ public class mcMMO extends JavaPlugin {
     }
     }
 
 
     private void checkModConfigs() {
     private void checkModConfigs() {
-        if (!Config.getInstance().getToolModsEnabled()) {
+        if (!MainConfig.getInstance().getToolModsEnabled()) {
             getLogger().warning("Cauldron implementation found, but the custom tool config for mcMMO is disabled!");
             getLogger().warning("Cauldron implementation found, but the custom tool config for mcMMO is disabled!");
             getLogger().info("To enable, set Mods.Tool_Mods_Enabled to TRUE in config.yml.");
             getLogger().info("To enable, set Mods.Tool_Mods_Enabled to TRUE in config.yml.");
         }
         }
 
 
-        if (!Config.getInstance().getArmorModsEnabled()) {
+        if (!MainConfig.getInstance().getArmorModsEnabled()) {
             getLogger().warning("Cauldron implementation found, but the custom armor config for mcMMO is disabled!");
             getLogger().warning("Cauldron implementation found, but the custom armor config for mcMMO is disabled!");
             getLogger().info("To enable, set Mods.Armor_Mods_Enabled to TRUE in config.yml.");
             getLogger().info("To enable, set Mods.Armor_Mods_Enabled to TRUE in config.yml.");
         }
         }
 
 
-        if (!Config.getInstance().getBlockModsEnabled()) {
+        if (!MainConfig.getInstance().getBlockModsEnabled()) {
             getLogger().warning("Cauldron implementation found, but the custom block config for mcMMO is disabled!");
             getLogger().warning("Cauldron implementation found, but the custom block config for mcMMO is disabled!");
             getLogger().info("To enable, set Mods.Block_Mods_Enabled to TRUE in config.yml.");
             getLogger().info("To enable, set Mods.Block_Mods_Enabled to TRUE in config.yml.");
         }
         }
 
 
-        if (!Config.getInstance().getEntityModsEnabled()) {
+        if (!MainConfig.getInstance().getEntityModsEnabled()) {
             getLogger().warning("Cauldron implementation found, but the custom entity config for mcMMO is disabled!");
             getLogger().warning("Cauldron implementation found, but the custom entity config for mcMMO is disabled!");
             getLogger().info("To enable, set Mods.Entity_Mods_Enabled to TRUE in config.yml.");
             getLogger().info("To enable, set Mods.Entity_Mods_Enabled to TRUE in config.yml.");
         }
         }

+ 7 - 7
src/main/java/com/gmail/nossr50/party/PartyManager.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.party;
 package com.gmail.nossr50.party;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.chat.ChatMode;
 import com.gmail.nossr50.datatypes.database.UpgradeType;
 import com.gmail.nossr50.datatypes.database.UpgradeType;
 import com.gmail.nossr50.datatypes.interactions.NotificationType;
 import com.gmail.nossr50.datatypes.interactions.NotificationType;
@@ -63,7 +63,7 @@ public final class PartyManager {
      */
      */
     public static boolean isPartyFull(Player player, Party targetParty)
     public static boolean isPartyFull(Player player, Party targetParty)
     {
     {
-        return !Permissions.partySizeBypass(player) && Config.getInstance().getPartyMaxSize() >= 1 && targetParty.getOnlineMembers().size() >= Config.getInstance().getPartyMaxSize();
+        return !Permissions.partySizeBypass(player) && MainConfig.getInstance().getPartyMaxSize() >= 1 && targetParty.getOnlineMembers().size() >= MainConfig.getInstance().getPartyMaxSize();
     }
     }
 
 
     /**
     /**
@@ -131,7 +131,7 @@ public final class PartyManager {
 
 
         if (party != null) {
         if (party != null) {
             Player player = mcMMOPlayer.getPlayer();
             Player player = mcMMOPlayer.getPlayer();
-            double range = Config.getInstance().getPartyShareRange();
+            double range = MainConfig.getInstance().getPartyShareRange();
 
 
             for (Player member : party.getOnlineMembers()) {
             for (Player member : party.getOnlineMembers()) {
                 if (!player.equals(member) && member.isValid() && Misc.isNear(player.getLocation(), member.getLocation(), range)) {
                 if (!player.equals(member) && member.isValid() && Misc.isNear(player.getLocation(), member.getLocation(), range)) {
@@ -149,7 +149,7 @@ public final class PartyManager {
 
 
         if (party != null) {
         if (party != null) {
             Player player = mcMMOPlayer.getPlayer();
             Player player = mcMMOPlayer.getPlayer();
-            double range = Config.getInstance().getPartyShareRange();
+            double range = MainConfig.getInstance().getPartyShareRange();
 
 
             for (Player member : party.getVisibleMembers(player)) {
             for (Player member : party.getVisibleMembers(player)) {
                 if (!player.equals(member)
                 if (!player.equals(member)
@@ -404,9 +404,9 @@ public final class PartyManager {
         /*
         /*
          * Don't let players join a full party
          * Don't let players join a full party
          */
          */
-        if(Config.getInstance().getPartyMaxSize() > 0 && invite.getMembers().size() >= Config.getInstance().getPartyMaxSize())
+        if(MainConfig.getInstance().getPartyMaxSize() > 0 && invite.getMembers().size() >= MainConfig.getInstance().getPartyMaxSize())
         {
         {
-            NotificationManager.sendPlayerInformation(mcMMOPlayer.getPlayer(), NotificationType.PARTY_MESSAGE, "Commands.Party.PartyFull.InviteAccept", invite.getName(), String.valueOf(Config.getInstance().getPartyMaxSize()));
+            NotificationManager.sendPlayerInformation(mcMMOPlayer.getPlayer(), NotificationType.PARTY_MESSAGE, "Commands.Party.PartyFull.InviteAccept", invite.getName(), String.valueOf(MainConfig.getInstance().getPartyMaxSize()));
             return;
             return;
         }
         }
 
 
@@ -766,7 +766,7 @@ public final class PartyManager {
      * @param level The current party level
      * @param level The current party level
      */
      */
     public static void informPartyMembersLevelUp(Party party, int levelsGained, int level) {
     public static void informPartyMembersLevelUp(Party party, int levelsGained, int level) {
-        boolean levelUpSoundsEnabled = Config.getInstance().getLevelUpSoundsEnabled();
+        boolean levelUpSoundsEnabled = MainConfig.getInstance().getLevelUpSoundsEnabled();
         for (Player member : party.getOnlineMembers()) {
         for (Player member : party.getOnlineMembers()) {
             member.sendMessage(LocaleLoader.getString("Party.LevelUp", levelsGained, level));
             member.sendMessage(LocaleLoader.getString("Party.LevelUp", levelsGained, level));
 
 

+ 3 - 4
src/main/java/com/gmail/nossr50/party/ShareHandler.java

@@ -1,7 +1,6 @@
 package com.gmail.nossr50.party;
 package com.gmail.nossr50.party;
 
 
-import com.gmail.nossr50.config.Config;
-import com.gmail.nossr50.config.party.ItemWeightConfig;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.experience.XPGainReason;
 import com.gmail.nossr50.datatypes.experience.XPGainSource;
 import com.gmail.nossr50.datatypes.experience.XPGainSource;
 import com.gmail.nossr50.datatypes.party.ItemShareType;
 import com.gmail.nossr50.datatypes.party.ItemShareType;
@@ -44,7 +43,7 @@ public final class ShareHandler {
         nearMembers.add(mcMMOPlayer.getPlayer());
         nearMembers.add(mcMMOPlayer.getPlayer());
 
 
         int partySize = nearMembers.size();
         int partySize = nearMembers.size();
-        double shareBonus = Math.min(Config.getInstance().getPartyShareBonusBase() + (partySize * Config.getInstance().getPartyShareBonusIncrease()), Config.getInstance().getPartyShareBonusCap());
+        double shareBonus = Math.min(MainConfig.getInstance().getPartyShareBonusBase() + (partySize * MainConfig.getInstance().getPartyShareBonusIncrease()), MainConfig.getInstance().getPartyShareBonusCap());
         float splitXp = (float) (xp / partySize * shareBonus);
         float splitXp = (float) (xp / partySize * shareBonus);
 
 
         for (Player member : nearMembers) {
         for (Player member : nearMembers) {
@@ -98,7 +97,7 @@ public final class ShareHandler {
 
 
         switch (shareMode) {
         switch (shareMode) {
             case EQUAL:
             case EQUAL:
-                int itemWeight = ItemWeightConfig.getInstance().getItemWeight(itemStack.getType());
+                int itemWeight = ItemWeightMainConfig.getInstance().getItemWeight(itemStack.getType());
 
 
                 for (int i = 0; i < itemStack.getAmount(); i++) {
                 for (int i = 0; i < itemStack.getAmount(); i++) {
                     int highestRoll = 0;
                     int highestRoll = 0;

+ 4 - 4
src/main/java/com/gmail/nossr50/runnables/backups/CleanBackupsTask.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.runnables.backups;
 package com.gmail.nossr50.runnables.backups;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import org.bukkit.scheduler.BukkitRunnable;
 import org.bukkit.scheduler.BukkitRunnable;
 
 
@@ -48,11 +48,11 @@ public class CleanBackupsTask extends BukkitRunnable {
             int weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
             int weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
             int year = cal.get(Calendar.YEAR);
             int year = cal.get(Calendar.YEAR);
 
 
-            if (isPast24Hours(date) && Config.getInstance().getKeepLast24Hours()) {
+            if (isPast24Hours(date) && MainConfig.getInstance().getKeepLast24Hours()) {
                 // Keep all files from the last 24 hours
                 // Keep all files from the last 24 hours
                 continue;
                 continue;
             }
             }
-            else if (isLastWeek(date) && !savedDays.contains(dayOfWeek) && Config.getInstance().getKeepDailyLastWeek()) {
+            else if (isLastWeek(date) && !savedDays.contains(dayOfWeek) && MainConfig.getInstance().getKeepDailyLastWeek()) {
                 // Keep daily backups of the past week
                 // Keep daily backups of the past week
                 savedDays.add(dayOfWeek);
                 savedDays.add(dayOfWeek);
                 continue;
                 continue;
@@ -64,7 +64,7 @@ public class CleanBackupsTask extends BukkitRunnable {
                     savedYearsWeeks.put(year, savedWeeks);
                     savedYearsWeeks.put(year, savedWeeks);
                 }
                 }
 
 
-                if (!savedWeeks.contains(weekOfYear) && Config.getInstance().getKeepWeeklyPastMonth()) {
+                if (!savedWeeks.contains(weekOfYear) && MainConfig.getInstance().getKeepWeeklyPastMonth()) {
                     // Keep one backup of each week
                     // Keep one backup of each week
                     savedWeeks.add(weekOfYear);
                     savedWeeks.add(weekOfYear);
                     continue;
                     continue;

+ 2 - 2
src/main/java/com/gmail/nossr50/runnables/commands/McrankCommandDisplayTask.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.runnables.commands;
 package com.gmail.nossr50.runnables.commands;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -30,7 +30,7 @@ public class McrankCommandDisplayTask extends BukkitRunnable {
 
 
     @Override
     @Override
     public void run() {
     public void run() {
-        if (useBoard && Config.getInstance().getScoreboardsEnabled()) {
+        if (useBoard && MainConfig.getInstance().getScoreboardsEnabled()) {
             displayBoard();
             displayBoard();
         }
         }
 
 

+ 2 - 2
src/main/java/com/gmail/nossr50/runnables/commands/MctopCommandDisplayTask.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.runnables.commands;
 package com.gmail.nossr50.runnables.commands;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.datatypes.database.PlayerStat;
 import com.gmail.nossr50.datatypes.database.PlayerStat;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 import com.gmail.nossr50.locale.LocaleLoader;
 import com.gmail.nossr50.locale.LocaleLoader;
@@ -34,7 +34,7 @@ public class MctopCommandDisplayTask extends BukkitRunnable {
 
 
     @Override
     @Override
     public void run() {
     public void run() {
-        if (useBoard && Config.getInstance().getScoreboardsEnabled()) {
+        if (useBoard && MainConfig.getInstance().getScoreboardsEnabled()) {
             displayBoard();
             displayBoard();
         }
         }
 
 

+ 0 - 1
src/main/java/com/gmail/nossr50/runnables/database/FormulaConversionTask.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.runnables.database;
 package com.gmail.nossr50.runnables.database;
 
 
-import com.gmail.nossr50.config.experience.ExperienceConfig;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.experience.FormulaType;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;
 import com.gmail.nossr50.datatypes.player.McMMOPlayer;

+ 3 - 4
src/main/java/com/gmail/nossr50/runnables/database/UUIDUpdateAsyncTask.java

@@ -1,6 +1,5 @@
 package com.gmail.nossr50.runnables.database;
 package com.gmail.nossr50.runnables.database;
 
 
-import com.gmail.nossr50.config.HiddenConfig;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.database.DatabaseManager;
 import com.gmail.nossr50.datatypes.database.UpgradeType;
 import com.gmail.nossr50.datatypes.database.UpgradeType;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
@@ -16,9 +15,9 @@ import java.util.logging.Level;
 
 
 public class UUIDUpdateAsyncTask extends BukkitRunnable {
 public class UUIDUpdateAsyncTask extends BukkitRunnable {
     private mcMMO plugin;
     private mcMMO plugin;
-    private static final int MAX_LOOKUP = Math.max(HiddenConfig.getInstance().getUUIDConvertAmount(), 100);
-    private static final int RATE_LIMIT = HiddenConfig.getInstance().getMojangRateLimit();
-    private static final long LIMIT_PERIOD = HiddenConfig.getInstance().getMojangLimitPeriod();
+    private static final int MAX_LOOKUP = Math.max(HiddenMainConfig.getInstance().getUUIDConvertAmount(), 100);
+    private static final int RATE_LIMIT = HiddenMainConfig.getInstance().getMojangRateLimit();
+    private static final long LIMIT_PERIOD = HiddenMainConfig.getInstance().getMojangLimitPeriod();
     private static final int BATCH_SIZE = MAX_LOOKUP * 3;
     private static final int BATCH_SIZE = MAX_LOOKUP * 3;
 
 
     private List<String> userNames;
     private List<String> userNames;

+ 2 - 2
src/main/java/com/gmail/nossr50/runnables/database/UserPurgeTask.java

@@ -1,6 +1,6 @@
 package com.gmail.nossr50.runnables.database;
 package com.gmail.nossr50.runnables.database;
 
 
-import com.gmail.nossr50.config.Config;
+import com.gmail.nossr50.config.MainConfig;
 import com.gmail.nossr50.mcMMO;
 import com.gmail.nossr50.mcMMO;
 import org.bukkit.scheduler.BukkitRunnable;
 import org.bukkit.scheduler.BukkitRunnable;
 
 
@@ -13,7 +13,7 @@ public class UserPurgeTask extends BukkitRunnable {
         lock.lock();
         lock.lock();
         mcMMO.getDatabaseManager().purgePowerlessUsers();
         mcMMO.getDatabaseManager().purgePowerlessUsers();
 
 
-        if (Config.getInstance().getOldUsersCutoff() != -1) {
+        if (MainConfig.getInstance().getOldUsersCutoff() != -1) {
             mcMMO.getDatabaseManager().purgeOldUsers();
             mcMMO.getDatabaseManager().purgeOldUsers();
         }
         }
         lock.unlock();
         lock.unlock();

Some files were not shown because too many files changed in this diff