From c09907924c83f142005d1915501d6579a4b37bf7 Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Sun, 11 Oct 2020 16:08:02 -0500 Subject: [PATCH 1/4] Bankcaps interfering with taxes. Potential fix for #4364. --- .../bukkit/towny/tasks/DailyTimerTask.java | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java index 996927f589..9a1c38affb 100644 --- a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java +++ b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java @@ -343,10 +343,16 @@ protected void collectTownTaxes(Town town) throws EconomyException { resident.getAccount().payTo(cost, town, "Town Tax (Percentage)"); } else if (!resident.getAccount().payTo(town.getTaxes(), town, "Town Tax")) { - removedResidents.add(resident.getName()); - - // remove this resident from the town. - resident.removeTown(); + // Handle town bank caps not allowing a player to deposit the money, but not because the player could not pay. + if (town.getAccount().getHoldingBalance() + town.getTaxes() > town.getAccount().getBalanceCap()) { + double tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); + resident.getAccount().payTo(tax, town, "Town tax hitting bank cap."); + } else { + removedResidents.add(resident.getName()); + + // remove this resident from the town. + resident.removeTown(); + } } } } @@ -386,17 +392,23 @@ protected void collectTownTaxes(Town town) throws EconomyException { continue; if (!resident.getAccount().payTo(townBlock.getType().getTax(town), town, String.format("Plot Tax (%s)", townBlock.getType()))) { - if (!lostPlots.contains(resident.getName())) - lostPlots.add(resident.getName()); - - townBlock.setResident(null); - townBlock.setPlotPrice(-1); - - // Set the plot permissions to mirror the towns. - townBlock.setType(townBlock.getType()); - universe.getDataSource().saveResident(resident); - universe.getDataSource().saveTownBlock(townBlock); + if (town.getAccount().getHoldingBalance() + townBlock.getType().getTax(town) > town.getAccount().getBalanceCap()) { + double tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); + resident.getAccount().payTo(tax, town, "Town plottax hitting bank cap."); + } else { + if (!lostPlots.contains(resident.getName())) + lostPlots.add(resident.getName()); + + townBlock.setResident(null); + townBlock.setPlotPrice(-1); + + // Set the plot permissions to mirror the towns. + townBlock.setType(townBlock.getType()); + + universe.getDataSource().saveResident(resident); + universe.getDataSource().saveTownBlock(townBlock); + } } } } catch (NotRegisteredException ignored) { From f06b610a5aedf467668be08eb52ab05b3f9b5376 Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Mon, 12 Oct 2020 09:56:18 -0500 Subject: [PATCH 2/4] Bankcaps interfering with taxes. - Improves on last commit by also handling whether the player has enough to pay the lesser tax amount. --- .../bukkit/towny/tasks/DailyTimerTask.java | 71 +++++++++++-------- 1 file changed, 42 insertions(+), 29 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java index 9a1c38affb..76a687ff6f 100644 --- a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java +++ b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java @@ -320,6 +320,8 @@ protected void collectTownTaxes(Town town) throws EconomyException { while (residentItr.hasNext()) { resident = residentItr.next(); + boolean paid = true; + double tax = 0; /* * Only collect resident tax from this resident if it really * still exists. We are running in an Async thread so MUST @@ -335,26 +337,32 @@ protected void collectTownTaxes(Town town) throws EconomyException { } continue; } else if (town.isTaxPercentage()) { - double cost = resident.getAccount().getHoldingBalance() * town.getTaxes() / 100; + tax = resident.getAccount().getHoldingBalance() * town.getTaxes() / 100; // Make sure that the town percent tax doesn't remove above the // allotted amount of cash. - cost = Math.min(cost, town.getMaxPercentTaxAmount()); + tax = Math.min(tax, town.getMaxPercentTaxAmount()); - resident.getAccount().payTo(cost, town, "Town Tax (Percentage)"); + resident.getAccount().payTo(tax, town, "Town Tax (Percentage)"); } else if (!resident.getAccount().payTo(town.getTaxes(), town, "Town Tax")) { // Handle town bank caps not allowing a player to deposit the money, but not because the player could not pay. if (town.getAccount().getHoldingBalance() + town.getTaxes() > town.getAccount().getBalanceCap()) { - double tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); - resident.getAccount().payTo(tax, town, "Town tax hitting bank cap."); + tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); + if (resident.getAccount().canPayFromHoldings(tax)) + resident.getAccount().payTo(tax, town, "Town tax hitting bank cap."); + else + paid = false; } else { - removedResidents.add(resident.getName()); - - // remove this resident from the town. - resident.removeTown(); + paid = false; } } } + + if (!paid) { + removedResidents.add(resident.getName()); + // remove this resident from the town. + resident.removeTown(); + } } if (removedResidents != null) { if (removedResidents.size() == 1) @@ -373,6 +381,7 @@ protected void collectTownTaxes(Town town) throws EconomyException { TownBlock townBlock; while (townBlockItr.hasNext()) { + boolean paid = true; townBlock = townBlockItr.next(); if (!townBlock.hasResident()) @@ -386,34 +395,38 @@ protected void collectTownTaxes(Town town) throws EconomyException { * verify all objects. */ if (universe.getDataSource().hasResident(resident.getName())) { - if (resident.hasTown()) - if (resident.getTown() == townBlock.getTown()) - if (TownyPerms.getResidentPerms(resident).containsKey("towny.tax_exempt") || resident.isNPC()) - continue; + if (resident.hasTown() && resident.getTown() == townBlock.getTown()) + if (TownyPerms.getResidentPerms(resident).containsKey("towny.tax_exempt") || resident.isNPC()) + continue; + + double tax = townBlock.getType().getTax(town); - if (!resident.getAccount().payTo(townBlock.getType().getTax(town), town, String.format("Plot Tax (%s)", townBlock.getType()))) { + if (!resident.getAccount().payTo(tax, town, String.format("Plot Tax (%s)", townBlock.getType()))) { - if (town.getAccount().getHoldingBalance() + townBlock.getType().getTax(town) > town.getAccount().getBalanceCap()) { - double tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); - resident.getAccount().payTo(tax, town, "Town plottax hitting bank cap."); + if (town.getAccount().getHoldingBalance() + tax > town.getAccount().getBalanceCap()) { + tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); + if (resident.getAccount().canPayFromHoldings(tax)) + resident.getAccount().payTo(tax, town, "Town plottax hitting bank cap."); + else + paid = false; } else { - if (!lostPlots.contains(resident.getName())) - lostPlots.add(resident.getName()); - - townBlock.setResident(null); - townBlock.setPlotPrice(-1); - - // Set the plot permissions to mirror the towns. - townBlock.setType(townBlock.getType()); - - universe.getDataSource().saveResident(resident); - universe.getDataSource().saveTownBlock(townBlock); + paid = false; } } } + + if (!paid) { + if (!lostPlots.contains(resident.getName())) + lostPlots.add(resident.getName()); + + townBlock.setResident(null); + townBlock.setPlotPrice(-1); + // Set the plot permissions to mirror the towns. + townBlock.setType(townBlock.getType()); + universe.getDataSource().saveTownBlock(townBlock); + } } catch (NotRegisteredException ignored) { } - } if (lostPlots != null) { if (lostPlots.size() == 1) From 9a58c05d99fd197059f59cc7f42aea6cc43ac83a Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Mon, 12 Oct 2020 09:59:07 -0500 Subject: [PATCH 3/4] Bankcaps interfering with taxes. - Use town.getTaxes() only once now. --- .../palmergames/bukkit/towny/tasks/DailyTimerTask.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java index 76a687ff6f..f38f9a6267 100644 --- a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java +++ b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java @@ -321,7 +321,7 @@ protected void collectTownTaxes(Town town) throws EconomyException { resident = residentItr.next(); boolean paid = true; - double tax = 0; + double tax = town.getTaxes(); /* * Only collect resident tax from this resident if it really * still exists. We are running in an Async thread so MUST @@ -337,16 +337,16 @@ protected void collectTownTaxes(Town town) throws EconomyException { } continue; } else if (town.isTaxPercentage()) { - tax = resident.getAccount().getHoldingBalance() * town.getTaxes() / 100; + tax = resident.getAccount().getHoldingBalance() * tax / 100; // Make sure that the town percent tax doesn't remove above the // allotted amount of cash. tax = Math.min(tax, town.getMaxPercentTaxAmount()); resident.getAccount().payTo(tax, town, "Town Tax (Percentage)"); - } else if (!resident.getAccount().payTo(town.getTaxes(), town, "Town Tax")) { + } else if (!resident.getAccount().payTo(tax, town, "Town Tax")) { // Handle town bank caps not allowing a player to deposit the money, but not because the player could not pay. - if (town.getAccount().getHoldingBalance() + town.getTaxes() > town.getAccount().getBalanceCap()) { + if (town.getAccount().getHoldingBalance() + tax > town.getAccount().getBalanceCap()) { tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); if (resident.getAccount().canPayFromHoldings(tax)) resident.getAccount().payTo(tax, town, "Town tax hitting bank cap."); From cf7f39c317bb4d40912107aa6403a6b1212519ba Mon Sep 17 00:00:00 2001 From: Llm Dl Date: Thu, 22 Oct 2020 21:03:34 -0500 Subject: [PATCH 4/4] Fix paying twice because the logic of whether someone can pay a tax has no knowledge of what the bank cap is. --- .../bukkit/towny/tasks/DailyTimerTask.java | 73 +++++++++---------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java index f38f9a6267..caf867da56 100644 --- a/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java +++ b/src/com/palmergames/bukkit/towny/tasks/DailyTimerTask.java @@ -320,7 +320,6 @@ protected void collectTownTaxes(Town town) throws EconomyException { while (residentItr.hasNext()) { resident = residentItr.next(); - boolean paid = true; double tax = town.getTaxes(); /* * Only collect resident tax from this resident if it really @@ -342,27 +341,31 @@ protected void collectTownTaxes(Town town) throws EconomyException { // Make sure that the town percent tax doesn't remove above the // allotted amount of cash. tax = Math.min(tax, town.getMaxPercentTaxAmount()); + + // Handle if the bank cannot be paid because of the cap. Since it is a % + // they will be able to pay but it might be more than the bank can accept, + // so we reduce it to the amount that the bank can accept, even if it + // becomes 0. + if (tax + town.getAccount().getHoldingBalance() > TownySettings.getTownBankCap()) + tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); resident.getAccount().payTo(tax, town, "Town Tax (Percentage)"); - } else if (!resident.getAccount().payTo(tax, town, "Town Tax")) { - // Handle town bank caps not allowing a player to deposit the money, but not because the player could not pay. - if (town.getAccount().getHoldingBalance() + tax > town.getAccount().getBalanceCap()) { + } else { + // Check if the bank could take the money, reduce it to 0 if required so that + // players do not get kicked in a situation they could be paying but cannot because + // of the bank cap. + if (tax + town.getAccount().getHoldingBalance() > TownySettings.getTownBankCap()) tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); - if (resident.getAccount().canPayFromHoldings(tax)) - resident.getAccount().payTo(tax, town, "Town tax hitting bank cap."); - else - paid = false; - } else { - paid = false; + + if (resident.getAccount().canPayFromHoldings(tax)) + resident.getAccount().payTo(tax, town, "Town tax (FlatRate)"); + else { + removedResidents.add(resident.getName()); + // remove this resident from the town. + resident.removeTown(); } } } - - if (!paid) { - removedResidents.add(resident.getName()); - // remove this resident from the town. - resident.removeTown(); - } } if (removedResidents != null) { if (removedResidents.size() == 1) @@ -381,7 +384,6 @@ protected void collectTownTaxes(Town town) throws EconomyException { TownBlock townBlock; while (townBlockItr.hasNext()) { - boolean paid = true; townBlock = townBlockItr.next(); if (!townBlock.hasResident()) @@ -400,33 +402,26 @@ protected void collectTownTaxes(Town town) throws EconomyException { continue; double tax = townBlock.getType().getTax(town); - + + // If the tax would put the town over the bank cap we reduce what will be + // paid by the plot owner to what will be allowed. + if (tax + town.getAccount().getHoldingBalance() > TownySettings.getTownBankCap()) + tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); + if (!resident.getAccount().payTo(tax, town, String.format("Plot Tax (%s)", townBlock.getType()))) { - - if (town.getAccount().getHoldingBalance() + tax > town.getAccount().getBalanceCap()) { - tax = town.getAccount().getBalanceCap() - town.getAccount().getHoldingBalance(); - if (resident.getAccount().canPayFromHoldings(tax)) - resident.getAccount().payTo(tax, town, "Town plottax hitting bank cap."); - else - paid = false; - } else { - paid = false; - } + if (!lostPlots.contains(resident.getName())) + lostPlots.add(resident.getName()); + + townBlock.setResident(null); + townBlock.setPlotPrice(-1); + // Set the plot permissions to mirror the towns. + townBlock.setType(townBlock.getType()); + universe.getDataSource().saveTownBlock(townBlock); } } - - if (!paid) { - if (!lostPlots.contains(resident.getName())) - lostPlots.add(resident.getName()); - - townBlock.setResident(null); - townBlock.setPlotPrice(-1); - // Set the plot permissions to mirror the towns. - townBlock.setType(townBlock.getType()); - universe.getDataSource().saveTownBlock(townBlock); - } } catch (NotRegisteredException ignored) { } + } if (lostPlots != null) { if (lostPlots.size() == 1)