SHARE
TWEET

Untitled

a guest Sep 19th, 2019 80 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package com.gmail.nossr50.database;
  2.  
  3. import com.gmail.nossr50.config.AdvancedConfig;
  4. import com.gmail.nossr50.config.Config;
  5. import com.gmail.nossr50.datatypes.MobHealthbarType;
  6. import com.gmail.nossr50.datatypes.database.DatabaseType;
  7. import com.gmail.nossr50.datatypes.database.PlayerStat;
  8. import com.gmail.nossr50.datatypes.database.UpgradeType;
  9. import com.gmail.nossr50.datatypes.player.PlayerProfile;
  10. import com.gmail.nossr50.datatypes.player.UniqueDataType;
  11. import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
  12. import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
  13. import com.gmail.nossr50.mcMMO;
  14. import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask;
  15. import com.gmail.nossr50.util.Misc;
  16. import com.gmail.nossr50.util.StringUtils;
  17. import org.bukkit.Bukkit;
  18. import org.bukkit.OfflinePlayer;
  19.  
  20. import java.io.*;
  21. import java.util.*;
  22.  
  23. public final class FlatfileDatabaseManager implements DatabaseManager {
  24.     private final HashMap<PrimarySkillType, List<PlayerStat>> playerStatHash = new HashMap<PrimarySkillType, List<PlayerStat>>();
  25.     private final List<PlayerStat> powerLevels = new ArrayList<PlayerStat>();
  26.     private long lastUpdate = 0;
  27.  
  28.     private final long UPDATE_WAIT_TIME = 600000L; // 10 minutes
  29.     private final File usersFile;
  30.     private static final Object fileWritingLock = new Object();
  31.  
  32.     protected FlatfileDatabaseManager() {
  33.         usersFile = new File(mcMMO.getUsersFilePath());
  34.         checkStructure();
  35.         updateLeaderboards();
  36.  
  37.         if (mcMMO.getUpgradeManager().shouldUpgrade(UpgradeType.ADD_UUIDS)) {
  38.             new UUIDUpdateAsyncTask(mcMMO.p, getStoredUsers()).runTaskAsynchronously(mcMMO.p);
  39.         }
  40.     }
  41.  
  42.     public void purgePowerlessUsers() {
  43.         int purgedUsers = 0;
  44.  
  45.         mcMMO.p.getLogger().info("Purging powerless users...");
  46.  
  47.         BufferedReader in = null;
  48.         FileWriter out = null;
  49.         String usersFilePath = mcMMO.getUsersFilePath();
  50.  
  51.         // This code is O(n) instead of O(n²)
  52.         synchronized (fileWritingLock) {
  53.             try {
  54.                 in = new BufferedReader(new FileReader(usersFilePath));
  55.                 StringBuilder writer = new StringBuilder();
  56.                 String line;
  57.  
  58.                 while ((line = in.readLine()) != null) {
  59.                     String[] character = line.split(":");
  60.                     Map<PrimarySkillType, Integer> skills = getSkillMapFromLine(character);
  61.  
  62.                     boolean powerless = true;
  63.                     for (int skill : skills.values()) {
  64.                         if (skill != 0) {
  65.                             powerless = false;
  66.                             break;
  67.                         }
  68.                     }
  69.  
  70.                     // If they're still around, rewrite them to the file.
  71.                     if (!powerless) {
  72.                         writer.append(line).append("\r\n");
  73.                     }
  74.                     else {
  75.                         purgedUsers++;
  76.                     }
  77.                 }
  78.  
  79.                 // Write the new file
  80.                 out = new FileWriter(usersFilePath);
  81.                 out.write(writer.toString());
  82.             }
  83.             catch (IOException e) {
  84.                 mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
  85.             }
  86.             finally {
  87.                 if (in != null) {
  88.                     try {
  89.                         in.close();
  90.                     }
  91.                     catch (IOException e) {
  92.                         // Ignore
  93.                     }
  94.                 }
  95.                 if (out != null) {
  96.                     try {
  97.                         out.close();
  98.                     }
  99.                     catch (IOException e) {
  100.                         // Ignore
  101.                     }
  102.                 }
  103.             }
  104.         }
  105.  
  106.         mcMMO.p.getLogger().info("Purged " + purgedUsers + " users from the database.");
  107.     }
  108.  
  109.     public void purgeOldUsers() {
  110.         int removedPlayers = 0;
  111.         long currentTime = System.currentTimeMillis();
  112.  
  113.         mcMMO.p.getLogger().info("Purging old users...");
  114.  
  115.         BufferedReader in = null;
  116.         FileWriter out = null;
  117.         String usersFilePath = mcMMO.getUsersFilePath();
  118.  
  119.         // This code is O(n) instead of O(n²)
  120.         synchronized (fileWritingLock) {
  121.             try {
  122.                 in = new BufferedReader(new FileReader(usersFilePath));
  123.                 StringBuilder writer = new StringBuilder();
  124.                 String line;
  125.  
  126.                 while ((line = in.readLine()) != null) {
  127.                     String[] character = line.split(":");
  128.                     String name = character[USERNAME];
  129.                     long lastPlayed = 0;
  130.                     boolean rewrite = false;
  131.                     try {
  132.                         lastPlayed = Long.parseLong(character[37]) * Misc.TIME_CONVERSION_FACTOR;
  133.                     }
  134.                     catch (NumberFormatException e) {
  135.                         e.printStackTrace();
  136.                     }
  137.                     if (lastPlayed == 0) {
  138.                         OfflinePlayer player = mcMMO.p.getServer().getOfflinePlayer(name);
  139.                         lastPlayed = player.getLastPlayed();
  140.                         rewrite = true;
  141.                     }
  142.  
  143.                     if (currentTime - lastPlayed > PURGE_TIME) {
  144.                         removedPlayers++;
  145.                     }
  146.                     else {
  147.                         if (rewrite) {
  148.                             // Rewrite their data with a valid time
  149.                             character[37] = Long.toString(lastPlayed);
  150.                             String newLine = org.apache.commons.lang.StringUtils.join(character, ":");
  151.                             writer.append(newLine).append("\r\n");
  152.                         }
  153.                         else {
  154.                             writer.append(line).append("\r\n");
  155.                         }
  156.                     }
  157.                 }
  158.  
  159.                 // Write the new file
  160.                 out = new FileWriter(usersFilePath);
  161.                 out.write(writer.toString());
  162.             }
  163.             catch (IOException e) {
  164.                 mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
  165.             }
  166.             finally {
  167.                 if (in != null) {
  168.                     try {
  169.                         in.close();
  170.                     }
  171.                     catch (IOException e) {
  172.                         // Ignore
  173.                     }
  174.                 }
  175.                 if (out != null) {
  176.                     try {
  177.                         out.close();
  178.                     }
  179.                     catch (IOException e) {
  180.                         // Ignore
  181.                     }
  182.                 }
  183.             }
  184.         }
  185.  
  186.         mcMMO.p.getLogger().info("Purged " + removedPlayers + " users from the database.");
  187.     }
  188.  
  189.     public boolean removeUser(String playerName, UUID uuid) {
  190.         //NOTE: UUID is unused for FlatFile for this interface implementation
  191.         boolean worked = false;
  192.  
  193.         BufferedReader in = null;
  194.         FileWriter out = null;
  195.         String usersFilePath = mcMMO.getUsersFilePath();
  196.  
  197.         synchronized (fileWritingLock) {
  198.             try {
  199.                 in = new BufferedReader(new FileReader(usersFilePath));
  200.                 StringBuilder writer = new StringBuilder();
  201.                 String line;
  202.  
  203.                 while ((line = in.readLine()) != null) {
  204.                     // Write out the same file but when we get to the player we want to remove, we skip his line.
  205.                     if (!worked && line.split(":")[USERNAME].equalsIgnoreCase(playerName)) {
  206.                         mcMMO.p.getLogger().info("User found, removing...");
  207.                         worked = true;
  208.                         continue; // Skip the player
  209.                     }
  210.  
  211.                     writer.append(line).append("\r\n");
  212.                 }
  213.  
  214.                 out = new FileWriter(usersFilePath); // Write out the new file
  215.                 out.write(writer.toString());
  216.             }
  217.             catch (Exception e) {
  218.                 mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
  219.             }
  220.             finally {
  221.                 if (in != null) {
  222.                     try {
  223.                         in.close();
  224.                     }
  225.                     catch (IOException e) {
  226.                         // Ignore
  227.                     }
  228.                 }
  229.                 if (out != null) {
  230.                     try {
  231.                         out.close();
  232.                     }
  233.                     catch (IOException e) {
  234.                         // Ignore
  235.                     }
  236.                 }
  237.             }
  238.         }
  239.  
  240.         Misc.profileCleanup(playerName);
  241.  
  242.         return worked;
  243.     }
  244.  
  245.     @Override
  246.     public void cleanupUser(UUID uuid) {
  247.         //Not used in FlatFile
  248.     }
  249.  
  250.     public boolean saveUser(PlayerProfile profile) {
  251.         String playerName = profile.getPlayerName();
  252.         UUID uuid = profile.getUniqueId();
  253.  
  254.         BufferedReader in = null;
  255.         FileWriter out = null;
  256.         String usersFilePath = mcMMO.getUsersFilePath();
  257.  
  258.         synchronized (fileWritingLock) {
  259.             try {
  260.                 // Open the file
  261.                 in = new BufferedReader(new FileReader(usersFilePath));
  262.                 StringBuilder writer = new StringBuilder();
  263.                 String line;
  264.  
  265.                 boolean wroteUser = false;
  266.                 // While not at the end of the file
  267.                 while ((line = in.readLine()) != null) {
  268.                     // Read the line in and copy it to the output if it's not the player we want to edit
  269.                     String[] character = line.split(":");
  270.                     if (!(uuid != null && character[UUID_INDEX].equalsIgnoreCase(uuid.toString())) && !character[USERNAME].equalsIgnoreCase(playerName)) {
  271.                         writer.append(line).append("\r\n");
  272.                     }
  273.                     else {
  274.                         // Otherwise write the new player information
  275.                         writeUserToLine(profile, playerName, uuid, writer);
  276.                         wroteUser = true;
  277.                     }
  278.                 }
  279.  
  280.                 /*
  281.                  * If we couldn't find the user in the DB we need to add him
  282.                  */
  283.                 if(!wroteUser)
  284.                 {
  285.                     writeUserToLine(profile, playerName, uuid, writer);
  286.                 }
  287.  
  288.                 // Write the new file
  289.                 out = new FileWriter(usersFilePath);
  290.                 out.write(writer.toString());
  291.                 return true;
  292.             }
  293.             catch (Exception e) {
  294.                 e.printStackTrace();
  295.                 return false;
  296.             }
  297.             finally {
  298.                 if (in != null) {
  299.                     try {
  300.                         in.close();
  301.                     }
  302.                     catch (IOException e) {
  303.                         // Ignore
  304.                     }
  305.                 }
  306.                 if (out != null) {
  307.                     try {
  308.                         out.close();
  309.                     }
  310.                     catch (IOException e) {
  311.                         // Ignore
  312.                     }
  313.                 }
  314.             }
  315.         }
  316.     }
  317.  
  318.     private void writeUserToLine(PlayerProfile profile, String playerName, UUID uuid, StringBuilder writer) {
  319.         writer.append(playerName).append(":");
  320.         writer.append(profile.getSkillLevel(PrimarySkillType.MINING)).append(":");
  321.         writer.append(":");
  322.         writer.append(":");
  323.         writer.append(profile.getSkillXpLevel(PrimarySkillType.MINING)).append(":");
  324.         writer.append(profile.getSkillLevel(PrimarySkillType.WOODCUTTING)).append(":");
  325.         writer.append(profile.getSkillXpLevel(PrimarySkillType.WOODCUTTING)).append(":");
  326.         writer.append(profile.getSkillLevel(PrimarySkillType.REPAIR)).append(":");
  327.         writer.append(profile.getSkillLevel(PrimarySkillType.UNARMED)).append(":");
  328.         writer.append(profile.getSkillLevel(PrimarySkillType.HERBALISM)).append(":");
  329.         writer.append(profile.getSkillLevel(PrimarySkillType.EXCAVATION)).append(":");
  330.         writer.append(profile.getSkillLevel(PrimarySkillType.ARCHERY)).append(":");
  331.         writer.append(profile.getSkillLevel(PrimarySkillType.SWORDS)).append(":");
  332.         writer.append(profile.getSkillLevel(PrimarySkillType.AXES)).append(":");
  333.         writer.append(profile.getSkillLevel(PrimarySkillType.ACROBATICS)).append(":");
  334.         writer.append(profile.getSkillXpLevel(PrimarySkillType.REPAIR)).append(":");
  335.         writer.append(profile.getSkillXpLevel(PrimarySkillType.UNARMED)).append(":");
  336.         writer.append(profile.getSkillXpLevel(PrimarySkillType.HERBALISM)).append(":");
  337.         writer.append(profile.getSkillXpLevel(PrimarySkillType.EXCAVATION)).append(":");
  338.         writer.append(profile.getSkillXpLevel(PrimarySkillType.ARCHERY)).append(":");
  339.         writer.append(profile.getSkillXpLevel(PrimarySkillType.SWORDS)).append(":");
  340.         writer.append(profile.getSkillXpLevel(PrimarySkillType.AXES)).append(":");
  341.         writer.append(profile.getSkillXpLevel(PrimarySkillType.ACROBATICS)).append(":");
  342.         writer.append(":");
  343.         writer.append(profile.getSkillLevel(PrimarySkillType.TAMING)).append(":");
  344.         writer.append(profile.getSkillXpLevel(PrimarySkillType.TAMING)).append(":");
  345.         writer.append((int) profile.getAbilityDATS(SuperAbilityType.BERSERK)).append(":");
  346.         writer.append((int) profile.getAbilityDATS(SuperAbilityType.GIGA_DRILL_BREAKER)).append(":");
  347.         writer.append((int) profile.getAbilityDATS(SuperAbilityType.TREE_FELLER)).append(":");
  348.         writer.append((int) profile.getAbilityDATS(SuperAbilityType.GREEN_TERRA)).append(":");
  349.         writer.append((int) profile.getAbilityDATS(SuperAbilityType.SERRATED_STRIKES)).append(":");
  350.         writer.append((int) profile.getAbilityDATS(SuperAbilityType.SKULL_SPLITTER)).append(":");
  351.         writer.append((int) profile.getAbilityDATS(SuperAbilityType.SUPER_BREAKER)).append(":");
  352.         writer.append(":");
  353.         writer.append(profile.getSkillLevel(PrimarySkillType.FISHING)).append(":");
  354.         writer.append(profile.getSkillXpLevel(PrimarySkillType.FISHING)).append(":");
  355.         writer.append((int) profile.getAbilityDATS(SuperAbilityType.BLAST_MINING)).append(":");
  356.         writer.append(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR).append(":");
  357.         MobHealthbarType mobHealthbarType = profile.getMobHealthbarType();
  358.         writer.append(mobHealthbarType == null ? Config.getInstance().getMobHealthbarDefault().toString() : mobHealthbarType.toString()).append(":");
  359.         writer.append(profile.getSkillLevel(PrimarySkillType.ALCHEMY)).append(":");
  360.         writer.append(profile.getSkillXpLevel(PrimarySkillType.ALCHEMY)).append(":");
  361.         writer.append(uuid != null ? uuid.toString() : "NULL").append(":");
  362.         writer.append(profile.getScoreboardTipsShown()).append(":");
  363.         writer.append(profile.getUniqueData(UniqueDataType.CHIMAERA_WING_DATS)).append(":");
  364.         writer.append(profile.getSkillLevel(PrimarySkillType.HUNTING)).append(":");
  365.         writer.append(profile.getSkillXpLevel(PrimarySkillType.HUNTING)).append(":");
  366.         writer.append("\r\n");
  367.     }
  368.  
  369.     public List<PlayerStat> readLeaderboard(PrimarySkillType skill, int pageNumber, int statsPerPage) {
  370.         updateLeaderboards();
  371.         List<PlayerStat> statsList = skill == null ? powerLevels : playerStatHash.get(skill);
  372.         int fromIndex = (Math.max(pageNumber, 1) - 1) * statsPerPage;
  373.  
  374.         return statsList.subList(Math.min(fromIndex, statsList.size()), Math.min(fromIndex + statsPerPage, statsList.size()));
  375.     }
  376.  
  377.     public Map<PrimarySkillType, Integer> readRank(String playerName) {
  378.         updateLeaderboards();
  379.  
  380.         Map<PrimarySkillType, Integer> skills = new HashMap<PrimarySkillType, Integer>();
  381.  
  382.         for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
  383.             skills.put(skill, getPlayerRank(playerName, playerStatHash.get(skill)));
  384.         }
  385.  
  386.         skills.put(null, getPlayerRank(playerName, powerLevels));
  387.  
  388.         return skills;
  389.     }
  390.  
  391.     public void newUser(String playerName, UUID uuid) {
  392.         BufferedWriter out = null;
  393.         synchronized (fileWritingLock) {
  394.             try {
  395.                 // Open the file to write the player
  396.                 out = new BufferedWriter(new FileWriter(mcMMO.getUsersFilePath(), true));
  397.  
  398.                 String startingLevel = AdvancedConfig.getInstance().getStartingLevel() + ":";
  399.  
  400.                 // Add the player to the end
  401.                 out.append(playerName).append(":");
  402.                 out.append(startingLevel); // Mining
  403.                 out.append(":");
  404.                 out.append(":");
  405.                 out.append("0:"); // Xp
  406.                 out.append(startingLevel); // Woodcutting
  407.                 out.append("0:"); // WoodCuttingXp
  408.                 out.append(startingLevel); // Repair
  409.                 out.append(startingLevel); // Unarmed
  410.                 out.append(startingLevel); // Herbalism
  411.                 out.append(startingLevel); // Excavation
  412.                 out.append(startingLevel); // Archery
  413.                 out.append(startingLevel); // Swords
  414.                 out.append(startingLevel); // Axes
  415.                 out.append(startingLevel); // Acrobatics
  416.                 out.append("0:"); // RepairXp
  417.                 out.append("0:"); // UnarmedXp
  418.                 out.append("0:"); // HerbalismXp
  419.                 out.append("0:"); // ExcavationXp
  420.                 out.append("0:"); // ArcheryXp
  421.                 out.append("0:"); // SwordsXp
  422.                 out.append("0:"); // AxesXp
  423.                 out.append("0:"); // AcrobaticsXp
  424.                 out.append(":");
  425.                 out.append(startingLevel); // Taming
  426.                 out.append("0:"); // TamingXp
  427.                 out.append("0:"); // DATS
  428.                 out.append("0:"); // DATS
  429.                 out.append("0:"); // DATS
  430.                 out.append("0:"); // DATS
  431.                 out.append("0:"); // DATS
  432.                 out.append("0:"); // DATS
  433.                 out.append("0:"); // DATS
  434.                 out.append(":");
  435.                 out.append(startingLevel); // Fishing
  436.                 out.append("0:"); // FishingXp
  437.                 out.append("0:"); // Blast Mining
  438.                 out.append(String.valueOf(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR)).append(":"); // LastLogin
  439.                 out.append(Config.getInstance().getMobHealthbarDefault().toString()).append(":"); // Mob Healthbar HUD
  440.                 out.append(startingLevel); // Alchemy
  441.                 out.append("0:"); // AlchemyXp
  442.                 out.append(uuid != null ? uuid.toString() : "NULL").append(":"); // UUID
  443.                 out.append("0:"); // Scoreboard tips shown
  444.                 out.append(startingLevel); // Hunter
  445.                 out.append("0:"); // HunterXp
  446.                 // Add more in the same format as the line above
  447.  
  448.                 out.newLine();
  449.             }
  450.             catch (Exception e) {
  451.                 e.printStackTrace();
  452.             }
  453.             finally {
  454.                 if (out != null) {
  455.                     try {
  456.                         out.close();
  457.                     }
  458.                     catch (IOException e) {
  459.                         // Ignore
  460.                     }
  461.                 }
  462.             }
  463.         }
  464.     }
  465.  
  466.     @Deprecated
  467.     public PlayerProfile loadPlayerProfile(String playerName, boolean create) {
  468.         return loadPlayerProfile(playerName, null, false);
  469.     }
  470.  
  471.     public PlayerProfile loadPlayerProfile(UUID uuid) {
  472.         return loadPlayerProfile("", uuid, false);
  473.     }
  474.  
  475.     public PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean create) {
  476.         BufferedReader in = null;
  477.         String usersFilePath = mcMMO.getUsersFilePath();
  478.  
  479.         synchronized (fileWritingLock) {
  480.             try {
  481.                 // Open the user file
  482.                 in = new BufferedReader(new FileReader(usersFilePath));
  483.                 String line;
  484.  
  485.                 while ((line = in.readLine()) != null) {
  486.                     // Find if the line contains the player we want.
  487.                     String[] character = line.split(":");
  488.  
  489.                     // Compare names because we don't have a valid uuid for that player even
  490.                     // if input uuid is not null
  491.                     if (character[UUID_INDEX].equalsIgnoreCase("NULL")) {
  492.                         if (!character[USERNAME].equalsIgnoreCase(playerName)) {
  493.                             continue;
  494.                         }
  495.                     }
  496.                     // If input uuid is not null then we should compare uuids
  497.                     else if ((uuid != null && !character[UUID_INDEX].equalsIgnoreCase(uuid.toString())) || (uuid == null && !character[USERNAME].equalsIgnoreCase(playerName))) {
  498.                         continue;
  499.                     }
  500.  
  501.                     // Update playerName in database after name change
  502.                     if (!character[USERNAME].equalsIgnoreCase(playerName)) {
  503.                         mcMMO.p.debug("Name change detected: " + character[USERNAME] + " => " + playerName);
  504.                         character[USERNAME] = playerName;
  505.                     }
  506.  
  507.                     return loadFromLine(character);
  508.                 }
  509.  
  510.                 // Didn't find the player, create a new one
  511.                 if (create) {
  512.                     if (uuid == null) {
  513.                         newUser(playerName, uuid);
  514.                         return new PlayerProfile(playerName, true);
  515.                     }
  516.  
  517.                     newUser(playerName, uuid);
  518.                     return new PlayerProfile(playerName, uuid, true);
  519.                 }
  520.             }
  521.             catch (Exception e) {
  522.                 e.printStackTrace();
  523.             }
  524.             finally {
  525.                 // I have no idea why it's necessary to inline tryClose() here, but it removes
  526.                 // a resource leak warning, and I'm trusting the compiler on this one.
  527.                 if (in != null) {
  528.                     try {
  529.                         in.close();
  530.                     }
  531.                     catch (IOException e) {
  532.                         // Ignore
  533.                     }
  534.                 }
  535.             }
  536.         }
  537.  
  538.         // Return unloaded profile
  539.         if (uuid == null) {
  540.             return new PlayerProfile(playerName);
  541.         }
  542.  
  543.         return new PlayerProfile(playerName, uuid);
  544.     }
  545.  
  546.     public void convertUsers(DatabaseManager destination) {
  547.         BufferedReader in = null;
  548.         String usersFilePath = mcMMO.getUsersFilePath();
  549.         int convertedUsers = 0;
  550.         long startMillis = System.currentTimeMillis();
  551.  
  552.         synchronized (fileWritingLock) {
  553.             try {
  554.                 // Open the user file
  555.                 in = new BufferedReader(new FileReader(usersFilePath));
  556.                 String line;
  557.  
  558.                 while ((line = in.readLine()) != null) {
  559.                     String[] character = line.split(":");
  560.  
  561.                     try {
  562.                         destination.saveUser(loadFromLine(character));
  563.                     }
  564.                     catch (Exception e) {
  565.                         e.printStackTrace();
  566.                     }
  567.                     convertedUsers++;
  568.                     Misc.printProgress(convertedUsers, progressInterval, startMillis);
  569.                 }
  570.             }
  571.             catch (Exception e) {
  572.                 e.printStackTrace();
  573.             }
  574.             finally {
  575.                 if (in != null) {
  576.                     try {
  577.                         in.close();
  578.                     }
  579.                     catch (IOException e) {
  580.                         // Ignore
  581.                     }
  582.                 }
  583.             }
  584.         }
  585.     }
  586.  
  587.     public boolean saveUserUUID(String userName, UUID uuid) {
  588.         boolean worked = false;
  589.  
  590.         int i = 0;
  591.         BufferedReader in = null;
  592.         FileWriter out = null;
  593.         String usersFilePath = mcMMO.getUsersFilePath();
  594.  
  595.         synchronized (fileWritingLock) {
  596.             try {
  597.                 in = new BufferedReader(new FileReader(usersFilePath));
  598.                 StringBuilder writer = new StringBuilder();
  599.                 String line;
  600.  
  601.                 while ((line = in.readLine()) != null) {
  602.                     String[] character = line.split(":");
  603.                     if (!worked && character[USERNAME].equalsIgnoreCase(userName)) {
  604.                         if (character.length < 42) {
  605.                             mcMMO.p.getLogger().severe("Could not update UUID for " + userName + "!");
  606.                             mcMMO.p.getLogger().severe("Database entry is invalid.");
  607.                             continue;
  608.                         }
  609.  
  610.                         line = line.replace(character[UUID_INDEX], uuid.toString());
  611.                         worked = true;
  612.                     }
  613.  
  614.                     i++;
  615.                     writer.append(line).append("\r\n");
  616.                 }
  617.  
  618.                 out = new FileWriter(usersFilePath); // Write out the new file
  619.                 out.write(writer.toString());
  620.             }
  621.             catch (Exception e) {
  622.                 mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
  623.             }
  624.             finally {
  625.                 mcMMO.p.getLogger().info(i + " entries written while saving UUID for " + userName);
  626.                 if (in != null) {
  627.                     try {
  628.                         in.close();
  629.                     }
  630.                     catch (IOException e) {
  631.                         // Ignore
  632.                     }
  633.                 }
  634.                 if (out != null) {
  635.                     try {
  636.                         out.close();
  637.                     }
  638.                     catch (IOException e) {
  639.                         // Ignore
  640.                     }
  641.                 }
  642.             }
  643.         }
  644.  
  645.         return worked;
  646.     }
  647.  
  648.     public boolean saveUserUUIDs(Map<String, UUID> fetchedUUIDs) {
  649.         BufferedReader in = null;
  650.         FileWriter out = null;
  651.         String usersFilePath = mcMMO.getUsersFilePath();
  652.         int i = 0;
  653.  
  654.         synchronized (fileWritingLock) {
  655.             try {
  656.                 in = new BufferedReader(new FileReader(usersFilePath));
  657.                 StringBuilder writer = new StringBuilder();
  658.                 String line;
  659.  
  660.                 while (((line = in.readLine()) != null)) {
  661.                     String[] character = line.split(":");
  662.                     if (!fetchedUUIDs.isEmpty() && fetchedUUIDs.containsKey(character[USERNAME])) {
  663.                         if (character.length < 42) {
  664.                             mcMMO.p.getLogger().severe("Could not update UUID for " + character[USERNAME] + "!");
  665.                             mcMMO.p.getLogger().severe("Database entry is invalid.");
  666.                             continue;
  667.                         }
  668.  
  669.                         character[UUID_INDEX] = fetchedUUIDs.remove(character[USERNAME]).toString();
  670.                         line = new StringBuilder(org.apache.commons.lang.StringUtils.join(character, ":")).append(":").toString();
  671.                     }
  672.  
  673.                     i++;
  674.                     writer.append(line).append("\r\n");
  675.                 }
  676.  
  677.                 out = new FileWriter(usersFilePath); // Write out the new file
  678.                 out.write(writer.toString());
  679.             }
  680.             catch (Exception e) {
  681.                 mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
  682.             }
  683.             finally {
  684.                 mcMMO.p.getLogger().info(i + " entries written while saving UUID batch");
  685.                 if (in != null) {
  686.                     try {
  687.                         in.close();
  688.                     }
  689.                     catch (IOException e) {
  690.                         // Ignore
  691.                     }
  692.                 }
  693.                 if (out != null) {
  694.                     try {
  695.                         out.close();
  696.                     }
  697.                     catch (IOException e) {
  698.                         // Ignore
  699.                     }
  700.                 }
  701.             }
  702.         }
  703.  
  704.         return true;
  705.     }
  706.  
  707.     public List<String> getStoredUsers() {
  708.         ArrayList<String> users = new ArrayList<String>();
  709.         BufferedReader in = null;
  710.         String usersFilePath = mcMMO.getUsersFilePath();
  711.  
  712.         synchronized (fileWritingLock) {
  713.             try {
  714.                 // Open the user file
  715.                 in = new BufferedReader(new FileReader(usersFilePath));
  716.                 String line;
  717.  
  718.                 while ((line = in.readLine()) != null) {
  719.                     String[] character = line.split(":");
  720.                     users.add(character[USERNAME]);
  721.                 }
  722.             }
  723.             catch (Exception e) {
  724.                 e.printStackTrace();
  725.             }
  726.             finally {
  727.                 if (in != null) {
  728.                     try {
  729.                         in.close();
  730.                     }
  731.                     catch (IOException e) {
  732.                         // Ignore
  733.                     }
  734.                 }
  735.             }
  736.         }
  737.         return users;
  738.     }
  739.  
  740.     /**
  741.      * Update the leader boards.
  742.      */
  743.     private void updateLeaderboards() {
  744.         // Only update FFS leaderboards every 10 minutes.. this puts a lot of strain on the server (depending on the size of the database) and should not be done frequently
  745.         if (System.currentTimeMillis() < lastUpdate + UPDATE_WAIT_TIME) {
  746.             return;
  747.         }
  748.  
  749.         String usersFilePath = mcMMO.getUsersFilePath();
  750.         lastUpdate = System.currentTimeMillis(); // Log when the last update was run
  751.         powerLevels.clear(); // Clear old values from the power levels
  752.  
  753.         // Initialize lists
  754.         List<PlayerStat> mining = new ArrayList<PlayerStat>();
  755.         List<PlayerStat> woodcutting = new ArrayList<PlayerStat>();
  756.         List<PlayerStat> herbalism = new ArrayList<PlayerStat>();
  757.         List<PlayerStat> excavation = new ArrayList<PlayerStat>();
  758.         List<PlayerStat> acrobatics = new ArrayList<PlayerStat>();
  759.         List<PlayerStat> repair = new ArrayList<PlayerStat>();
  760.         List<PlayerStat> swords = new ArrayList<PlayerStat>();
  761.         List<PlayerStat> axes = new ArrayList<PlayerStat>();
  762.         List<PlayerStat> archery = new ArrayList<PlayerStat>();
  763.         List<PlayerStat> unarmed = new ArrayList<PlayerStat>();
  764.         List<PlayerStat> taming = new ArrayList<PlayerStat>();
  765.         List<PlayerStat> fishing = new ArrayList<PlayerStat>();
  766.         List<PlayerStat> alchemy = new ArrayList<PlayerStat>();
  767.         List<PlayerStat> hunting = new ArrayList<PlayerStat>();
  768.  
  769.         BufferedReader in = null;
  770.         String playerName = null;
  771.         // Read from the FlatFile database and fill our arrays with information
  772.         synchronized (fileWritingLock) {
  773.             try {
  774.                 in = new BufferedReader(new FileReader(usersFilePath));
  775.                 String line;
  776.  
  777.                 while ((line = in.readLine()) != null) {
  778.                     String[] data = line.split(":");
  779.                     playerName = data[USERNAME];
  780.                     int powerLevel = 0;
  781.  
  782.                     Map<PrimarySkillType, Integer> skills = getSkillMapFromLine(data);
  783.  
  784.                     powerLevel += putStat(acrobatics, playerName, skills.get(PrimarySkillType.ACROBATICS));
  785.                     powerLevel += putStat(alchemy, playerName, skills.get(PrimarySkillType.ALCHEMY));
  786.                     powerLevel += putStat(archery, playerName, skills.get(PrimarySkillType.ARCHERY));
  787.                     powerLevel += putStat(axes, playerName, skills.get(PrimarySkillType.AXES));
  788.                     powerLevel += putStat(excavation, playerName, skills.get(PrimarySkillType.EXCAVATION));
  789.                     powerLevel += putStat(fishing, playerName, skills.get(PrimarySkillType.FISHING));
  790.                     powerLevel += putStat(herbalism, playerName, skills.get(PrimarySkillType.HERBALISM));
  791.                     powerLevel += putStat(hunting, playerName, skills.get(PrimarySkillType.HUNTING));
  792.                     powerLevel += putStat(mining, playerName, skills.get(PrimarySkillType.MINING));
  793.                     powerLevel += putStat(repair, playerName, skills.get(PrimarySkillType.REPAIR));
  794.                     powerLevel += putStat(swords, playerName, skills.get(PrimarySkillType.SWORDS));
  795.                     powerLevel += putStat(taming, playerName, skills.get(PrimarySkillType.TAMING));
  796.                     powerLevel += putStat(unarmed, playerName, skills.get(PrimarySkillType.UNARMED));
  797.                     powerLevel += putStat(woodcutting, playerName, skills.get(PrimarySkillType.WOODCUTTING));
  798.  
  799.                     putStat(powerLevels, playerName, powerLevel);
  800.                 }
  801.             }
  802.             catch (Exception e) {
  803.                 mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " during user " + playerName + " (Are you sure you formatted it correctly?) " + e.toString());
  804.             }
  805.             finally {
  806.                 if (in != null) {
  807.                     try {
  808.                         in.close();
  809.                     }
  810.                     catch (IOException e) {
  811.                         // Ignore
  812.                     }
  813.                 }
  814.             }
  815.         }
  816.  
  817.         SkillComparator c = new SkillComparator();
  818.  
  819.         Collections.sort(mining, c);
  820.         Collections.sort(woodcutting, c);
  821.         Collections.sort(repair, c);
  822.         Collections.sort(unarmed, c);
  823.         Collections.sort(herbalism, c);
  824.         Collections.sort(excavation, c);
  825.         Collections.sort(archery, c);
  826.         Collections.sort(swords, c);
  827.         Collections.sort(axes, c);
  828.         Collections.sort(acrobatics, c);
  829.         Collections.sort(taming, c);
  830.         Collections.sort(fishing, c);
  831.         Collections.sort(alchemy, c);
  832.         Collections.sort(hunting, c);
  833.         Collections.sort(powerLevels, c);
  834.  
  835.         playerStatHash.put(PrimarySkillType.MINING, mining);
  836.         playerStatHash.put(PrimarySkillType.WOODCUTTING, woodcutting);
  837.         playerStatHash.put(PrimarySkillType.REPAIR, repair);
  838.         playerStatHash.put(PrimarySkillType.UNARMED, unarmed);
  839.         playerStatHash.put(PrimarySkillType.HERBALISM, herbalism);
  840.         playerStatHash.put(PrimarySkillType.EXCAVATION, excavation);
  841.         playerStatHash.put(PrimarySkillType.ARCHERY, archery);
  842.         playerStatHash.put(PrimarySkillType.SWORDS, swords);
  843.         playerStatHash.put(PrimarySkillType.AXES, axes);
  844.         playerStatHash.put(PrimarySkillType.ACROBATICS, acrobatics);
  845.         playerStatHash.put(PrimarySkillType.TAMING, taming);
  846.         playerStatHash.put(PrimarySkillType.FISHING, fishing);
  847.         playerStatHash.put(PrimarySkillType.ALCHEMY, alchemy);
  848.         playerStatHash.put(PrimarySkillType.HUNTING, hunting);
  849.     }
  850.  
  851.     /**
  852.      * Checks that the file is present and valid
  853.      */
  854.     private void checkStructure() {
  855.         if (usersFile.exists()) {
  856.             BufferedReader in = null;
  857.             FileWriter out = null;
  858.             String usersFilePath = mcMMO.getUsersFilePath();
  859.  
  860.             synchronized (fileWritingLock) {
  861.                 try {
  862.                     in = new BufferedReader(new FileReader(usersFilePath));
  863.                     StringBuilder writer = new StringBuilder();
  864.                     String line;
  865.                     HashSet<String> usernames = new HashSet<String>();
  866.                     HashSet<String> players = new HashSet<String>();
  867.  
  868.                     while ((line = in.readLine()) != null) {
  869.                         // Remove empty lines from the file
  870.                         if (line.isEmpty()) {
  871.                             continue;
  872.                         }
  873.  
  874.                         // Length checks depend on last character being ':'
  875.                         if (line.charAt(line.length() - 1) != ':') {
  876.                             line = line.concat(":");
  877.                         }
  878.                         boolean updated = false;
  879.                         String[] character = line.split(":");
  880.  
  881.  
  882.  
  883.                         // Prevent the same username from being present multiple times
  884.                         if (!usernames.add(character[USERNAME])) {
  885.                             character[USERNAME] = "_INVALID_OLD_USERNAME_'";
  886.                             updated = true;
  887.                             if (character.length < UUID_INDEX + 1 || character[UUID_INDEX].equals("NULL")) {
  888.                                 continue;
  889.                             }
  890.                         }
  891.  
  892.                         // Prevent the same player from being present multiple times
  893.                         if (character.length >= 42 && (!character[UUID_INDEX].isEmpty() && !character[UUID_INDEX].equals("NULL") && !players.add(character[UUID_INDEX]))) {
  894.                             continue;
  895.                         }
  896.  
  897.                         if (character.length < 33) {
  898.                             // Before Version 1.0 - Drop
  899.                             mcMMO.p.getLogger().warning("Dropping malformed or before version 1.0 line from database - " + line);
  900.                             continue;
  901.                         }
  902.  
  903.                         String oldVersion = null;
  904.  
  905.                         if (character.length > 33 && !character[33].isEmpty()) {
  906.                             // Removal of Spout Support
  907.                             // Version 1.4.07-dev2
  908.                             // commit 7bac0e2ca5143bce84dc160617fed97f0b1cb968
  909.                             character[33] = "";
  910.                             if (oldVersion == null) {
  911.                                 oldVersion = "1.4.07";
  912.                             }
  913.                             updated = true;
  914.                         }
  915.  
  916.                         if (Config.getInstance().getTruncateSkills()) {
  917.                             for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
  918.                                 int index = getSkillIndex(skill);
  919.                                 if (index >= character.length) {
  920.                                     continue;
  921.                                 }
  922.                                 int cap = Config.getInstance().getLevelCap(skill);
  923.                                 if (Integer.valueOf(character[index]) > cap) {
  924.                                     mcMMO.p.getLogger().warning("Truncating " + skill.getName() + " to configured max level for player " + character[USERNAME]);
  925.                                     character[index] = cap + "";
  926.                                     updated = true;
  927.                                 }
  928.                             }
  929.                         }
  930.  
  931.                         // If they're valid, rewrite them to the file.
  932.                         if (!updated && character.length == 46) {
  933.                             writer.append(line).append("\r\n");
  934.                             continue;
  935.                         }
  936.  
  937.                         if (character.length <= 33) {
  938.                             // Introduction of HUDType
  939.                             // Version 1.1.06
  940.                             // commit 78f79213cdd7190cd11ae54526f3b4ea42078e8a
  941.                             character = Arrays.copyOf(character, character.length + 1);
  942.                             character[character.length - 1] = "";
  943.                             oldVersion = "1.1.06";
  944.                         }
  945.  
  946.                         if (character.length <= 35) {
  947.                             // Introduction of Fishing
  948.                             // Version 1.2.00
  949.                             // commit a814b57311bc7734661109f0e77fc8bab3a0bd29
  950.                             character = Arrays.copyOf(character, character.length + 2);
  951.                             character[character.length - 1] = "0";
  952.                             character[character.length - 2] = "0";
  953.                             if (oldVersion == null) {
  954.                                 oldVersion = "1.2.00";
  955.                             }
  956.                         }
  957.                         if (character.length <= 36) {
  958.                             // Introduction of Blast Mining cooldowns
  959.                             // Version 1.3.00-dev
  960.                             // commit fadbaf429d6b4764b8f1ad0efaa524a090e82ef5
  961.                             character = Arrays.copyOf(character, character.length + 1);
  962.                             character[character.length - 1] = "0";
  963.                             if (oldVersion == null) {
  964.                                 oldVersion = "1.3.00";
  965.                             }
  966.                         }
  967.                         if (character.length <= 37) {
  968.                             // Making old-purge work with flatfile
  969.                             // Version 1.4.00-dev
  970.                             // commmit 3f6c07ba6aaf44e388cc3b882cac3d8f51d0ac28
  971.                             // XXX Cannot create an OfflinePlayer at startup, use 0 and fix in purge
  972.                             character = Arrays.copyOf(character, character.length + 1);
  973.                             character[character.length - 1] = "0";
  974.                             if (oldVersion == null) {
  975.                                 oldVersion = "1.4.00";
  976.                             }
  977.                         }
  978.                         if (character.length <= 38) {
  979.                             // Addition of mob healthbars
  980.                             // Version 1.4.06
  981.                             // commit da29185b7dc7e0d992754bba555576d48fa08aa6
  982.                             character = Arrays.copyOf(character, character.length + 1);
  983.                             character[character.length - 1] = Config.getInstance().getMobHealthbarDefault().toString();
  984.                             if (oldVersion == null) {
  985.                                 oldVersion = "1.4.06";
  986.                             }
  987.                         }
  988.                         if (character.length <= 39) {
  989.                             // Addition of Alchemy
  990.                             // Version 1.4.08
  991.                             character = Arrays.copyOf(character, character.length + 2);
  992.                             character[character.length - 1] = "0";
  993.                             character[character.length - 2] = "0";
  994.                             if (oldVersion == null) {
  995.                                 oldVersion = "1.4.08";
  996.                             }
  997.                         }
  998.                         if (character.length <= 41) {
  999.                             // Addition of UUIDs
  1000.                             // Version 1.5.01
  1001.                             // Add a value because otherwise it gets removed
  1002.                             character = Arrays.copyOf(character, character.length + 1);
  1003.                             character[character.length - 1] = "NULL";
  1004.                             if (oldVersion == null) {
  1005.                                 oldVersion = "1.5.01";
  1006.                             }
  1007.                         }
  1008.                         if (character.length <= 42) {
  1009.                             // Addition of scoreboard tips auto disable
  1010.                             // Version 1.5.02
  1011.                             character = Arrays.copyOf(character, character.length + 1);
  1012.                             character[character.length - 1] = "0";
  1013.                             if (oldVersion == null) {
  1014.                                 oldVersion = "1.5.02";
  1015.                             }
  1016.                         }
  1017.                         Bukkit.getLogger().info(Integer.toString(character.length));
  1018.                         if (character.length <= 44) {
  1019.                             // Addition of Hunting
  1020.                             character = Arrays.copyOf(character, character.length + 2);
  1021.                             character[character.length - 1] = "0";
  1022.                             character[character.length - 2] = "0";
  1023.  
  1024.                             if (oldVersion == null) {
  1025.                                 oldVersion = "2.1.106M";
  1026.                             }
  1027.  
  1028.                             Bukkit.getLogger().info(Integer.toString(character.length));
  1029.  
  1030.                             for (int index = 0; index < 46; index++) {
  1031.                                 Bukkit.getLogger().info("Index: " + index + ", String: " + character[index]);
  1032.                             }
  1033.                         }
  1034.  
  1035.                         boolean corrupted = false;
  1036.  
  1037.                         for (int i = 0; i < character.length; i++) {
  1038.                             if (character[i].isEmpty() && !(i == 2 || i == 3 || i == 23 || i == 33 || i == 41)) {
  1039.                                 corrupted = true;
  1040.                                 if (i == 37) {
  1041.                                     character[i] = String.valueOf(System.currentTimeMillis() / Misc.TIME_CONVERSION_FACTOR);
  1042.                                 }
  1043.                                 else if (i == 38) {
  1044.                                     character[i] = Config.getInstance().getMobHealthbarDefault().toString();
  1045.                                 }
  1046.                                 else {
  1047.                                     character[i] = "0";
  1048.                                 }
  1049.                             }
  1050.  
  1051.                             if (StringUtils.isInt(character[i]) && i == 38) {
  1052.                                 corrupted = true;
  1053.                                 character[i] = Config.getInstance().getMobHealthbarDefault().toString();
  1054.                             }
  1055.  
  1056.                             if (!StringUtils.isInt(character[i]) && !(i == 0 || i == 2 || i == 3 || i == 23 || i == 33 || i == 38 || i == 41)) {
  1057.                                 corrupted = true;
  1058.                                 character[i] = "0";
  1059.                             }
  1060.                         }
  1061.  
  1062.                         if (corrupted) {
  1063.                             mcMMO.p.debug("Updating corrupted database line for player " + character[USERNAME]);
  1064.                         }
  1065.  
  1066.                         if (oldVersion != null) {
  1067.                             mcMMO.p.debug("Updating database line from before version " + oldVersion + " for player " + character[USERNAME]);
  1068.                         }
  1069.  
  1070.                         updated |= corrupted;
  1071.                         updated |= oldVersion != null;
  1072.  
  1073.                         if (Config.getInstance().getTruncateSkills()) {
  1074.                             Map<PrimarySkillType, Integer> skills = getSkillMapFromLine(character);
  1075.                             for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
  1076.                                 int cap = Config.getInstance().getLevelCap(skill);
  1077.                                 if (skills.get(skill) > cap) {
  1078.                                     updated = true;
  1079.                                 }
  1080.                             }
  1081.                         }
  1082.  
  1083.                         if (updated) {
  1084.                             line = new StringBuilder(org.apache.commons.lang.StringUtils.join(character, ":")).append(":").toString();
  1085.                         }
  1086.  
  1087.                         writer.append(line).append("\r\n");
  1088.                     }
  1089.  
  1090.                     // Write the new file
  1091.                     out = new FileWriter(usersFilePath);
  1092.                     out.write(writer.toString());
  1093.                 }
  1094.                 catch (IOException e) {
  1095.                     mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
  1096.                 }
  1097.                 finally {
  1098.                     if (in != null) {
  1099.                         try {
  1100.                             in.close();
  1101.                         }
  1102.                         catch (IOException e) {
  1103.                             // Ignore
  1104.                         }
  1105.                     }
  1106.                     if (out != null) {
  1107.                         try {
  1108.                             out.close();
  1109.                         }
  1110.                         catch (IOException e) {
  1111.                             // Ignore
  1112.                         }
  1113.                     }
  1114.                 }
  1115.             }
  1116.  
  1117.             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_FISHING);
  1118.             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_BLAST_MINING_COOLDOWN);
  1119.             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_SQL_INDEXES);
  1120.             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_MOB_HEALTHBARS);
  1121.             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.DROP_SQL_PARTY_NAMES);
  1122.             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.DROP_SPOUT);
  1123.             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_ALCHEMY);
  1124.             mcMMO.getUpgradeManager().setUpgradeCompleted(UpgradeType.ADD_HUNTER);
  1125.             return;
  1126.         }
  1127.  
  1128.         usersFile.getParentFile().mkdir();
  1129.  
  1130.         try {
  1131.             mcMMO.p.debug("Creating mcmmo.users file...");
  1132.             new File(mcMMO.getUsersFilePath()).createNewFile();
  1133.         }
  1134.         catch (IOException e) {
  1135.             e.printStackTrace();
  1136.         }
  1137.     }
  1138.  
  1139.     private Integer getPlayerRank(String playerName, List<PlayerStat> statsList) {
  1140.         if (statsList == null) {
  1141.             return null;
  1142.         }
  1143.  
  1144.         int currentPos = 1;
  1145.  
  1146.         for (PlayerStat stat : statsList) {
  1147.             if (stat.name.equalsIgnoreCase(playerName)) {
  1148.                 return currentPos;
  1149.             }
  1150.  
  1151.             currentPos++;
  1152.         }
  1153.  
  1154.         return null;
  1155.     }
  1156.  
  1157.     private int putStat(List<PlayerStat> statList, String playerName, int statValue) {
  1158.         statList.add(new PlayerStat(playerName, statValue));
  1159.         return statValue;
  1160.     }
  1161.  
  1162.     private class SkillComparator implements Comparator<PlayerStat> {
  1163.         @Override
  1164.         public int compare(PlayerStat o1, PlayerStat o2) {
  1165.             return (o2.statVal - o1.statVal);
  1166.         }
  1167.     }
  1168.  
  1169.     private PlayerProfile loadFromLine(String[] character) {
  1170.         Map<PrimarySkillType, Integer>   skills     = getSkillMapFromLine(character);      // Skill levels
  1171.         Map<PrimarySkillType, Float>     skillsXp   = new EnumMap<PrimarySkillType, Float>(PrimarySkillType.class);     // Skill & XP
  1172.         Map<SuperAbilityType, Integer> skillsDATS = new EnumMap<SuperAbilityType, Integer>(SuperAbilityType.class); // Ability & Cooldown
  1173.         Map<UniqueDataType, Integer> uniquePlayerDataMap = new EnumMap<UniqueDataType, Integer>(UniqueDataType.class);
  1174.         MobHealthbarType mobHealthbarType;
  1175.         int scoreboardTipsShown;
  1176.  
  1177.         // TODO on updates, put new values in a try{} ?
  1178.  
  1179.         skillsXp.put(PrimarySkillType.TAMING, (float) Integer.valueOf(character[EXP_TAMING]));
  1180.         skillsXp.put(PrimarySkillType.MINING, (float) Integer.valueOf(character[EXP_MINING]));
  1181.         skillsXp.put(PrimarySkillType.REPAIR, (float) Integer.valueOf(character[EXP_REPAIR]));
  1182.         skillsXp.put(PrimarySkillType.WOODCUTTING, (float) Integer.valueOf(character[EXP_WOODCUTTING]));
  1183.         skillsXp.put(PrimarySkillType.UNARMED, (float) Integer.valueOf(character[EXP_UNARMED]));
  1184.         skillsXp.put(PrimarySkillType.HERBALISM, (float) Integer.valueOf(character[EXP_HERBALISM]));
  1185.         skillsXp.put(PrimarySkillType.EXCAVATION, (float) Integer.valueOf(character[EXP_EXCAVATION]));
  1186.         skillsXp.put(PrimarySkillType.ARCHERY, (float) Integer.valueOf(character[EXP_ARCHERY]));
  1187.         skillsXp.put(PrimarySkillType.SWORDS, (float) Integer.valueOf(character[EXP_SWORDS]));
  1188.         skillsXp.put(PrimarySkillType.AXES, (float) Integer.valueOf(character[EXP_AXES]));
  1189.         skillsXp.put(PrimarySkillType.ACROBATICS, (float) Integer.valueOf(character[EXP_ACROBATICS]));
  1190.         skillsXp.put(PrimarySkillType.FISHING, (float) Integer.valueOf(character[EXP_FISHING]));
  1191.         skillsXp.put(PrimarySkillType.ALCHEMY, (float) Integer.valueOf(character[EXP_ALCHEMY]));
  1192.         skillsXp.put(PrimarySkillType.HUNTING, (float) Integer.valueOf(character[EXP_HUNTING]));
  1193.  
  1194.         // Taming - Unused
  1195.         skillsDATS.put(SuperAbilityType.SUPER_BREAKER, Integer.valueOf(character[COOLDOWN_SUPER_BREAKER]));
  1196.         // Repair - Unused
  1197.         skillsDATS.put(SuperAbilityType.TREE_FELLER, Integer.valueOf(character[COOLDOWN_TREE_FELLER]));
  1198.         skillsDATS.put(SuperAbilityType.BERSERK, Integer.valueOf(character[COOLDOWN_BERSERK]));
  1199.         skillsDATS.put(SuperAbilityType.GREEN_TERRA, Integer.valueOf(character[COOLDOWN_GREEN_TERRA]));
  1200.         skillsDATS.put(SuperAbilityType.GIGA_DRILL_BREAKER, Integer.valueOf(character[COOLDOWN_GIGA_DRILL_BREAKER]));
  1201.         // Archery - Unused
  1202.         skillsDATS.put(SuperAbilityType.SERRATED_STRIKES, Integer.valueOf(character[COOLDOWN_SERRATED_STRIKES]));
  1203.         skillsDATS.put(SuperAbilityType.SKULL_SPLITTER, Integer.valueOf(character[COOLDOWN_SKULL_SPLITTER]));
  1204.         // Acrobatics - Unused
  1205.         skillsDATS.put(SuperAbilityType.BLAST_MINING, Integer.valueOf(character[COOLDOWN_BLAST_MINING]));
  1206.  
  1207.         try {
  1208.             mobHealthbarType = MobHealthbarType.valueOf(character[HEALTHBAR]);
  1209.         }
  1210.         catch (Exception e) {
  1211.             mobHealthbarType = Config.getInstance().getMobHealthbarDefault();
  1212.         }
  1213.  
  1214.         UUID uuid;
  1215.         try {
  1216.             uuid = UUID.fromString(character[UUID_INDEX]);
  1217.         }
  1218.         catch (Exception e) {
  1219.             uuid = null;
  1220.         }
  1221.  
  1222.         try {
  1223.             scoreboardTipsShown = Integer.valueOf(character[SCOREBOARD_TIPS]);
  1224.         }
  1225.         catch (Exception e) {
  1226.             scoreboardTipsShown = 0;
  1227.         }
  1228.  
  1229.         try {
  1230.             uniquePlayerDataMap.put(UniqueDataType.CHIMAERA_WING_DATS, Integer.valueOf(character[COOLDOWN_CHIMAERA_WING]));
  1231.         }
  1232.         catch (Exception e) {
  1233.             uniquePlayerDataMap.put(UniqueDataType.CHIMAERA_WING_DATS, 0);
  1234.         }
  1235.  
  1236.         return new PlayerProfile(character[USERNAME], uuid, skills, skillsXp, skillsDATS, mobHealthbarType, scoreboardTipsShown, uniquePlayerDataMap);
  1237.     }
  1238.  
  1239.     private Map<PrimarySkillType, Integer> getSkillMapFromLine(String[] character) {
  1240.         Map<PrimarySkillType, Integer> skills = new EnumMap<PrimarySkillType, Integer>(PrimarySkillType.class);   // Skill & Level
  1241.  
  1242.         skills.put(PrimarySkillType.TAMING, Integer.valueOf(character[SKILLS_TAMING]));
  1243.         skills.put(PrimarySkillType.MINING, Integer.valueOf(character[SKILLS_MINING]));
  1244.         skills.put(PrimarySkillType.REPAIR, Integer.valueOf(character[SKILLS_REPAIR]));
  1245.         skills.put(PrimarySkillType.WOODCUTTING, Integer.valueOf(character[SKILLS_WOODCUTTING]));
  1246.         skills.put(PrimarySkillType.UNARMED, Integer.valueOf(character[SKILLS_UNARMED]));
  1247.         skills.put(PrimarySkillType.HERBALISM, Integer.valueOf(character[SKILLS_HERBALISM]));
  1248.         skills.put(PrimarySkillType.EXCAVATION, Integer.valueOf(character[SKILLS_EXCAVATION]));
  1249.         skills.put(PrimarySkillType.ARCHERY, Integer.valueOf(character[SKILLS_ARCHERY]));
  1250.         skills.put(PrimarySkillType.SWORDS, Integer.valueOf(character[SKILLS_SWORDS]));
  1251.         skills.put(PrimarySkillType.AXES, Integer.valueOf(character[SKILLS_AXES]));
  1252.         skills.put(PrimarySkillType.ACROBATICS, Integer.valueOf(character[SKILLS_ACROBATICS]));
  1253.         skills.put(PrimarySkillType.FISHING, Integer.valueOf(character[SKILLS_FISHING]));
  1254.         skills.put(PrimarySkillType.ALCHEMY, Integer.valueOf(character[SKILLS_ALCHEMY]));
  1255.         skills.put(PrimarySkillType.HUNTING, Integer.valueOf(character[SKILLS_HUNTING]));
  1256.  
  1257.         return skills;
  1258.     }
  1259.  
  1260.     public DatabaseType getDatabaseType() {
  1261.         return DatabaseType.FLATFILE;
  1262.     }
  1263.  
  1264.     @Override
  1265.     public void onDisable() { }
  1266.  
  1267.     private int getSkillIndex(PrimarySkillType skill) {
  1268.         switch (skill) {
  1269.             case ACROBATICS:
  1270.                 return SKILLS_ACROBATICS;
  1271.             case ALCHEMY:
  1272.                 return SKILLS_ALCHEMY;
  1273.             case ARCHERY:
  1274.                 return SKILLS_ARCHERY;
  1275.             case AXES:
  1276.                 return SKILLS_AXES;
  1277.             case EXCAVATION:
  1278.                 return SKILLS_EXCAVATION;
  1279.             case FISHING:
  1280.                 return SKILLS_FISHING;
  1281.             case HERBALISM:
  1282.                 return SKILLS_HERBALISM;
  1283.             case MINING:
  1284.                 return SKILLS_MINING;
  1285.             case REPAIR:
  1286.                 return SKILLS_REPAIR;
  1287.             case SWORDS:
  1288.                 return SKILLS_SWORDS;
  1289.             case TAMING:
  1290.                 return SKILLS_TAMING;
  1291.             case UNARMED:
  1292.                 return SKILLS_UNARMED;
  1293.             case WOODCUTTING:
  1294.                 return SKILLS_WOODCUTTING;
  1295.             case HUNTING:
  1296.                 return SKILLS_HUNTING;
  1297.             default:
  1298.                 throw new RuntimeException("Primary Skills only");
  1299.            
  1300.         }
  1301.     }
  1302.    
  1303.     public static int USERNAME = 0;
  1304.     public static int SKILLS_MINING = 1;
  1305.     public static int EXP_MINING = 4;
  1306.     public static int SKILLS_WOODCUTTING = 5;
  1307.     public static int EXP_WOODCUTTING = 6;
  1308.     public static int SKILLS_REPAIR = 7;
  1309.     public static int SKILLS_UNARMED = 8;
  1310.     public static int SKILLS_HERBALISM = 9;
  1311.     public static int SKILLS_EXCAVATION = 10;
  1312.     public static int SKILLS_ARCHERY = 11;
  1313.     public static int SKILLS_SWORDS = 12;
  1314.     public static int SKILLS_AXES = 13;
  1315.     public static int SKILLS_ACROBATICS = 14;
  1316.     public static int EXP_REPAIR = 15;
  1317.     public static int EXP_UNARMED = 16;
  1318.     public static int EXP_HERBALISM = 17;
  1319.     public static int EXP_EXCAVATION = 18;
  1320.     public static int EXP_ARCHERY = 19;
  1321.     public static int EXP_SWORDS = 20;
  1322.     public static int EXP_AXES = 21;
  1323.     public static int EXP_ACROBATICS = 22;
  1324.     public static int SKILLS_TAMING = 24;
  1325.     public static int EXP_TAMING = 25;
  1326.     public static int COOLDOWN_BERSERK = 26;
  1327.     public static int COOLDOWN_GIGA_DRILL_BREAKER = 27;
  1328.     public static int COOLDOWN_TREE_FELLER = 28;
  1329.     public static int COOLDOWN_GREEN_TERRA = 29;
  1330.     public static int COOLDOWN_SERRATED_STRIKES = 30;
  1331.     public static int COOLDOWN_SKULL_SPLITTER = 31;
  1332.     public static int COOLDOWN_SUPER_BREAKER = 32;
  1333.     public static int SKILLS_FISHING = 34;
  1334.     public static int EXP_FISHING = 35;
  1335.     public static int COOLDOWN_BLAST_MINING = 36;
  1336.     public static int LAST_LOGIN = 37;
  1337.     public static int HEALTHBAR = 38;
  1338.     public static int SKILLS_ALCHEMY = 39;
  1339.     public static int EXP_ALCHEMY = 40;
  1340.     public static int UUID_INDEX = 41;
  1341.     public static int SCOREBOARD_TIPS = 42;
  1342.     public static int COOLDOWN_CHIMAERA_WING = 43;
  1343.     public static int SKILLS_HUNTING = 44;
  1344.     public static int EXP_HUNTING = 45;
  1345.  
  1346.     public void resetMobHealthSettings() {
  1347.         BufferedReader in = null;
  1348.         FileWriter out = null;
  1349.         String usersFilePath = mcMMO.getUsersFilePath();
  1350.  
  1351.         synchronized (fileWritingLock) {
  1352.             try {
  1353.                 in = new BufferedReader(new FileReader(usersFilePath));
  1354.                 StringBuilder writer = new StringBuilder();
  1355.                 String line;
  1356.  
  1357.                 while ((line = in.readLine()) != null) {
  1358.                     // Remove empty lines from the file
  1359.                     if (line.isEmpty()) {
  1360.                         continue;
  1361.                     }
  1362.                     String[] character = line.split(":");
  1363.                    
  1364.                     character[HEALTHBAR] = Config.getInstance().getMobHealthbarDefault().toString();
  1365.                    
  1366.                     line = new StringBuilder(org.apache.commons.lang.StringUtils.join(character, ":")).append(":").toString();
  1367.  
  1368.                     writer.append(line).append("\r\n");
  1369.                 }
  1370.  
  1371.                 // Write the new file
  1372.                 out = new FileWriter(usersFilePath);
  1373.                 out.write(writer.toString());
  1374.             }
  1375.             catch (IOException e) {
  1376.                 mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
  1377.             }
  1378.             finally {
  1379.                 if (in != null) {
  1380.                     try {
  1381.                         in.close();
  1382.                     }
  1383.                     catch (IOException e) {
  1384.                         // Ignore
  1385.                     }
  1386.                 }
  1387.                 if (out != null) {
  1388.                     try {
  1389.                         out.close();
  1390.                     }
  1391.                     catch (IOException e) {
  1392.                         // Ignore
  1393.                     }
  1394.                 }
  1395.             }
  1396.         }
  1397.     }
  1398. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top