// 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 public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { // TODO Auto-generated method stub // buyclaimblocks Player player = (sender instanceof Player) ? (Player) sender : null; if (player == null) return false; GriefPrevention inst = GriefPrevention.instance; if (command.getName().equalsIgnoreCase("buyclaimblocks") && player != null) { // if economy is disabled, don't do anything if (GriefPrevention.economy == null) { GriefPrevention.sendMessage(player, TextMode.Err, Messages.BuySellNotConfigured); return true; } if (!player.hasPermission("griefprevention.buysellclaimblocks")) { GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoPermissionForCommand); return true; } // if purchase disabled, send error message if (GriefPrevention.instance.config_economy_claimBlocksPurchaseCost == 0) { GriefPrevention.sendMessage(player, TextMode.Err, Messages.OnlySellBlocks); return true; } // if no parameter, just tell player cost per block and balance if (args.length != 1) { GriefPrevention.sendMessage( player, TextMode.Info, Messages.BlockPurchaseCost, String.valueOf(GriefPrevention.instance.config_economy_claimBlocksPurchaseCost), String.valueOf(GriefPrevention.economy.getBalance(player.getName()))); return false; } else { // determine max purchasable blocks PlayerData playerData = inst.dataStore.getPlayerData(player.getName()); int maxPurchasable = GriefPrevention.instance.config_claims_maxAccruedBlocks - playerData.accruedClaimBlocks; // if the player is at his max, tell him so if (maxPurchasable <= 0) { GriefPrevention.sendMessage(player, TextMode.Err, Messages.ClaimBlockLimit); return true; } // try to parse number of blocks int blockCount; try { blockCount = Integer.parseInt(args[0]); } catch (NumberFormatException numberFormatException) { return false; // causes usage to be displayed } if (blockCount <= 0) { return false; } // correct block count to max allowed if (blockCount > maxPurchasable) { blockCount = maxPurchasable; } // if the player can't afford his purchase, send error // message double balance = inst.economy.getBalance(player.getName()); double totalCost = blockCount * GriefPrevention.instance.config_economy_claimBlocksPurchaseCost; if (totalCost > balance) { GriefPrevention.sendMessage( player, TextMode.Err, Messages.InsufficientFunds, String.valueOf(totalCost), String.valueOf(balance)); } // otherwise carry out transaction else { // withdraw cost inst.economy.withdrawPlayer(player.getName(), totalCost); // add blocks playerData.accruedClaimBlocks += blockCount; inst.dataStore.savePlayerData(player.getName(), playerData); // inform player GriefPrevention.sendMessage( player, TextMode.Success, Messages.PurchaseConfirmation, String.valueOf(totalCost), String.valueOf(playerData.getRemainingClaimBlocks())); } return true; } } // sellclaimblocks <amount> else if (command.getName().equalsIgnoreCase("sellclaimblocks") && player != null) { // if economy is disabled, don't do anything if (GriefPrevention.economy == null) { GriefPrevention.sendMessage(player, TextMode.Err, Messages.BuySellNotConfigured); return true; } if (!player.hasPermission("griefprevention.buysellclaimblocks")) { GriefPrevention.sendMessage(player, TextMode.Err, Messages.NoPermissionForCommand); return true; } // if disabled, error message if (GriefPrevention.instance.config_economy_claimBlocksSellValue == 0) { GriefPrevention.sendMessage(player, TextMode.Err, Messages.OnlyPurchaseBlocks); return true; } // load player data PlayerData playerData = inst.dataStore.getPlayerData(player.getName()); int availableBlocks = playerData.getRemainingClaimBlocks(); // if no amount provided, just tell player value per block sold, // and how many he can sell if (args.length != 1) { GriefPrevention.sendMessage( player, TextMode.Info, Messages.BlockSaleValue, String.valueOf(GriefPrevention.instance.config_economy_claimBlocksSellValue), String.valueOf(availableBlocks)); return false; } // parse number of blocks int blockCount; try { blockCount = Integer.parseInt(args[0]); } catch (NumberFormatException numberFormatException) { return false; // causes usage to be displayed } if (blockCount <= 0) { return false; } // if he doesn't have enough blocks, tell him so if (blockCount > availableBlocks) { GriefPrevention.sendMessage(player, TextMode.Err, Messages.NotEnoughBlocksForSale); } // otherwise carry out the transaction else { // compute value and deposit it double totalValue = blockCount * GriefPrevention.instance.config_economy_claimBlocksSellValue; inst.economy.depositPlayer(player.getName(), totalValue); // subtract blocks playerData.accruedClaimBlocks -= blockCount; inst.dataStore.savePlayerData(player.getName(), playerData); // inform player GriefPrevention.sendMessage( player, TextMode.Success, Messages.BlockSaleConfirmation, String.valueOf(totalValue), String.valueOf(playerData.getRemainingClaimBlocks())); } return true; } return false; }
@Override public CommandResult execute(CommandSource src, CommandContext ctx) { Player player; try { player = GriefPrevention.checkPlayer(src); } catch (CommandException e) { src.sendMessage(e.getText()); return CommandResult.success(); } // which claim is being abandoned? PlayerData playerData = GriefPrevention.instance.dataStore.getOrCreatePlayerData( player.getWorld(), player.getUniqueId()); Claim claim = GriefPrevention.instance.dataStore.getClaimAtPlayer(playerData, player.getLocation(), true); UUID ownerId = claim.ownerID; if (claim.parent != null) { ownerId = claim.parent.ownerID; } if (claim.isWildernessClaim()) { GriefPrevention.sendMessage(player, TextMode.Instr, Messages.AbandonClaimMissing); return CommandResult.success(); } else if (claim.allowEdit(player) != null || (!claim.isAdminClaim() && !player.getUniqueId().equals(ownerId))) { // verify ownership GriefPrevention.sendMessage(player, TextMode.Err, Messages.NotYourClaim); return CommandResult.success(); } // warn if has children and we're not explicitly deleting a top level claim else if (claim.children.size() > 0 && !deleteTopLevelClaim) { GriefPrevention.sendMessage(player, TextMode.Instr, Messages.DeleteTopLevelClaim); return CommandResult.empty(); } else { // delete it claim.removeSurfaceFluids(null); // remove all context permissions player.getSubjectData().clearPermissions(ImmutableSet.of(claim.getContext())); GriefPrevention.GLOBAL_SUBJECT .getSubjectData() .clearPermissions(ImmutableSet.of(claim.getContext())); GriefPrevention.instance.dataStore.deleteClaim(claim, true); // if in a creative mode world, restore the claim area if (GriefPrevention.instance.claimModeIsActive( claim.getLesserBoundaryCorner().getExtent().getProperties(), ClaimsMode.Creative)) { GriefPrevention.addLogEntry( player.getName() + " abandoned a claim @ " + GriefPrevention.getfriendlyLocationString(claim.getLesserBoundaryCorner())); GriefPrevention.sendMessage(player, TextMode.Warn, Messages.UnclaimCleanupWarning); GriefPrevention.instance.restoreClaim(claim, 20L * 60 * 2); } // this prevents blocks being gained without spending adjust claim blocks when abandoning a // top level claim if (!claim.isSubdivision() && !claim.isAdminClaim()) { int newAccruedClaimCount = playerData.getAccruedClaimBlocks() - ((int) Math.ceil(claim.getArea() * (1 - playerData.optionAbandonReturnRatio))); playerData.setAccruedClaimBlocks(newAccruedClaimCount); } // tell the player how many claim blocks he has left int remainingBlocks = playerData.getRemainingClaimBlocks(); GriefPrevention.sendMessage( player, TextMode.Success, Messages.AbandonSuccess, String.valueOf(remainingBlocks)); // revert any current visualization playerData.revertActiveVisual(player); playerData.warnedAboutMajorDeletion = false; } return CommandResult.success(); }
@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; }
@Override public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { // adjustbonusclaimblocks <player> <amount> or [<permission>] amount // requires exactly two parameters, the other player or group's name and // the adjustment if (args.length != 2) return false; Player player = (sender instanceof Player) ? (Player) sender : null; GriefPrevention inst = GriefPrevention.instance; // parse the adjustment amount int adjustment; try { adjustment = Integer.parseInt(args[1]); } catch (NumberFormatException numberFormatException) { return false; // causes usage to be displayed } // if granting blocks to all players with a specific permission if (args[0].startsWith("[") && args[0].endsWith("]")) { String permissionIdentifier = args[0].substring(1, args[0].length() - 1); int newTotal = inst.dataStore.adjustGroupBonusBlocks(permissionIdentifier, adjustment); if (player != null) GriefPrevention.sendMessage( player, TextMode.Success, Messages.AdjustGroupBlocksSuccess, permissionIdentifier, String.valueOf(adjustment), String.valueOf(newTotal)); if (player != null) GriefPrevention.AddLogEntry( player.getName() + " adjusted " + permissionIdentifier + "'s bonus claim blocks by " + adjustment + "."); return true; } // otherwise, find the specified player OfflinePlayer targetPlayer = inst.resolvePlayer(args[0]); if (targetPlayer == null) { if (player != null) GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound); return true; } // give blocks to player PlayerData playerData = inst.dataStore.getPlayerData(targetPlayer.getName()); playerData.bonusClaimBlocks += adjustment; inst.dataStore.savePlayerData(targetPlayer.getName(), playerData); GriefPrevention.sendMessage( player, TextMode.Success, Messages.AdjustBlocksSuccess, targetPlayer.getName(), String.valueOf(adjustment), String.valueOf(playerData.bonusClaimBlocks)); if (player != null) GriefPrevention.AddLogEntry( player.getName() + " adjusted " + targetPlayer.getName() + "'s bonus claim blocks by " + adjustment + "."); return true; }