/* * This file is part of EconomyLite, licensed under the MIT License (MIT). See the LICENSE file at the root of this project for more information. */ package io.github.flibio.economylite.modules.loan; import org.spongepowered.api.text.serializer.TextSerializers; import org.spongepowered.api.util.Tristate; import org.spongepowered.api.service.permission.SubjectData; import io.github.flibio.economylite.modules.loan.event.LoanBalanceChangeEvent; import io.github.flibio.economylite.EconomyLite; import io.github.flibio.utils.message.MessageStorage; import org.spongepowered.api.Sponge; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.economy.EconomyTransactionEvent; import org.spongepowered.api.service.economy.Currency; import org.spongepowered.api.service.economy.transaction.ResultType; import org.spongepowered.api.text.Text; import java.math.BigDecimal; import java.util.Locale; import java.util.Optional; import java.util.UUID; public class LoanListener { private MessageStorage messages = EconomyLite.getMessageStorage(); private LoanManager loans; private LoanModule module; private double maxLoanBal; private double intRate; public LoanListener(LoanModule module) { this.module = module; this.loans = module.getLoanManager(); this.maxLoanBal = module.getMaxLoan(); this.intRate = module.getInterestRate(); } @Listener public void onBalanceChange(EconomyTransactionEvent event) { // Check if the transaction failed due to insufficient funds if (event.getTransactionResult().getResult().equals(ResultType.ACCOUNT_NO_FUNDS)) { // Check if the UUID is in the event Optional<UUID> uOpt = event.getCause().first(UUID.class); Optional<String> sOpt = event.getCause().first(String.class); if (sOpt.isPresent()) { if (sOpt.get().equalsIgnoreCase("economylite:loan")) { return; } } if (uOpt.isPresent()) { UUID uuid = uOpt.get(); // Try to get the player Optional<Player> pOpt = Sponge.getServer().getPlayer(uuid); if (pOpt.isPresent()) { Player player = pOpt.get(); // Get loan balance of the player Optional<Double> dOpt = loans.getLoanBalance(uuid); if (dOpt.isPresent()) { double loanBalance = dOpt.get(); // Calculate amount of money the player is short of Currency cur = event.getTransactionResult().getCurrency(); BigDecimal bal = event.getTransactionResult().getAccount().getBalance(cur); BigDecimal mis = event.getTransactionResult().getAmount().subtract(bal); double misDouble = mis.doubleValue(); // Notify player of interest rate player.sendMessage(messages.getMessage("module.loan.interest", "rate", Double.toString(intRate))); // Check how much loan they can take out double maxLoan = (maxLoanBal - loanBalance) / intRate; if (maxLoan <= 0) { return; } if (maxLoan < misDouble) { // Offer the player a smaller loan player.sendMessage(messages.getMessage("module.loan.partial")); player.sendMessage(messages.getMessage("module.loan.ask", "amount", String.format(Locale.ENGLISH, "%,.2f", maxLoan), "label", getPrefix(maxLoan, cur))); double total = maxLoan * intRate; player.sendMessage(messages.getMessage("module.loan.payment", "amount", String.format(Locale.ENGLISH, "%,.2f", total), "label", getPrefix(total, cur))); module.tableLoans.remove(uuid); module.tableLoans.put(uuid, maxLoan); } else { // Ask the player if they want a full loan player.sendMessage(messages.getMessage("module.loan.ask", "amount", String.format(Locale.ENGLISH, "%,.2f", mis), "label", getPrefix(mis.doubleValue(), cur))); BigDecimal total = mis.multiply(BigDecimal.valueOf(intRate)); player.sendMessage(messages.getMessage("module.loan.payment", "amount", String.format(Locale.ENGLISH, "%,.2f", total), "label", getPrefix(total.doubleValue(), cur))); player.sendMessage(LoanTextUtils.yesOrNo("/loan accept", "/loan deny")); module.tableLoans.remove(uuid); module.tableLoans.put(uuid, mis.doubleValue()); } } } } } } @Listener public void onLoanChange(LoanBalanceChangeEvent event) { UUID uuid = event.getUser(); for (Player player : Sponge.getServer().getOnlinePlayers()) { if (player.getUniqueId().equals(uuid)) { if (event.getNewBalance() == 0) { // Remove the debtor permissions module.getPermissions().forEach((perm, val) -> { player.getSubjectData().setPermission(SubjectData.GLOBAL_CONTEXT, perm, Tristate.fromBoolean(!val)); }); } else { // Add the debtor permissions module.getPermissions().forEach((perm, val) -> { player.getSubjectData().setPermission(SubjectData.GLOBAL_CONTEXT, perm, Tristate.fromBoolean(val)); }); } } } } private String getPrefix(double amnt, Currency cur) { Text label = cur.getPluralDisplayName(); if (amnt == 1.0) { label = cur.getDisplayName(); } return TextSerializers.FORMATTING_CODE.serialize(label); } }