package jesse.keeblarcraft.BankMgr; import java.util.HashMap; import java.util.List; import java.util.ArrayList; import java.util.Map.Entry; import jesse.keeblarcraft.ConfigMgr.ConfigManager; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; // The bank manager takes care of routing any and all transactions throughout the server. // It is a singleton object that is active throughout the mods lifetime and will cache players accounts // when they log in to avoid constant look-ups through JSON. public final class BankManager { private static BankManager static_inst; public static BankManager GetInstance() { if (static_inst == null) { static_inst = new BankManager(); } return static_inst; } private class PlayerBankConfig { List activeBanks = new ArrayList(); // List of all banks a player has accounts in String defaultSelectedBank; } // Key = player uuid // Val = player config HashMap playerConfigs = new HashMap(); // Stores global detail information for bank mgr to use private static Integer KEEBLARCRAFT_SERVER_BANK_ID = 1000; // Server global bank (default bank on server) ConfigManager config = new ConfigManager(); // KEY = Bank routing number // Val = Bank object private HashMap banks = new HashMap(); // KEY = Bank name // Val = Bank routing number private HashMap bankNameFastMap = new HashMap(); public BankManager() {} // TODO: THIS NEEDS TO READ IN FROM A FILE TO STOP NUKING BANKS ON REBOOT ///////////////////////////////////////////////////////////////////////////// /// @fn InitializeBanks /// /// @brief Initializes all the banks on the server at construction time ///////////////////////////////////////////////////////////////////////////// public void InitializeBanks() { banks.put(KEEBLARCRAFT_SERVER_BANK_ID, new IndividualBank(Integer.toString(KEEBLARCRAFT_SERVER_BANK_ID), "KeeblarcraftGlobal")); // Initialize fast map for (Entry bank : banks.entrySet()) { bankNameFastMap.put(bank.getValue().GetBankName(), bank.getValue().GetRoutingNumber()); } } ///////////////////////////////////////////////////////////////////////////// /// @fn GetAllBankNames /// /// @return List of all the banks that exist on a server ///////////////////////////////////////////////////////////////////////////// public List GetAllBankNames() { List names = new ArrayList(); // Iterate through all banks in the list to get their names for (Entry bank : banks.entrySet()) { names.add(bank.getValue().GetBankName()); } return names; } ///////////////////////////////////////////////////////////////////////////// /// @fn GetBankByRoutingNumber /// /// @return The IndividualBank object by routing number if the bank exists ///////////////////////////////////////////////////////////////////////////// public IndividualBank GetBankByRoutingNumber(Integer number) { IndividualBank bank = null; if (banks.containsKey(number)) { bank = banks.get(number); } return bank; } ///////////////////////////////////////////////////////////////////////////// /// @fn GetBankByName /// /// @return The Individualbank object by name if the bank exists ///////////////////////////////////////////////////////////////////////////// public IndividualBank GetBankByName(String name) { IndividualBank bank = null; System.out.println("GetBankByName called with value " + name); if (bankNameFastMap.containsKey(name)) { System.out.println("Value of bank with name is " + bankNameFastMap.get(name)); System.out.println("Banks map size is " + banks.size()); bank = banks.get(bankNameFastMap.get(name)); } System.out.println("Returning bank information"); return bank; } ///////////////////////////////////////////////////////////////////////////// /// @fn ChangeDefaultPlayerAccount /// /// @param[in] player Player object to change default accounts of /// /// @param[in] The new default account global account identifier /// /// @return Changes the players default account at a selected bank ///////////////////////////////////////////////////////////////////////////// public void ChangeDefaultPlayerAccount(ServerPlayerEntity player, String newDefaultAccount) { String bankName = AccountNumberGenerator.GetFinancialSymbolFromId(newDefaultAccount); System.out.println("ChangeDefaultPlayerAccount: Received bankName " + bankName); System.out.println(bankNameFastMap); // Verify bank exists first if (bankNameFastMap.containsKey(bankName)) { Integer routNum = bankNameFastMap.get(bankName); IndividualBank bank = banks.get(routNum); // Verify this person has access to this account if(bank.IsAccountHolder(newDefaultAccount, player.getUuidAsString())) { // Finally update config to this account since checks pass playerConfigs.get(player.getUuidAsString()).defaultSelectedBank = newDefaultAccount; } } else { player.sendMessage(Text.of("Could not change default selected bank. Bank does not exist!")); } } ///////////////////////////////////////////////////////////////////////////// /// @fn AdminChangeFunds /// /// @param[in] initiator The player object who is initiating this call /// /// @param[in] accountId The account to change funds of /// /// @param[in] amount The amount to change funds of in changeType /// /// @param[in] changeType The type of funds change being initiated /// /// @param[in] optionalReason The optional reason of changing funds /// /// @brief Command manager to initiate a funds change from an admins /// perspective (safe guards dropped). Valid changeTypes are /// found inside the switch-case statement in the below function ///////////////////////////////////////////////////////////////////////////// public void AdminChangeFunds(ServerPlayerEntity initiator, String accountId, Integer amount, String changeType, String optionalReason) { // Check to make sure account id exists Integer routingNum = AccountNumberGenerator.GetRoutingNumberFromId(accountId); IndividualBank bankFromRout = GetBankByRoutingNumber(routingNum); System.out.println("Is bank null? " + (bankFromRout == null ? "YES" : "NO")); System.out.println("Bank specified: " + bankFromRout); System.out.println("Routing number: " + routingNum); // Verify bank exists if (bankFromRout != null) { // Verify account exists System.out.println("accountNumber is " + accountId); String accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId); System.out.println("changeType is " + changeType); switch (changeType) { case "add": bankFromRout.AddMoneyToAccount(accountNumber, amount); break; case "subtract": bankFromRout.SubtractMoneyFromAccount(accountNumber, amount); break; case "set": bankFromRout.SetMoneyOnAccount(accountNumber, amount); break; default: System.out.println("The operation that was specified by the developer does not exist. Valid operations are add/subtract/set"); break; } } else { initiator.sendMessage(Text.of("That bank does not exist!")); } } ///////////////////////////////////////////////////////////////////////////// /// @fn InitiateBankFundsTransfer /// /// @param[in] fromPlayer is the player funds are coming out of /// /// @param[in] toAccount is the account the funds are going to /// /// @param[in] amount is the amount of money coming from the player /// /// @brief Initiate a funds transfer between accounts or banks ///////////////////////////////////////////////////////////////////////////// public void InitiateBankFundsTransfer(ServerPlayerEntity fromPlayer, String toAccount, Integer amount) { // Get player default selection String fromAccount = playerConfigs.get(fromPlayer.getUuidAsString()).defaultSelectedBank; String fromAccountSymbol = AccountNumberGenerator.GetFinancialSymbolFromId(fromAccount); String toAccountSymbol = AccountNumberGenerator.GetFinancialSymbolFromId(toAccount); System.out.println("InitiateBankFundsTransfer: FROM_ACCOUNT, FROM_ACCOUNT_SYMBOL, TO_ACCOUNT_SYMBOL: " + fromAccount + ", " + fromAccountSymbol + ", " + toAccountSymbol); Integer destRoutingNumber = bankNameFastMap.get(toAccountSymbol); Integer fromRoutingNumber = bankNameFastMap.get(fromAccountSymbol); IndividualBank destBank = banks.get(destRoutingNumber); IndividualBank fromBank = banks.get(fromRoutingNumber); // Verify banks exist if (destBank != null && fromBank != null) { if (fromBank.IsValidWithdrawal(amount, fromAccount)) { fromBank.SubtractMoneyFromAccount(fromAccount, amount); destBank.AddMoneyToAccount(toAccount, amount); fromPlayer.sendMessage(Text.of("[" + fromAccountSymbol + "]: Your wire has processed.")); } else { fromPlayer.sendMessage(Text.of("[" + fromAccountSymbol + "]: You are not allowed to make this withdrawal.")); } } else { fromPlayer.sendMessage(Text.of("Something went wrong! Either your bank or their bank does not exist. You shouldn't get this error!")); } } public void InitiateBankAccountClosure(String bankIdentifier, ServerPlayerEntity player, String bankAccountId) { } ///////////////////////////////////////////////////////////////////////////// /// @fn GetDefaultSelectedAccount /// /// @param[in] playerUuid is the player to get their default account /// /// @param[in] bankIdentifier is the bank the default account is at /// /// @brief Gets a players default account /// /// @return The global account identifier of the default selected account ///////////////////////////////////////////////////////////////////////////// public String GetDefaultSelectedAccount(String playerUuid, String bankIdentifier) { String account = ""; if (playerConfigs.containsKey(playerUuid)) { account = playerConfigs.get(playerUuid).defaultSelectedBank; } return account; } ///////////////////////////////////////////////////////////////////////////// /// @fn InitiateBankAccountCreation /// /// @param[in] bankIdentifier is the bank routing number /// /// @param[in] player is the player object trying to create account /// /// @paran[in] accountType Is the type of account the player wants to make /// /// @brief Initiates a bank account creation with a bank ///////////////////////////////////////////////////////////////////////////// public void InitiateBankAccountCreation(String bankIdentifier, ServerPlayerEntity player, String accountType) { Boolean success = false; System.out.println("initiating bank creation"); boolean defaultServerBank = bankIdentifier == null || bankIdentifier == ""; System.out.println("value of bankIdentifier is " + defaultServerBank); System.out.println("The player name is " + player.getEntityName()); // DEBUG System.out.println("BANK NAME: " + banks.get(KEEBLARCRAFT_SERVER_BANK_ID).GetBankName()); System.out.println("BANK BALANCE: " + banks.get(KEEBLARCRAFT_SERVER_BANK_ID).GetBankBalance()); // DEBUG END // Create an account via the server-owned bank account if (defaultServerBank) { success = banks.get(KEEBLARCRAFT_SERVER_BANK_ID).CreateAccount(player.getUuidAsString(), player.getEntityName(), accountType); } else { System.out.println("Creating bank on non-server owned bank"); // Create an account via a specified bank identifier Integer routingNumber = Integer.parseInt(bankIdentifier); if (banks.containsKey(routingNumber)) { banks.get(routingNumber).CreateAccount(player.getUuidAsString(), player.getEntityName(), accountType); } else { player.sendMessage(Text.of("That bank does not exist")); } } if (success) { player.sendMessage(Text.of("The banking operation was successful and your banking information has been updated")); } else { player.sendMessage(Text.of("The banking operating FAILED. You may need to visit the bank for more information!")); } } }