594 lines
29 KiB
Java
594 lines
29 KiB
Java
package jesse.keeblarcraft.BankMgr;
|
|
|
|
import java.util.*;
|
|
import java.util.Map.Entry;
|
|
|
|
import static java.util.Map.entry;
|
|
|
|
import java.io.File;
|
|
|
|
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
|
|
import jesse.keeblarcraft.Keeblarcraft;
|
|
import jesse.keeblarcraft.BankMgr.BankAccountType.ACCOUNT_TYPE;
|
|
import jesse.keeblarcraft.Utils.CommonStructures.Pair;
|
|
|
|
// Contains the information of an individual bank
|
|
//
|
|
// The bank will keep track of all accounts within its facilities. In addition to accounts, the bank
|
|
// maintains its own identifier which is unique and other misc things.
|
|
public class IndividualBank {
|
|
private Map<ACCOUNT_TYPE, Integer> ACCOUNT_TYPES = Map.ofEntries(
|
|
entry(ACCOUNT_TYPE.CHECKING, 0),
|
|
entry(ACCOUNT_TYPE.SAVINGS, 1)
|
|
);
|
|
|
|
private ConfigManager config = new ConfigManager();
|
|
private Integer routingNumber; // this is the banks unique identifier
|
|
private Integer numberOfAccounts = 0; // Total number of accounts the bank has. This includes only active accounts inside accountsList.
|
|
private Integer maxBankAccounts = 100_000_000; // Making this simple for myself any one type of account has 8 random numbers genereated so 10^8 possible accounts
|
|
private String bankFourLetterIdentifier;
|
|
private String registeredBankName;
|
|
|
|
private static String CONFIG_LOCATION = "config/keeblarcraft/bank/";
|
|
|
|
// Think FDIC but from the servers account (keeblarcraft insurance corporation)
|
|
// KBIC will ensure an amount of money based on its trustworthiness to a bank and the number of holders it has.
|
|
private Integer kbicInsuredAmount = 75_000;
|
|
private Boolean kbicInsured = false;
|
|
|
|
// bankMoney is the total amount of money the bank possesses itself. The bank itself is personally responsible
|
|
// for backing the amount of money it claims it has and this is the balance that is withdrawn from for credits.
|
|
// A bank can have a sum of money that is less than the total amount of money of all its account holders
|
|
private Integer bankMoney = 0;
|
|
|
|
// Key = ACCOUNT NUMBER
|
|
// Value = ACCOUNT
|
|
private class Accounts {
|
|
// Key = account identifier
|
|
// Val = account object
|
|
private HashMap<String, IndividualAccount> accountsList = new HashMap<String, IndividualAccount>();
|
|
|
|
// Key = user uuid
|
|
// Val = List of account identifiers
|
|
private HashMap<String, List<String>> accountsListFromName = new HashMap<String, List<String>>(); // This is a list that just points to a list of account numbers by person. USEFUL
|
|
}
|
|
|
|
Accounts accounts;
|
|
private List<String> lockedUsers; // A list of users who are locked out of the bank and are incapable of performing more actions within it
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn IndividualBank
|
|
///
|
|
/// @param[in] routingNumber is the routing number this bank is constructed
|
|
/// with
|
|
///
|
|
/// @param[in] nameOfBank Will be the display name of this bank to players
|
|
///
|
|
/// @brief Constructor for this bank
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public IndividualBank(String routingNumber, String nameOfBank) {
|
|
accounts = new Accounts();
|
|
lockedUsers = new ArrayList<String>();
|
|
registeredBankName = nameOfBank.toUpperCase();
|
|
bankFourLetterIdentifier = nameOfBank.substring(0, 4).toLowerCase();
|
|
this.routingNumber = Integer.parseInt(routingNumber);
|
|
|
|
System.out.println("CREATING BANK ACCOUNT WITH ROUTING NUMBER " + routingNumber + " AND NAME " + nameOfBank);
|
|
|
|
boolean existingFile = false;
|
|
try {
|
|
// Read in the global accounts list
|
|
String accountsListDir = CONFIG_LOCATION + routingNumber.toString() + "/accounts/";
|
|
System.out.println("accountsListDir + bankName is " + accountsListDir + nameOfBank);
|
|
accounts = config.GetJsonObjectFromFile(accountsListDir + nameOfBank, Accounts.class);
|
|
existingFile = accounts != null;
|
|
|
|
// TODO: REPLACE WITH SQL SERVER. DIRTY ITERATE OVER ALL FILES IN DIRECTORY TO LOAD STRUCTURE
|
|
File dir = new File(accountsListDir);
|
|
File[] allFiles = dir.listFiles();
|
|
if (accounts != null && allFiles != null) {
|
|
for (File file : allFiles ) {
|
|
// First grab file identifier as KEY
|
|
String accountIdentifier = file.getName();
|
|
String accountFromFile = accountsListDir + "/" + accountIdentifier;
|
|
System.out.println("accountIdentifier found in file is " + accountIdentifier);
|
|
System.out.println("account identifier with dir path is " + accountFromFile);
|
|
accounts.accountsList.put(accountIdentifier, config.GetJsonObjectFromFile(accountFromFile, IndividualAccount.class));
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
System.out.println("The try-catch in IndividualBank.java failed to complete. Printing stack trace");
|
|
// e.printStackTrace();
|
|
// Falling into this catch just means the file needs to be made
|
|
}
|
|
|
|
if (!existingFile)
|
|
{
|
|
try {
|
|
// We assume the bank dir is created by server. Create this banks dir
|
|
// config.CreateDirectory("bank/" + routingNumber);
|
|
// Create this banks initial accounts dir
|
|
config.CreateDirectory(CONFIG_LOCATION + routingNumber + "/accounts");
|
|
|
|
// Flash initial account configuration file for this bank
|
|
FlashConfig("accounts");
|
|
} catch (Exception e) {
|
|
Keeblarcraft.LOGGER.error("Could not write to file in IndividualBank");
|
|
}
|
|
}
|
|
|
|
// A modified config reader is needed here for when each IndividualAccount is read in - the name is taken from that and is attached to the
|
|
// 'accountsListFromName' structure. This makes it no worse than O(n) to fill these two structures in.
|
|
// NOTE: This is an *EXPENSIVE* operation! Future us might need to update this. Also note a method is needed for everytime a player opens a new account
|
|
// or gets put on one to update the map every time
|
|
if (accounts != null) {
|
|
for (Entry<String, IndividualAccount> account : accounts.accountsList.entrySet()) {
|
|
// We must loop over the string of holders for each account as well to make the flattened accountsListFromName map
|
|
List<String> accountHolders = account.getValue().GetAccountHolders();
|
|
|
|
// Match each user to the secondary map & add to list-value if not existing
|
|
for (String accountHolder : accountHolders) {
|
|
if (accounts.accountsListFromName.containsKey(accountHolder)) {
|
|
// Case 1: User exists, update map entry
|
|
accounts.accountsListFromName.get(accountHolder).add(account.getKey()); // Add a new account id to this person in the new flat map
|
|
} else {
|
|
// Case 2: User does not already exist; add a new map entry
|
|
accounts.accountsListFromName.put(accountHolder, List.of(account.getKey())); // Store name as key, and new List with the value of ACCOUNT #
|
|
}
|
|
}
|
|
}
|
|
numberOfAccounts = accounts.accountsList.size();
|
|
} else {
|
|
accounts = new Accounts();
|
|
numberOfAccounts = 0;
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn GetBankName
|
|
///
|
|
/// @return Returns this banks name
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public String GetBankName() {
|
|
return registeredBankName;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn GetAccountsOfUser
|
|
///
|
|
/// @param[in] uuid is the players UUID to check
|
|
///
|
|
/// @brief Gets all the accounts a user has at this bank by UUID
|
|
///
|
|
/// @return List of all bank accounts. List will be EMPTY if no accounts
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public List<IndividualAccount> GetAccountsOfUser(String uuid) {
|
|
List<IndividualAccount> accountsFromUser = new ArrayList<IndividualAccount>();
|
|
List<String> listOfAccounts = accounts.accountsListFromName.get(uuid);
|
|
|
|
if (listOfAccounts != null && !listOfAccounts.isEmpty()) {
|
|
for (String listOfAccount : listOfAccounts) {
|
|
accountsFromUser.add(accounts.accountsList.get(listOfAccount));
|
|
}
|
|
}
|
|
return accountsFromUser;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn GetBankBalance
|
|
///
|
|
/// @return The banks balance
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Integer GetBankBalance() {
|
|
return bankMoney;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn AddBankBalance
|
|
///
|
|
/// @param[in] amount Amount to add to the banks balance
|
|
///
|
|
/// @brief Adds to the banks balance
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public void AddBankBalance(Integer amount) {
|
|
bankMoney += amount;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn SubtractBankBalance
|
|
///
|
|
/// @param[in] amount Amount to subtract from banks balance
|
|
///
|
|
/// @brief Subtracts from the banks balance
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public void SubtractBankBalance(Integer amount) {
|
|
bankMoney -= amount;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn SetBankBalance
|
|
///
|
|
/// @param[in] amount Amount to give the bank
|
|
///
|
|
/// @brief Set the banks balance
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public void SetBankBalance(Integer amount) {
|
|
bankMoney = amount;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn IsBankInsured
|
|
///
|
|
/// @return True if bank is insured, false if not
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Boolean IsBankInsured() {
|
|
return kbicInsured;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn InsuranceAmount
|
|
///
|
|
/// @brief Get the insurance amount at this bank
|
|
///
|
|
/// @return Insurance amount
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Integer InsuranceAmount() {
|
|
Integer insuredAmnt = 0;
|
|
if (kbicInsured) {
|
|
insuredAmnt = kbicInsuredAmount;
|
|
} else {
|
|
insuredAmnt = 0;
|
|
}
|
|
return insuredAmnt;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn UpdateBankAccounts
|
|
///
|
|
/// @brief Flashes bank account information to disk; updates volatile
|
|
/// memory of banking information for this bank
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public void UpdateBankAccounts(String newHolderName, String newHolderUuid, String accountIdentifier, IndividualAccount newAccountOnly) {
|
|
// Update the fast-access map first
|
|
System.out.println("UpdateBankAccounts called with information " + newHolderName + " " + newHolderUuid + " " + accountIdentifier);
|
|
if (accounts.accountsListFromName.containsKey(newHolderUuid)) {
|
|
// Check if user is already in map
|
|
accounts.accountsListFromName.get(newHolderUuid).add(accountIdentifier);
|
|
} else {
|
|
// Add new entry to map
|
|
List<String> userAccountList = new ArrayList<String>(); // Lists are immutable; must make ArrayList
|
|
userAccountList.add(accountIdentifier);
|
|
accounts.accountsListFromName.put(newHolderUuid, userAccountList);
|
|
}
|
|
|
|
// Update regular account list
|
|
if (accounts.accountsList.containsKey(accountIdentifier)) {
|
|
// This path assumes we are adding a holder as opposed to adding an account (else, how else would this work?)
|
|
System.out.println("Account found in accounts list, adding this person as a holder instead");
|
|
accounts.accountsList.get(accountIdentifier).AddAccountHolder(newHolderName, newHolderUuid);
|
|
} else {
|
|
// Non-existent account means a new one!
|
|
System.out.println("Brand new account creation, adding!");
|
|
accounts.accountsList.put(accountIdentifier, newAccountOnly);
|
|
numberOfAccounts++;
|
|
}
|
|
|
|
System.out.println("Flashing configuration file");
|
|
FlashConfig("bank/" + routingNumber + "/accounts");
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn GetRoutingNumber
|
|
///
|
|
/// @return Routing number
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Integer GetRoutingNumber() {
|
|
return this.routingNumber;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn AddMoneyToAccount
|
|
///
|
|
/// @param[in] accountId is the account to add money to at this bank
|
|
///
|
|
/// @param[in] amount is the amount of money to add to this account
|
|
///
|
|
/// @brief Adds money to an account at this bank if it exists
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public void AddMoneyToAccount(String accountId, Integer amount) {
|
|
IndividualAccount account = accounts.accountsList.get(AccountNumberGenerator.GetAccountNumberFromId(accountId));
|
|
System.out.println("Received account # " + accountId + " and money amnt " + amount);
|
|
System.out.println("Is account null? " + (account == null ? "YES":"NO"));
|
|
|
|
System.out.println("accounts.accountList.size() : " + accounts.accountsList.size());
|
|
for (Entry<String, IndividualAccount> accnt : accounts.accountsList.entrySet()) {
|
|
System.out.println("Account num in entry: " + accnt.getValue().GetAccountNumber());
|
|
}
|
|
|
|
if (account != null && account.Deposit(amount)) {
|
|
GenerateTransactionReport(TransactionMetadata.TRANSACTION_TYPE.DEPOSIT, new Pair<>("ADMIN", "ADMIN"), new Pair<>("ADMIN", "ADMIN"), amount, "ADMIN");
|
|
FlashConfig("bank/" + routingNumber + "/accounts");
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn SubtractMoneyFromAccount
|
|
///
|
|
/// @param[in] accountId is the account to subtract money to at this bank
|
|
///
|
|
/// @param[in] amount is the amount of money to subtract to this account
|
|
///
|
|
/// @brief Subtracts money from an account at this bank if it exists
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public void SubtractMoneyFromAccount(String accountId, Integer amount) {
|
|
IndividualAccount account = accounts.accountsList.get(AccountNumberGenerator.GetAccountNumberFromId(accountId));
|
|
|
|
if (account != null && account.Withdraw(amount)) {
|
|
GenerateTransactionReport(TransactionMetadata.TRANSACTION_TYPE.WITHDRAWAL, new Pair<>("ADMIN", "ADMIN"), new Pair<>("ADMIN", "ADMIN"), amount, "ADMIN");
|
|
FlashConfig("bank/" + routingNumber + "/accounts");
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn SetMoneyOnAccount
|
|
///
|
|
/// @param[in] accountId is the account number
|
|
///
|
|
/// @param[in] amount is the new balance to give this account
|
|
///
|
|
/// @brief Sets a balance on an account if it exists
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public void SetMoneyOnAccount(String accountId, Integer amount) {
|
|
IndividualAccount account = accounts.accountsList.get(accountId);
|
|
System.out.println("Is account null? " + (account == null ? "YES" : "NO"));
|
|
System.out.println("Received account # " + accountId + " and money amnt " + amount);
|
|
|
|
for (Entry<String, IndividualAccount> debug : accounts.accountsList.entrySet()) {
|
|
System.out.println("ACCOUNT ID: " + debug.getKey());
|
|
System.out.println("ACCOUNT NUM: " + debug.getValue().GetAccountNumber());
|
|
}
|
|
|
|
if (account != null) {
|
|
account.SetMoney(amount);
|
|
GenerateTransactionReport(TransactionMetadata.TRANSACTION_TYPE.OTHER, new Pair<>("ADMIN", "ADMIN"), new Pair<>("ADMIN", "ADMIN"), amount, "ADMIN");
|
|
FlashConfig("bank/" + routingNumber + "/accounts");
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn CreateAccount
|
|
///
|
|
/// @param[in] holderUuid is the new holders UUID of this account
|
|
///
|
|
/// @param[in] holderName is the display name of the holder
|
|
///
|
|
/// @param[in] accountTypeStr is the account type as a string (will be number)
|
|
///
|
|
/// @brief Create a new account at this bank
|
|
///
|
|
/// @return True if account can be created, false if it fails
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Boolean CreateAccount(String holderUuid, String holderName, ACCOUNT_TYPE accountType) {
|
|
Boolean success = false;
|
|
if (accounts.accountsList.size() <= maxBankAccounts) {
|
|
// Verify this isn't a blacklisted user
|
|
System.out.println("Is user bank locked? " + lockedUsers.contains(holderName));
|
|
if (!lockedUsers.contains(holderName)) {
|
|
Integer maxAttempts = 15; // Reasonably a unique bank account should pop up within 1000 generations. If not, the user may try again.
|
|
String accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountType), holderName);
|
|
|
|
System.out.println("Account generator came back with bank account id { " + accountId + " }");
|
|
System.out.println("4 letter bank: " + AccountNumberGenerator.GetFinancialSymbolFromId(accountId));
|
|
System.out.println("Routing: " + AccountNumberGenerator.GetRoutingNumberFromId(accountId));
|
|
System.out.println("Account type: " + AccountNumberGenerator.GetAccountTypeFromId(accountId));
|
|
System.out.println("RNG Account number: " + AccountNumberGenerator.GetAccountNumberFromId(accountId));
|
|
|
|
// TODO: Fix in future with a method that will guarentee a one-time necessary number generator. Statistically speaking; this will be okay for the
|
|
// entire life time of the server. BUT, you never know!
|
|
while (maxAttempts != 0 && !accounts.accountsList.containsKey(AccountNumberGenerator.GetAccountNumberFromId(accountId))) {
|
|
accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountType), holderName);
|
|
System.out.println("Account generator came back with bank account id { " + accountId + " }");
|
|
maxAttempts--;
|
|
}
|
|
|
|
// Final check to add the account
|
|
String actualAccountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
|
|
System.out.println("Bank account identifier is { " + actualAccountNumber + " }. Is this already an existing account? " + accounts.accountsList.containsKey(actualAccountNumber));
|
|
if (!accounts.accountsList.containsKey(actualAccountNumber)) {
|
|
IndividualAccount newAccount = new IndividualAccount(actualAccountNumber, this.routingNumber, List.of(holderName),
|
|
List.of(holderUuid), false, 0,
|
|
"", accountType, bankFourLetterIdentifier);
|
|
System.out.println("Updating accounts list for this bank");
|
|
UpdateBankAccounts(holderName, holderUuid, actualAccountNumber, newAccount);
|
|
success = true;
|
|
}
|
|
}
|
|
}
|
|
return success;
|
|
}
|
|
|
|
// fromParty is expected to be UUID mapped to username
|
|
// toParty is expected to be UUID mapped to username
|
|
// NOTHING should be null in this generation!
|
|
public void GenerateTransactionReport(TransactionMetadata.TRANSACTION_TYPE transactionType, Pair<String, String> fromParty, Pair<String, String> toParty, Integer amount, String reason) {
|
|
// The transaction ID is to be formatted (for now) as #-FROMUUID-TOUUID-RNG
|
|
// For this version, we pray there is not a duplicate RNG dupe and no checking is done for now!
|
|
StringBuilder transactionId = new StringBuilder("#" + fromParty.GetKey() + "-" + toParty.GetKey() + Integer.toString(new Random().nextInt(100_000_000) + 1_000_000));
|
|
TransactionMetadata trans = new TransactionMetadata(transactionType, fromParty, toParty, amount, transactionId.toString(), reason);
|
|
|
|
// This is a hacky solution to make sure the transaction file doesn't exist. It is "technically" possible we fail 10 times in a row
|
|
// then can't write and thus no papertrail is left - however if the RNG fails to make a unique enough number with these UUID's between
|
|
// 1 million and 100 million then we have other issues to worry about.
|
|
int maxTries = 10;
|
|
// We now want to iterate over the files in the transaction dir and pop a new file in
|
|
while (config.DoesFileExist("bank/" + routingNumber + "/transactions/" + transactionId) && maxTries-- >= 0) {
|
|
transactionId.append(Integer.toString(new Random().nextInt(100_000_000) + 1_000_000));
|
|
}
|
|
|
|
if (!config.DoesFileExist("bank/" + routingNumber + "/transactions/" + transactionId)) {
|
|
config.WriteToJsonFile("bank/" + routingNumber + "/transactions/" + transactionId + ".json", trans);
|
|
}
|
|
}
|
|
|
|
// The value 0 should be treated as either non-exist
|
|
public Optional<Integer> GetAccountBalance(String accountId) {
|
|
Optional<Integer> amount = Optional.empty();
|
|
if (accounts.accountsList.containsKey(accountId)) {
|
|
IndividualAccount account = accounts.accountsList.get(accountId);
|
|
amount = Optional.of(account.GetAccountBalance());
|
|
}
|
|
return amount;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn LockAccountHolder
|
|
///
|
|
/// @param[in] holderName is player to lock account
|
|
///
|
|
/// @brief Locks all accounts under a name for this user
|
|
///
|
|
/// @return True if lock succeeds, false if not
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Boolean LockAccountHolder(String holderName) {
|
|
Boolean success = false;
|
|
|
|
int accountIter = 0;
|
|
for (Entry<String, List<String>> holderAccounts : accounts.accountsListFromName.entrySet()) {
|
|
accounts.accountsList.get(holderAccounts.getValue().get(accountIter++)).LockAccount();
|
|
}
|
|
return success;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn CloseAccount
|
|
///
|
|
/// @param[in] accountId is id of account to be closed
|
|
///
|
|
/// @brief Closes an account
|
|
///
|
|
/// @note Balance of account must be 0 to close successfully
|
|
///
|
|
/// @return True if can close, false if not
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Boolean CloseAccount(String accountId, String playerUuid) {
|
|
boolean success = false;
|
|
|
|
if (accounts.accountsList.containsKey(accountId) && accounts.accountsList.get(accountId).GetAccountBalance() == 0) {
|
|
System.out.println("Closing user account...");
|
|
// The below two lists should ALWAYS be in sync. If there is a discrepancy; this may segfault!
|
|
accounts.accountsList.remove(accountId);
|
|
accounts.accountsListFromName.get(playerUuid).remove(accountId);
|
|
FlashConfig("bank/" + routingNumber + "/accounts");
|
|
success = true;
|
|
}
|
|
return success;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn HasAccount
|
|
///
|
|
/// @param[in] accountIdentifier account number to check to see if it exists
|
|
/// at this bank
|
|
///
|
|
/// @brief See if an account identifier belongs to this bank
|
|
///
|
|
/// @return True if this bank has this account identifier, false if not
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Boolean HasAccount(String accountIdentifier) {
|
|
return accounts.accountsList.containsKey(accountIdentifier);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn IsValidWithdrawal
|
|
///
|
|
/// @param[in] withdrawalAmount The amount to be withdrawn
|
|
///
|
|
/// @param[in] accountIdentifier account to withdraw from
|
|
///
|
|
/// @brief Verifies if a withdrawal will succeed on an account prior to
|
|
/// the actual withdrawal itself
|
|
///
|
|
/// @return True if this account can afford this withdrawal. False if not
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Boolean IsValidWithdrawal(Integer withdrawalAmount, String accountIdentifier) {
|
|
boolean isValid = false;
|
|
|
|
System.out.println("Account id: " + accountIdentifier);
|
|
System.out.println("Short account id: " + AccountNumberGenerator.GetAccountNumberFromId(accountIdentifier));
|
|
String localAccountId = AccountNumberGenerator.GetAccountNumberFromId(accountIdentifier);
|
|
System.out.println("Amount to withdraw: " + withdrawalAmount);
|
|
System.out.println("accounts list map: " + accounts.accountsList);
|
|
if (accounts.accountsList.containsKey(localAccountId)) {
|
|
IndividualAccount account = accounts.accountsList.get(localAccountId);
|
|
System.out.println("Is account null? " + (account == null));
|
|
|
|
if (account.CanWithdraw(withdrawalAmount)) {
|
|
isValid = true;
|
|
}
|
|
}
|
|
|
|
return isValid;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn IsAccountHolder
|
|
///
|
|
/// @param[in] accountIdentifier Account to check
|
|
///
|
|
/// @param[in] uuid Is players UUID to see if they are on this account
|
|
///
|
|
/// @brief Check if a player is on this account
|
|
///
|
|
/// @return True if player is on this account. False if not or account
|
|
/// does not exist
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public Boolean IsAccountHolder(String accountIdentifier, String uuid) {
|
|
Boolean isHolder = false;
|
|
|
|
System.out.println("Looking for accountIdentifier: " + accountIdentifier);
|
|
for (Entry<String, IndividualAccount> account : accounts.accountsList.entrySet()) {
|
|
System.out.println("ACCOUNT ID: " + account.getKey());
|
|
}
|
|
|
|
// Verify account exists first
|
|
if (accounts.accountsList.containsKey(accountIdentifier)) {
|
|
isHolder = accounts.accountsList.get(accountIdentifier).IsHolder(uuid);
|
|
} else {
|
|
System.out.println("Account identifier found to not exist");
|
|
}
|
|
|
|
return isHolder;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
/// @fn FlashConfig
|
|
///
|
|
/// @param[in] dirName is config to flash to. Banking is not trivial and will
|
|
/// require separate files to be updated at different locations!
|
|
///
|
|
/// @brief Flashes the config to the disk
|
|
///
|
|
/// @note dirName should be the relative full path to dir
|
|
/// @note Function will be removed in near future for SQL but is
|
|
/// expensive to run as it flashes everything even if un-updated
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
public void FlashConfig(String dirName) {
|
|
for (Entry<String, IndividualAccount> singleAccount : accounts.accountsList.entrySet()) {
|
|
System.out.println("FlashConfig. dirname: " + dirName);
|
|
// Iterate over each one & verify if a file exists inside the dir. if it does;
|
|
// nuke it and
|
|
// replace it with the new contents in memory
|
|
String accountNum = singleAccount.getKey().toString();
|
|
|
|
// delete file
|
|
File file = new File(dirName + "/" + accountNum + ".json");
|
|
System.out.println("Checking path: " + dirName + "/" + accountNum + ".json");
|
|
if (file.exists()) {
|
|
file.delete();
|
|
}
|
|
|
|
// Re-flash file
|
|
config.WriteToJsonFile(dirName + "/" + accountNum + ".json", singleAccount.getValue());
|
|
}
|
|
}
|
|
} |