2024-11-05 00:45:28 +00:00
package jesse.keeblarcraft.BankMgr ;
2024-11-10 04:21:21 +00:00
import java.util.ArrayList ;
2024-11-05 00:45:28 +00:00
import java.util.HashMap ;
import java.util.List ;
import java.util.Map ;
2024-11-07 01:01:41 +00:00
import java.util.Map.Entry ;
2024-11-05 00:45:28 +00:00
2024-11-07 01:01:41 +00:00
import static java.util.Map.entry ;
2024-11-10 04:21:21 +00:00
import java.io.File ;
2024-11-05 00:45:28 +00:00
import jesse.keeblarcraft.ConfigMgr.ConfigManager ;
2025-01-02 03:47:50 +00:00
import jesse.keeblarcraft.Keeblarcraft ;
import jesse.keeblarcraft.ChatStuff.ChatMsg ;
2024-11-05 00:45:28 +00:00
// 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 {
2024-11-07 01:01:41 +00:00
private Map < String , Integer > ACCOUNT_TYPES = Map . ofEntries (
entry ( " checking " , 0 ) ,
entry ( " savings " , 1 )
) ;
2024-11-10 04:21:21 +00:00
private ConfigManager config = new ConfigManager ( ) ;
2024-11-07 01:01:41 +00:00
private Integer routingNumber ; // this is the banks unique identifier
private Integer numberOfAccounts ; // 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
2024-11-10 04:21:21 +00:00
private String bankFourLetterIdentifier ;
private String registeredBankName ;
2024-11-05 00:45:28 +00:00
2024-11-24 20:06:34 +00:00
private static String CONFIG_LOCATION = " config/keeblarcraft/bank/ " ;
2024-11-05 00:45:28 +00:00
// 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 ;
private Boolean kbicInsured ;
// 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 ;
// Key = ACCOUNT NUMBER
// Value = ACCOUNT
2024-11-10 04:21:21 +00:00
private class Accounts {
2024-11-24 03:06:00 +00:00
// Key = account identifier
// Val = account object
2024-11-10 04:21:21 +00:00
private HashMap < String , IndividualAccount > accountsList = new HashMap < String , IndividualAccount > ( ) ;
2024-11-24 03:06:00 +00:00
// Key = user uuid
// Val = List of account identifiers
2024-11-10 04:21:21 +00:00
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
}
2024-11-05 00:45:28 +00:00
2024-11-10 04:21:21 +00:00
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
2024-11-05 00:45:28 +00:00
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
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 ) ;
2024-11-05 00:45:28 +00:00
2024-11-10 04:21:21 +00:00
System . out . println ( " CREATING BANK ACCOUNT WITH ROUTING NUMBER " + routingNumber + " AND NAME " + nameOfBank ) ;
2024-11-07 01:01:41 +00:00
2024-11-10 04:21:21 +00:00
boolean existingFile = false ;
try {
// Read in the global accounts list
2024-11-24 20:06:34 +00:00
String accountsListDir = CONFIG_LOCATION + routingNumber . toString ( ) + " /accounts/ " ;
2024-11-10 04:21:21 +00:00
System . out . println ( " accountsListDir + bankName is " + accountsListDir + nameOfBank ) ;
accounts = config . GetJsonObjectFromFile ( accountsListDir + nameOfBank , Accounts . class ) ;
existingFile = true ;
2024-11-07 01:01:41 +00:00
2024-11-10 04:21:21 +00:00
// TODO: REPLACE WITH SQL SERVER. DIRTY ITERATE OVER ALL FILES IN DIRECTORY TO LOAD STRUCTURE
File dir = new File ( accountsListDir ) ;
File [ ] allFiles = dir . listFiles ( ) ;
2025-01-03 04:05:16 +00:00
if ( accounts ! = null & & allFiles ! = null ) {
2024-11-10 04:21:21 +00:00
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
}
2024-11-07 01:01:41 +00:00
2024-11-10 04:21:21 +00:00
if ( ! existingFile )
{
try {
// We assume the bank dir is created by server. Create this banks dir
2024-11-24 20:06:34 +00:00
// config.CreateDirectory("bank/" + routingNumber);
2024-11-10 04:21:21 +00:00
// Create this banks initial accounts dir
2024-11-24 20:06:34 +00:00
config . CreateDirectory ( CONFIG_LOCATION + routingNumber + " /accounts " ) ;
2024-11-07 01:01:41 +00:00
2024-11-10 04:21:21 +00:00
// Flash initial account configuration file for this bank
FlashConfig ( " accounts " ) ;
} catch ( Exception e ) {
2025-01-02 03:47:50 +00:00
Keeblarcraft . LOGGER . error ( " Could not write to file in IndividualBank " ) ;
2024-11-10 04:21:21 +00:00
}
}
2024-11-07 01:01:41 +00:00
2024-11-05 00:45:28 +00:00
// 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
2024-11-07 01:01:41 +00:00
// '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
2025-01-03 04:05:16 +00:00
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 ( Integer holderIndex = 0 ; holderIndex < accountHolders . size ( ) ; holderIndex + + ) {
if ( accounts . accountsListFromName . containsKey ( accountHolders . get ( holderIndex ) ) ) {
// Case 1: User exists, update map entry
accounts . accountsListFromName . get ( accountHolders . get ( holderIndex ) ) . 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 ( accountHolders . get ( holderIndex ) , List . of ( account . getKey ( ) ) ) ; // Store name as key, and new List with the value of ACCOUNT #
}
2024-11-07 01:01:41 +00:00
}
}
2025-01-03 04:05:16 +00:00
numberOfAccounts = accounts . accountsList . size ( ) ;
} else {
accounts = new Accounts ( ) ;
numberOfAccounts = 0 ;
2024-11-07 01:01:41 +00:00
}
2024-11-10 04:21:21 +00:00
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn GetBankName
///
/// @return Returns this banks name
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public String GetBankName ( ) {
return registeredBankName ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public List < IndividualAccount > GetAccountsOfUser ( String uuid ) {
System . out . println ( " UUID passed in: " + uuid ) ;
List < IndividualAccount > accountsFromUser = new ArrayList < IndividualAccount > ( ) ;
List < String > listOfAccounts = accounts . accountsListFromName . get ( uuid ) ;
2024-11-17 03:56:52 +00:00
System . out . println ( " Is list of accounts null? " + ( listOfAccounts = = null ? " YES " : " NO " ) ) ;
System . out . println ( " List of account size: " + listOfAccounts . size ( ) ) ;
2024-11-10 04:21:21 +00:00
if ( listOfAccounts ! = null & & listOfAccounts . size ( ) > 0 ) {
for ( int i = 0 ; i < listOfAccounts . size ( ) ; i + + ) {
accountsFromUser . add ( accounts . accountsList . get ( listOfAccounts . get ( i ) ) ) ;
}
}
return accountsFromUser ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn GetBankBalance
///
/// @return The banks balance
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public Integer GetBankBalance ( ) {
return bankMoney ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn AddBankBalance
///
/// @param[in] amount Amount to add to the banks balance
///
/// @brief Adds to the banks balance
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public void AddBankBalance ( Integer amount ) {
bankMoney + = amount ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn SubtractBankBalance
///
/// @param[in] amount Amount to subtract from banks balance
///
/// @brief Subtracts from the banks balance
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public void SubtractBankBalance ( Integer amount ) {
bankMoney - = amount ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn SetBankBalance
///
/// @param[in] amount Amount to give the bank
///
/// @brief Set the banks balance
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public void SetBankBalance ( Integer amount ) {
bankMoney = amount ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn IsBankInsured
///
/// @return True if bank is insured, false if not
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public Boolean IsBankInsured ( ) {
return kbicInsured ;
}
2024-11-07 01:01:41 +00:00
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn InsuranceAmount
///
/// @brief Get the insurance amount at this bank
///
/// @return Insurance amount
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public Integer InsuranceAmount ( ) {
Integer insuredAmnt = 0 ;
if ( kbicInsured ) {
insuredAmnt = kbicInsuredAmount ;
} else {
insuredAmnt = 0 ;
}
return insuredAmnt ;
2024-11-05 00:45:28 +00:00
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn UpdateBankAccounts
///
/// @brief Flashes bank account information to disk; updates volatile
/// memory of banking information for this bank
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public void UpdateBankAccounts ( String newHolderName , String newHolderUuid , String accountIdentifier , IndividualAccount newAccountOnly ) {
2024-11-07 01:01:41 +00:00
// Update the fast-access map first
2024-11-17 03:56:52 +00:00
System . out . println ( " UpdateBankAccounts called with information " + newHolderName + " " + newHolderUuid + " " + accountIdentifier ) ;
if ( accounts . accountsListFromName . containsKey ( newHolderUuid ) ) {
2024-11-07 01:01:41 +00:00
// Check if user is already in map
2024-11-10 04:21:21 +00:00
accounts . accountsListFromName . get ( newHolderUuid ) . add ( accountIdentifier ) ;
2024-11-07 01:01:41 +00:00
} else {
// Add new entry to map
2024-11-17 03:56:52 +00:00
List < String > userAccountList = new ArrayList < String > ( ) ; // Lists are immutable; must make ArrayList
userAccountList . add ( accountIdentifier ) ;
accounts . accountsListFromName . put ( newHolderUuid , userAccountList ) ;
2024-11-07 01:01:41 +00:00
}
// Update regular account list
2024-11-10 04:21:21 +00:00
if ( accounts . accountsList . containsKey ( accountIdentifier ) ) {
2024-11-07 01:01:41 +00:00
// This path assumes we are adding a holder as opposed to adding an account (else, how else would this work?)
2024-11-10 04:21:21 +00:00
System . out . println ( " Account found in accounts list, adding this person as a holder instead " ) ;
accounts . accountsList . get ( accountIdentifier ) . AddAccountHolder ( newHolderName , newHolderUuid ) ;
2024-11-07 01:01:41 +00:00
} else {
// Non-existent account means a new one!
2024-11-10 04:21:21 +00:00
System . out . println ( " Brand new account creation, adding! " ) ;
accounts . accountsList . put ( accountIdentifier , newAccountOnly ) ;
2024-11-07 01:01:41 +00:00
numberOfAccounts + + ;
}
2024-11-10 04:21:21 +00:00
System . out . println ( " Flashing configuration file " ) ;
FlashConfig ( " bank/ " + routingNumber + " /accounts " ) ;
2024-11-07 01:01:41 +00:00
}
2024-11-05 00:45:28 +00:00
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn GetRoutingNumber
///
/// @return Routing number
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public Integer GetRoutingNumber ( ) {
return this . routingNumber ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-14 01:56:20 +00:00
public void AddMoneyToAccount ( String accountId , Integer amount ) {
IndividualAccount account = accounts . accountsList . get ( accountId ) ;
2024-11-17 03:56:52 +00:00
System . out . println ( " Received account # " + accountId + " and money amnt " + amount ) ;
2024-11-14 01:56:20 +00:00
if ( account ! = null ) {
account . Deposit ( amount ) ;
2024-12-06 07:04:09 +00:00
FlashConfig ( " bank/ " + routingNumber + " /accounts " ) ;
2024-11-14 01:56:20 +00:00
}
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-14 01:56:20 +00:00
public void SubtractMoneyFromAccount ( String accountId , Integer amount ) {
IndividualAccount account = accounts . accountsList . get ( accountId ) ;
2024-11-17 03:56:52 +00:00
for ( Entry < String , IndividualAccount > debug : accounts . accountsList . entrySet ( ) ) {
System . out . println ( " ACCOUNT ID: " + debug . getKey ( ) ) ;
System . out . println ( " ACCOUNT NUM: " + debug . getValue ( ) . GetAccountNumber ( ) ) ;
}
2024-11-14 01:56:20 +00:00
if ( account ! = null ) {
account . Withdraw ( amount ) ;
2024-12-06 07:04:09 +00:00
FlashConfig ( " bank/ " + routingNumber + " /accounts " ) ;
2024-11-14 01:56:20 +00:00
}
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-14 01:56:20 +00:00
public void SetMoneyOnAccount ( String accountId , Integer amount ) {
IndividualAccount account = accounts . accountsList . get ( accountId ) ;
2024-11-17 03:56:52 +00:00
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 ( ) ) ;
}
2024-11-14 01:56:20 +00:00
if ( account ! = null ) {
account . SetMoney ( amount ) ;
2024-12-06 07:04:09 +00:00
FlashConfig ( " bank/ " + routingNumber + " /accounts " ) ;
2024-11-14 01:56:20 +00:00
}
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public Boolean CreateAccount ( String holderUuid , String holderName , String accountTypeStr ) {
2024-11-05 00:45:28 +00:00
Boolean success = false ;
2024-11-10 04:21:21 +00:00
System . out . println ( " Attempting to create new bank account given args UUID / NAME / TYPE : " + holderUuid + " " + holderName + " " + accountTypeStr ) ;
System . out . println ( " accounts size is " + accounts . accountsList . size ( ) ) ;
System . out . println ( " account string is { " + accountTypeStr + " }. Does this account type exist in this bank? => " + ACCOUNT_TYPES . containsKey ( accountTypeStr . toLowerCase ( ) ) ) ;
if ( accounts . accountsList . size ( ) < = maxBankAccounts & & ACCOUNT_TYPES . containsKey ( accountTypeStr . toLowerCase ( ) ) ) {
2024-11-07 01:01:41 +00:00
// Verify this isn't a blacklisted user
2024-11-10 04:21:21 +00:00
System . out . println ( " Is user bank locked? " + lockedUsers . contains ( holderName ) ) ;
2024-11-07 01:01:41 +00:00
if ( ! lockedUsers . contains ( holderName ) ) {
2024-11-10 04:21:21 +00:00
Integer maxAttempts = 15 ; // Reasonably a unique bank account should pop up within 1000 generations. If not, the user may try again.
2024-11-07 01:01:41 +00:00
String accountId = AccountNumberGenerator . GenerateNewAccountNumber ( bankFourLetterIdentifier , routingNumber , ACCOUNT_TYPES . get ( accountTypeStr ) , holderName ) ;
2024-11-05 00:45:28 +00:00
2024-11-10 04:21:21 +00:00
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 ) ) ;
2024-11-07 01:01:41 +00:00
// 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!
2024-11-10 04:21:21 +00:00
while ( maxAttempts ! = 0 & & ! accounts . accountsList . containsKey ( AccountNumberGenerator . GetAccountNumberFromId ( accountId ) ) ) {
2024-11-07 01:01:41 +00:00
accountId = AccountNumberGenerator . GenerateNewAccountNumber ( bankFourLetterIdentifier , routingNumber , ACCOUNT_TYPES . get ( accountTypeStr ) , holderName ) ;
2024-11-10 04:21:21 +00:00
System . out . println ( " Account generator came back with bank account id { " + accountId + " } " ) ;
2024-11-07 01:01:41 +00:00
maxAttempts - - ;
}
2024-11-05 00:45:28 +00:00
2024-11-07 01:01:41 +00:00
// Final check to add the account
2024-11-10 04:21:21 +00:00
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 ,
2024-11-10 06:01:44 +00:00
" " , ACCOUNT_TYPES . get ( accountTypeStr ) , bankFourLetterIdentifier ) ;
2024-11-10 04:21:21 +00:00
System . out . println ( " Updating accounts list for this bank " ) ;
UpdateBankAccounts ( holderName , holderUuid , actualAccountNumber , newAccount ) ;
2024-11-07 01:01:41 +00:00
success = true ;
}
}
2024-11-05 00:45:28 +00:00
}
2024-11-07 01:01:41 +00:00
return success ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn AliasAccount
///
/// @param[in] accountId to alias
///
/// @param[in] newAlias is name to give this account
///
/// @brief Alias an account
/////////////////////////////////////////////////////////////////////////////
2024-11-07 01:01:41 +00:00
public void AliasAccount ( String accountId , String newAlias ) {
2024-11-10 04:21:21 +00:00
String accountNumber = AccountNumberGenerator . GetAccountNumberFromId ( accountId ) ;
if ( accounts . accountsList . containsKey ( accountNumber ) ) {
accounts . accountsList . get ( accountNumber ) . AliasAccount ( newAlias ) ;
2024-11-07 01:01:41 +00:00
}
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-07 01:01:41 +00:00
public Boolean LockAccountHolder ( String holderName ) {
Boolean success = false ;
2024-11-05 00:45:28 +00:00
2024-11-07 01:01:41 +00:00
Integer accountIter = 0 ;
2024-11-10 04:21:21 +00:00
for ( Entry < String , List < String > > holderAccounts : accounts . accountsListFromName . entrySet ( ) ) {
accounts . accountsList . get ( holderAccounts . getValue ( ) . get ( accountIter + + ) ) . LockAccount ( ) ;
2024-11-07 01:01:41 +00:00
}
return success ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-07 01:01:41 +00:00
public Boolean CloseAccount ( String accountId ) {
Boolean success = false ;
2024-11-10 04:21:21 +00:00
String accountNumber = AccountNumberGenerator . GetAccountNumberFromId ( accountId ) ;
2024-11-07 01:01:41 +00:00
2024-11-10 04:21:21 +00:00
if ( accounts . accountsList . get ( accountNumber ) . GetAccountBalance ( ) = = 0 ) {
accounts . accountsList . remove ( accountNumber ) ;
2024-11-07 01:01:41 +00:00
success = true ;
}
2024-11-05 00:45:28 +00:00
return success ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-10 04:21:21 +00:00
public Boolean HasAccount ( String accountIdentifier ) {
2024-11-05 00:45:28 +00:00
Boolean containsAccount = false ;
2024-11-10 04:21:21 +00:00
if ( accounts . accountsList . containsKey ( accountIdentifier ) ) {
2024-11-05 00:45:28 +00:00
containsAccount = true ;
}
2024-11-07 01:01:41 +00:00
return containsAccount ;
2024-11-05 00:45:28 +00:00
}
2024-11-10 04:21:21 +00:00
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-24 03:06:00 +00:00
public Boolean IsValidWithdrawal ( Integer withdrawalAmount , String accountIdentifier ) {
Boolean isValid = false ;
if ( accounts . accountsList . containsKey ( accountIdentifier ) ) {
IndividualAccount account = accounts . accountsList . get ( accountIdentifier ) ;
if ( account . CanWithdraw ( withdrawalAmount ) ) {
isValid = true ;
}
}
return isValid ;
}
2024-12-06 07:04:09 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @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
/////////////////////////////////////////////////////////////////////////////
2024-11-24 03:06:00 +00:00
public Boolean IsAccountHolder ( String accountIdentifier , String uuid ) {
Boolean isHolder = false ;
// Verify account exists first
if ( accounts . accountsList . containsKey ( accountIdentifier ) ) {
isHolder = accounts . accountsList . get ( accountIdentifier ) . IsHolder ( uuid ) ;
}
return isHolder ;
}
2024-11-10 04:21:21 +00:00
/////////////////////////////////////////////////////////////////////////////
/// @fn FlashConfig
///
2024-12-06 07:04:09 +00:00
/// @param[in] dirName is config to flash to. Banking is not trivial and will
/// require separate files to be updated at different locations!
///
2024-11-10 04:21:21 +00:00
/// @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 ( ) ) {
// 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 " ) ;
if ( file . exists ( ) ) {
file . delete ( ) ;
}
// Re-flash file
2025-01-02 03:47:50 +00:00
config . WriteToJsonFile ( dirName + " / " + accountNum + " .json " , singleAccount . getValue ( ) ) ;
2024-11-10 04:21:21 +00:00
}
}
2024-11-07 01:01:41 +00:00
}