// saves changes to player data. MUST be called after you're done making // changes, otherwise a reload will lose them @Override public synchronized void savePlayerData(String playerName, PlayerData playerData) { // never save data for the "administrative" account. an empty string for // claim owner indicates administrative account if (playerName.length() == 0) return; BufferedWriter outStream = null; try { // open the player's file File playerDataFile = new File(playerDataFolderPath + File.separator + playerName.toLowerCase()); playerDataFile.createNewFile(); outStream = new BufferedWriter(new FileWriter(playerDataFile)); // first line is last login timestamp if (playerData.lastLogin == null) playerData.lastLogin = new Date(); DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss"); outStream.write(dateFormat.format(playerData.lastLogin)); outStream.newLine(); // second line is accrued claim blocks outStream.write(String.valueOf(playerData.accruedClaimBlocks)); outStream.newLine(); // third line is bonus claim blocks outStream.write(String.valueOf(playerData.bonusClaimBlocks)); outStream.newLine(); // fourth line is a double-semicolon-delimited list of claims /*if (playerData.claims.size() > 0) { outStream.write(this.locationToString(playerData.claims.get(0).getLesserBoundaryCorner())); for (int i = 1; i < playerData.claims.size(); i++) { outStream.write(";;" + this.locationToString(playerData.claims.get(i).getLesserBoundaryCorner())); } } */ // write out wether the player's inventory needs to be cleared on join. outStream.newLine(); outStream.write(String.valueOf(playerData.ClearInventoryOnJoin)); outStream.newLine(); } // if any problem, log it catch (Exception e) { GriefPrevention.AddLogEntry( "GriefPrevention: Unexpected exception saving data for player \"" + playerName + "\": " + e.getMessage()); } try { // close the file if (outStream != null) { outStream.close(); } } catch (IOException exception) { } }
@Override synchronized PlayerData getPlayerDataFromStorage(String playerName) { // if the file exists when we check for the specific casing, use that file. // On Windows machines the FS will not be case sensitive, however, for *nix based machines // the file systems and the file I/O API are case sensitive. We save data lowercase now // however previous installations may have upper-cased filenames. Thus we will // look for the filename for the file that it would be named if we create the path // with a case-insensitive player name. File CaseInsensitive = new File(getPlayerDataFile(playerName)); File playerFile; playerFile = CaseInsensitive; PlayerData playerData = new PlayerData(); playerData.playerName = playerName; // if it doesn't exist as a file if (!playerFile.exists()) { // create a file with defaults, but only if the player has been // online before. Player playerobj = Bukkit.getPlayer(playerName); if (playerobj == null) { this.savePlayerData(playerName, playerData); } else if (playerobj.hasPlayedBefore() || playerobj.isOnline()) { this.savePlayerData(playerName, playerData); } } // otherwise, read the file else { BufferedReader inStream = null; try { inStream = new BufferedReader(new FileReader(playerFile.getAbsolutePath())); // first line is last login timestamp String lastLoginTimestampString = inStream.readLine(); // convert that to a date and store it DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss"); try { playerData.lastLogin = dateFormat.parse(lastLoginTimestampString); } catch (ParseException parseException) { GriefPrevention.AddLogEntry( "Unable to load last login for \"" + playerFile.getName() + "\"."); playerData.lastLogin = null; } // second line is accrued claim blocks String accruedBlocksString = inStream.readLine(); // convert that to a number and store it playerData.accruedClaimBlocks = Integer.parseInt(accruedBlocksString); // third line is any bonus claim blocks granted by // administrators String bonusBlocksString = inStream.readLine(); // convert that to a number and store it playerData.bonusClaimBlocks = Integer.parseInt(bonusBlocksString); // fourth line is a double-semicolon-delimited list of claims, // which is currently ignored try { inStream.readLine(); String playerinventoryclear = inStream.readLine(); playerData.ClearInventoryOnJoin = Boolean.parseBoolean(playerinventoryclear); } catch (Exception exx) { } // do nothing, seems like there was no value. Oh well. inStream.close(); } // if there's any problem with the file's content, log an error // message catch (Exception e) { GriefPrevention.AddLogEntry("Unable to load data for player \"" + playerName + "\": "); } try { if (inStream != null) inStream.close(); } catch (IOException exception) { } } return playerData; }