[BANKING] Some tested code that finally works for banking stuff. Much to go still, but more honed in. So much to do :(
Some checks are pending
build / build (21) (push) Waiting to run

This commit is contained in:
Jkibbels 2024-11-09 23:21:21 -05:00
parent 87afc5c8ab
commit a42d196c3c
7 changed files with 429 additions and 268 deletions

View File

@ -28,16 +28,24 @@ public class AccountNumberGenerator {
// Callers of this function are required to verify the given number is unique. // Callers of this function are required to verify the given number is unique.
public static String GenerateNewAccountNumber(String symbol, Integer routingNumber, Integer accountType, String username) { public static String GenerateNewAccountNumber(String symbol, Integer routingNumber, Integer accountType, String username) {
String generatedAccountNumber = symbol + "-" + routingNumber + "-" + accountType + "-"; String generatedAccountNumber = symbol + "-" + routingNumber + "-" + accountType;
// Block to translate part of username into number format // Block to translate part of username into number format
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
if (username.length() >= 3 && username.charAt(i) <= 255) { // 255 is largest ASCII value. Might be a sloppy check; can always test later (if I find someone with non ASCII) if (username.length() >= 3 && username.charAt(i) <= 255) { // 255 is largest ASCII value. Might be a sloppy check; can always test later (if I find someone with non ASCII)
generatedAccountNumber += (int) username.charAt(i); Integer asciiValueOfLetter = (int) username.charAt(i);
String strValueOfAscii = asciiValueOfLetter.toString();
strValueOfAscii = strValueOfAscii.substring(0, 1);
generatedAccountNumber += strValueOfAscii;
} else if (username.charAt(i) <= 255) { // Case where length is less than 3 but is still in ASCII table } else if (username.charAt(i) <= 255) { // Case where length is less than 3 but is still in ASCII table
generatedAccountNumber += (int) username.charAt(i); Integer asciiValueOfLetter = (int) username.charAt(i);
String strValueOfAscii = asciiValueOfLetter.toString();
strValueOfAscii = strValueOfAscii.substring(0, 1);
generatedAccountNumber += strValueOfAscii;
} else { // Case where the length is less than 3 and is not standard ASCII } else { // Case where the length is less than 3 and is not standard ASCII
generatedAccountNumber += '0'; generatedAccountNumber += "0";
} }
} }
@ -59,11 +67,11 @@ public class AccountNumberGenerator {
return Integer.parseInt(accountId.substring(5, 9)); return Integer.parseInt(accountId.substring(5, 9));
} }
public static Integer GetAccountNumberFromId(String accountId) { public static String GetAccountNumberFromId(String accountId) {
return Integer.parseInt(accountId.substring(10, accountId.length())); return accountId.substring(10);
} }
public static Integer GetAccountTypeFromId(String accountId) { public static Integer GetAccountTypeFromId(String accountId) {
return (int) accountId.charAt(10); return ((int) accountId.charAt(10)) - 48; // ASCII 0 starts at 48. One must subtract 48 to be correct.
} }
} }

View File

@ -1,30 +1,110 @@
package jesse.keeblarcraft.BankMgr; package jesse.keeblarcraft.BankMgr;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Map.Entry;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; 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. // 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 // 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 (TODO for this). // when they log in to avoid constant look-ups through JSON.
// public final class BankManager {
public class BankManager { private static BankManager static_inst;
public static BankManager GetInstance() {
if (static_inst == null) {
static_inst = new BankManager();
}
return static_inst;
}
private static Integer KEEBLARCRAFT_SERVER_BANK_ID = 1000;
ConfigManager config = new ConfigManager(); ConfigManager config = new ConfigManager();
private HashMap<Integer, IndividualBank> banks = new HashMap<Integer, IndividualBank>();
private HashMap<String, Integer> bankNameFastMap = new HashMap<String, Integer>();
// Contains all account information for a given bank public BankManager() {}
private class BankAccountInformation {
} public void InitializeBanks() {
banks.put(KEEBLARCRAFT_SERVER_BANK_ID, new IndividualBank(Integer.toString(KEEBLARCRAFT_SERVER_BANK_ID), "KeeblarcraftGlobal"));
// Structure of all the players banking information across all banks.
private class PlayerFinances {
// Key = Bank UUID
// Value = The account information for THIS player
HashMap<String, BankAccountInformation> allBanks;
}
public BankManager() {
// Initialize fast map
for (Entry<Integer, IndividualBank> bank : banks.entrySet()) {
bankNameFastMap.put(bank.getValue().GetBankName(), bank.getValue().GetRoutingNumber());
}
}
public List<String> GetAllBankNames() {
List<String> names = new ArrayList<String>();
// Iterate through all banks in the list to get their names
for (Entry<Integer, IndividualBank> bank : banks.entrySet()) {
names.add(bank.getValue().GetBankName());
}
return names;
}
public IndividualBank GetBankByRoutingNumber(Integer number) {
IndividualBank bank = null;
if (banks.containsKey(number)) {
bank = banks.get(number);
}
return bank;
}
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;
}
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.getDisplayName().getString());
// 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.getDisplayName().getString(), 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.getDisplayName().getString(), 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!"));
}
} }
} }

View File

@ -6,32 +6,44 @@ import java.util.List;
// TODO: Add ability to store NBT data of items in the future so we can store not just money but items too // TODO: Add ability to store NBT data of items in the future so we can store not just money but items too
// like a safety deposit box // like a safety deposit box
public class IndividualAccount { public class IndividualAccount {
private Integer accountNumber; private String accountNumber;
private String accountNumberAlias; private String accountNumberAlias;
private Integer routingNumber; // Will always be the bank it's in private Integer routingNumber; // Will always be the bank it's in
private List<String> accountHolders; private List<String> accountHolders;
private List<String> accountHolderUuids;
private Integer accountBalance; private Integer accountBalance;
private Boolean allowNegativeBalance; private Boolean allowNegativeBalance;
private Boolean accountLocked; private Boolean accountLocked;
private String accountType; // TODO: Replace with enum in future. Valid is "checking" and "savings" right now private Integer accountType; // TODO: Replace with enum in future. Valid is "checking" and "savings" right now
public IndividualAccount() {} public IndividualAccount() {}
public IndividualAccount(Integer accountNumber, Integer routingNumber, List<String> holders, public IndividualAccount(String accountNumber, Integer routingNumber, List<String> holders,
Boolean allowNegativeBalance, Integer initialBalance, String alias) { List<String> accountHolderUuids, Boolean allowNegativeBalance, Integer initialBalance,
String alias, Integer accountType) {
System.out.println("Called to create new IndividualAccount with following values: " + accountNumber + " " + routingNumber + " " + holders + " " +
accountHolderUuids + " " + allowNegativeBalance + " " + initialBalance + " " + alias + " " + accountType);
this.accountNumber = accountNumber; this.accountNumber = accountNumber;
this.routingNumber = routingNumber; this.routingNumber = routingNumber;
this.accountHolders = holders; this.accountHolders = holders;
this.accountHolderUuids = accountHolderUuids;
this.allowNegativeBalance = allowNegativeBalance; this.allowNegativeBalance = allowNegativeBalance;
this.accountBalance = initialBalance; this.accountBalance = initialBalance;
this.accountNumberAlias = alias; this.accountNumberAlias = alias;
this.accountType = accountType;
} }
public void AddAccountHolder(String newHolder) { // TODO: Make this a map in the future
public void AddAccountHolder(String newHolder, String newHolderUuid) {
if (!accountHolders.contains(newHolder)) { if (!accountHolders.contains(newHolder)) {
accountHolders.add(newHolder); accountHolders.add(newHolder);
} }
if (!accountHolderUuids.contains(newHolderUuid)) {
accountHolderUuids.add(newHolderUuid);
}
} }
public void AliasAccount(String newAlias) { public void AliasAccount(String newAlias) {
@ -106,7 +118,7 @@ public class IndividualAccount {
return accountBalance; return accountBalance;
} }
public Integer GetAccountNumber() { public String GetAccountNumber() {
return accountNumber; return accountNumber;
} }

View File

@ -1,12 +1,19 @@
package jesse.keeblarcraft.BankMgr; package jesse.keeblarcraft.BankMgr;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import static java.util.Map.entry; import static java.util.Map.entry;
import java.io.File;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION;
// Contains the information of an individual bank // Contains the information of an individual bank
// //
@ -18,12 +25,12 @@ public class IndividualBank {
entry("savings", 1) entry("savings", 1)
); );
private ConfigManager config = new ConfigManager();
ConfigManager config = new ConfigManager();
private Integer routingNumber; // this is the banks unique identifier 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 numberOfAccounts; // Total number of accounts the bank has. This includes only active accounts inside accountsList.
private String bankFourLetterIdentifier;
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 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;
// Think FDIC but from the servers account (keeblarcraft insurance corporation) // 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. // KBIC will ensure an amount of money based on its trustworthiness to a bank and the number of holders it has.
@ -37,87 +44,207 @@ public class IndividualBank {
// Key = ACCOUNT NUMBER // Key = ACCOUNT NUMBER
// Value = ACCOUNT // Value = ACCOUNT
private HashMap<Integer, IndividualAccount> accountsList; private class Accounts {
private HashMap<String, List<Integer>> accountsListFromName; // This is a list that just points to a list of account numbers by person. USEFUL private HashMap<String, IndividualAccount> accountsList = new HashMap<String, IndividualAccount>();
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 private List<String> lockedUsers; // A list of users who are locked out of the bank and are incapable of performing more actions within it
public IndividualBank(String routingNumber) { public IndividualBank(String routingNumber, String nameOfBank) {
accountsList = new HashMap<Integer, IndividualAccount>(); accounts = new Accounts();
accountsListFromName = new HashMap<String, List<Integer>>(); lockedUsers = new ArrayList<String>();
registeredBankName = nameOfBank.toUpperCase();
// READ IN BANK CONFIG 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 = "bank/" + routingNumber.toString() + "/accounts/";
System.out.println("accountsListDir + bankName is " + accountsListDir + nameOfBank);
accounts = config.GetJsonObjectFromFile(accountsListDir + nameOfBank, Accounts.class);
existingFile = true;
// 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 (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)
{
System.out.println(ChatUtil.ColoredString("Trying to create new file", CONSOLE_COLOR.BLUE));
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("bank/" + routingNumber + "/accounts");
// Flash initial account configuration file for this bank
FlashConfig("accounts");
} catch (Exception e) {
System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED));
}
} else {
System.out.println(ChatUtil.ColoredString("Moving on", CONSOLE_COLOR.BLUE));
}
// 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 // 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. // '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 // 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 // or gets put on one to update the map every time
for (Entry<Integer, IndividualAccount> account : accountsList.entrySet()) { 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 // 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(); List<String> accountHolders = account.getValue().GetAccountHolders();
// Match each user to the secondary map & add to list-value if not existing // Match each user to the secondary map & add to list-value if not existing
for (Integer holderIndex = 0; holderIndex < accountHolders.size(); holderIndex++) { for (Integer holderIndex = 0; holderIndex < accountHolders.size(); holderIndex++) {
if (accountsListFromName.containsKey(accountHolders.get(holderIndex))) { if (accounts.accountsListFromName.containsKey(accountHolders.get(holderIndex))) {
// Case 1: User exists, update map entry // Case 1: User exists, update map entry
accountsListFromName.get(accountHolders.get(holderIndex)).add(account.getKey()); // Add a new account id to this person in the new flat map accounts.accountsListFromName.get(accountHolders.get(holderIndex)).add(account.getKey()); // Add a new account id to this person in the new flat map
} else { } else {
// Case 2: User does not already exist; add a new map entry // Case 2: User does not already exist; add a new map entry
accountsListFromName.put(accountHolders.get(holderIndex), List.of(account.getKey())); // Store name as key, and new List with the value of ACCOUNT # accounts.accountsListFromName.put(accountHolders.get(holderIndex), List.of(account.getKey())); // Store name as key, and new List with the value of ACCOUNT #
} }
} }
} }
numberOfAccounts = accounts.accountsList.size();
}
numberOfAccounts = accountsList.size(); public String GetBankName() {
return registeredBankName;
}
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);
System.out.println("Is list of accounts null? " + listOfAccounts == null);
if (listOfAccounts != null && listOfAccounts.size() > 0) {
for (int i = 0; i < listOfAccounts.size(); i++) {
accountsFromUser.add(accounts.accountsList.get(listOfAccounts.get(i)));
}
}
return accountsFromUser;
}
public Integer GetBankBalance() {
return bankMoney;
}
public void AddBankBalance(Integer amount) {
bankMoney += amount;
}
public void SubtractBankBalance(Integer amount) {
bankMoney -= amount;
}
public void SetBankBalance(Integer amount) {
bankMoney = amount;
}
public Boolean IsBankInsured() {
return kbicInsured;
}
public Integer InsuranceAmount() {
Integer insuredAmnt = 0;
if (kbicInsured) {
insuredAmnt = kbicInsuredAmount;
} else {
insuredAmnt = 0;
}
return insuredAmnt;
} }
// Updates the regular bank account list & the fast-access bank account list // Updates the regular bank account list & the fast-access bank account list
// NO values are allowed to be null. Manually update lists separately if that's the behaviour you want! // NO values are allowed to be null. Manually update lists separately if that's the behaviour you want!
public void UpdateBankAccounts(String newHolderName, Integer accountIdentifier, IndividualAccount newAccountOnly) { public void UpdateBankAccounts(String newHolderName, String newHolderUuid, String accountIdentifier, IndividualAccount newAccountOnly) {
// Update the fast-access map first // Update the fast-access map first
if (accountsListFromName.containsKey(newHolderName)) { if (accounts.accountsListFromName.containsKey(newHolderName)) {
// Check if user is already in map // Check if user is already in map
accountsListFromName.get(newHolderName).add(accountIdentifier); System.out.println("User found in fast access map. Adding account identifier to fast-access map");
accounts.accountsListFromName.get(newHolderUuid).add(accountIdentifier);
} else { } else {
// Add new entry to map // Add new entry to map
accountsListFromName.put(newHolderName, List.of(accountIdentifier)); System.out.println("User not found in fast access map. Adding completely new entry");
accounts.accountsListFromName.put(newHolderUuid, List.of(accountIdentifier));
} }
// Update regular account list // Update regular account list
if (accountsList.containsKey(accountIdentifier)) { 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?) // This path assumes we are adding a holder as opposed to adding an account (else, how else would this work?)
accountsList.get(accountIdentifier).AddAccountHolder(newHolderName); System.out.println("Account found in accounts list, adding this person as a holder instead");
accounts.accountsList.get(accountIdentifier).AddAccountHolder(newHolderName, newHolderUuid);
} else { } else {
// Non-existent account means a new one! // Non-existent account means a new one!
accountsList.put(accountIdentifier, newAccountOnly); System.out.println("Brand new account creation, adding!");
accounts.accountsList.put(accountIdentifier, newAccountOnly);
numberOfAccounts++; numberOfAccounts++;
} }
System.out.println("Flashing configuration file");
FlashConfig("bank/" + routingNumber + "/accounts");
} }
public Boolean CreateAccount(String holderName, String accountTypeStr) { public Integer GetRoutingNumber() {
return this.routingNumber;
}
public Boolean CreateAccount(String holderUuid, String holderName, String accountTypeStr) {
Boolean success = false; Boolean success = false;
if (accountsList.size() <= maxBankAccounts && ACCOUNT_TYPES.containsKey(accountTypeStr.toLowerCase())) { 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())) {
// Verify this isn't a blacklisted user // Verify this isn't a blacklisted user
System.out.println("Is user bank locked? " + lockedUsers.contains(holderName));
if (!lockedUsers.contains(holderName)) { if (!lockedUsers.contains(holderName)) {
Integer maxAttempts = 1000; // Reasonably a unique bank account should pop up within 1000 generations. If not, the user may try again. 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(accountTypeStr), holderName); String accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountTypeStr), 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 // 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! // entire life time of the server. BUT, you never know!
while (maxAttempts != 0 && !accountsList.containsKey(AccountNumberGenerator.GetAccountNumberFromId(accountId))) { while (maxAttempts != 0 && !accounts.accountsList.containsKey(AccountNumberGenerator.GetAccountNumberFromId(accountId))) {
accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountTypeStr), holderName); accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountTypeStr), holderName);
System.out.println("Account generator came back with bank account id { " + accountId + " }");
maxAttempts--; maxAttempts--;
} }
// Final check to add the account // Final check to add the account
Integer actualAccountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId); String actualAccountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
if (!accountsList.containsKey(actualAccountNumber)) { System.out.println("Bank account identifier is { " + actualAccountNumber + " }. Is this already an existing account? " + accounts.accountsList.containsKey(actualAccountNumber));
IndividualAccount newAccount = new IndividualAccount(actualAccountNumber, this.routingNumber, List.of(holderName), false, 0, ""); if (!accounts.accountsList.containsKey(actualAccountNumber)) {
UpdateBankAccounts(holderName, actualAccountNumber, newAccount); IndividualAccount newAccount = new IndividualAccount(actualAccountNumber, this.routingNumber, List.of(holderName),
List.of(holderUuid), false, 0,
"", ACCOUNT_TYPES.get(accountTypeStr));
System.out.println("Updating accounts list for this bank");
UpdateBankAccounts(holderName, holderUuid, actualAccountNumber, newAccount);
success = true; success = true;
} }
} }
@ -126,9 +253,9 @@ public class IndividualBank {
} }
public void AliasAccount(String accountId, String newAlias) { public void AliasAccount(String accountId, String newAlias) {
Integer accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId); String accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
if (accountsList.containsKey(accountNumber)) { if (accounts.accountsList.containsKey(accountNumber)) {
accountsList.get(accountNumber).AliasAccount(newAlias); accounts.accountsList.get(accountNumber).AliasAccount(newAlias);
} }
} }
@ -136,8 +263,8 @@ public class IndividualBank {
Boolean success = false; Boolean success = false;
Integer accountIter = 0; Integer accountIter = 0;
for (Entry<String, List<Integer>> holderAccounts : accountsListFromName.entrySet()) { for (Entry<String, List<String>> holderAccounts : accounts.accountsListFromName.entrySet()) {
accountsList.get(holderAccounts.getValue().get(accountIter++)).LockAccount(); accounts.accountsList.get(holderAccounts.getValue().get(accountIter++)).LockAccount();
} }
return success; return success;
} }
@ -145,20 +272,53 @@ public class IndividualBank {
public Boolean CloseAccount(String accountId) { public Boolean CloseAccount(String accountId) {
Boolean success = false; Boolean success = false;
Integer accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId); String accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
if (accountsList.get(accountNumber).GetAccountBalance() == 0) { if (accounts.accountsList.get(accountNumber).GetAccountBalance() == 0) {
accountsList.remove(accountNumber); accounts.accountsList.remove(accountNumber);
success = true; success = true;
} }
return success; return success;
} }
public Boolean HasAccount(Integer accountIdentifier) { public Boolean HasAccount(String accountIdentifier) {
Boolean containsAccount = false; Boolean containsAccount = false;
if (accountsList.containsKey(accountIdentifier)) { if (accounts.accountsList.containsKey(accountIdentifier)) {
containsAccount = true; containsAccount = true;
} }
return containsAccount; return containsAccount;
} }
/////////////////////////////////////////////////////////////////////////////
/// @fn FlashConfig
///
/// @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
try {
config.WriteToJsonFile(dirName + "/" + accountNum + ".json", singleAccount.getValue());
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println("Failed to flash configuration file properly. Printing stack trace");
e.printStackTrace();
}
}
}
} }

View File

@ -1,15 +1,17 @@
package jesse.keeblarcraft.Commands; package jesse.keeblarcraft.Commands;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.LongArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import static java.util.Map.entry; import static java.util.Map.entry;
import jesse.keeblarcraft.BankMgr.BankManager; import jesse.keeblarcraft.BankMgr.BankManager;
import jesse.keeblarcraft.BankMgr.IndividualAccount;
import jesse.keeblarcraft.BankMgr.IndividualBank;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
@ -84,91 +86,19 @@ public class BankCommands {
// is just /bank ACTION-WORD [arguments...] [optionals] // is just /bank ACTION-WORD [arguments...] [optionals]
var bankRoot = CommandManager.literal("bank").build(); var bankRoot = CommandManager.literal("bank").build();
var actionWord = CommandManager.argument("ACTION_WORD", StringArgumentType.greedyString()).build(); // Removing "argList" and just running the entire list as an argList from actionWord makes `/bank help` possible
var argList = CommandManager.argument("ARG_LIST", StringArgumentType.greedyString()) var argList = CommandManager.argument("ARG_LIST", StringArgumentType.greedyString())
.executes(context -> ParseBankCommand .executes(context -> ParseBankCommand
( (
context, context,
StringArgumentType.getString(context, "ACTION_WORD"),
StringArgumentType.getString(context, "ARG_LIST")) StringArgumentType.getString(context, "ARG_LIST"))
) )
.build(); .build();
// Building the argument tree here // Building the argument tree here
dispatcher.getRoot().addChild(bankRoot); dispatcher.getRoot().addChild(bankRoot);
bankRoot.addChild(actionWord);
bankRoot.addChild(argList); bankRoot.addChild(argList);
// Aliases
dispatcher.register(CommandManager.literal("wire").redirect(actionWord));
dispatcher.register(CommandManager.literal("balance").redirect(actionWord));
}); });
// Command: "/getbalance"
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
// dispatcher.register(CommandManager.literal("getbalance")
// .executes(context -> GetBalance(context)));
// });
// // Command: "/setbalance || rootSetBalance"
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
// final var rootSetBalance = dispatcher.register(CommandManager.literal("setbalance")
// .then(CommandManager.argument("newBalance", IntegerArgumentType.integer())
// .then(CommandManager.argument("reason", StringArgumentType.string())
// .then(CommandManager.argument("otherParty", StringArgumentType.string())
// .executes(context -> SetBalance(
// IntegerArgumentType.getInteger(context, "newBalance"),
// StringArgumentType.getString(context, "reason"),
// StringArgumentType.getString(context, "otherParty"),
// context))))));
// dispatcher.register(CommandManager.literal("setbalance").redirect(rootSetBalance));
// });
// // Command: "/AddMoney"
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
// dispatcher.register(CommandManager.literal("AddMoney")
// .then(CommandManager.argument("reason", StringArgumentType.string())
// .then(CommandManager.argument("payment", LongArgumentType.longArg())
// .then(CommandManager.argument("otherParty", StringArgumentType.string())
// .executes(context -> AddMoney(
// StringArgumentType.getString(context, "reason"),
// LongArgumentType.getLong(context, "payment"),
// StringArgumentType.getString(context, "otherParty"),
// context))))));
// });
// // Command: "/subtractbalance || /SubtractBalance"
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
// final var SubtractBalance = dispatcher.register(CommandManager.literal("subtractbalance")
// .then(CommandManager.argument("reason", StringArgumentType.string())
// .then(CommandManager.argument("payment", LongArgumentType.longArg())
// .then(CommandManager.argument("otherParty", StringArgumentType.string())
// .executes(context -> SubtractBalance(
// StringArgumentType.getString(context, "reason"),
// LongArgumentType.getLong(context, "payment"),
// StringArgumentType.getString(context, "otherParty"),
// context))))));
// dispatcher.register(CommandManager.literal("subtractbalance").redirect(SubtractBalance));
// });
// // Command: "/wire || /sendmoney"
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
// final var sendmoney = dispatcher.register(CommandManager.literal("wire")
// .then(CommandManager.argument("reason", StringArgumentType.string())
// .then(CommandManager.argument("payment", LongArgumentType.longArg())
// .then(CommandManager.argument("otherParty", StringArgumentType.string())
// .executes(context -> Wire(
// StringArgumentType.getString(context, "reason"),
// LongArgumentType.getLong(context, "payment"),
// StringArgumentType.getString(context, "otherParty"),
// context))))));
// dispatcher.register(CommandManager.literal("wire").redirect(sendmoney));
// });
} }
// Remove filler words which only exist for human readability // Remove filler words which only exist for human readability
@ -178,21 +108,28 @@ public class BankCommands {
if (FILLER_WORDS.contains(str)) { if (FILLER_WORDS.contains(str)) {
argList.remove(index); argList.remove(index);
} }
// Also make every word lower case
str = str.toLowerCase();
index++; index++;
} }
return argList; return argList;
} }
public int ParseBankCommand(CommandContext<ServerCommandSource> context, String actionWord, String unformattedArgList) { public int ParseBankCommand(CommandContext<ServerCommandSource> context, String unformattedArgList) {
// String[] formattedArgList = unformattedArgList.split("\\s+"); // REGEX is matching 1+ whitespace characters List<String> formattedArgList = List.of(unformattedArgList.split("\\s+")); // REGEX is matching 1+ whitespace characters
List<String> formattedArgList = List.of(unformattedArgList.split("\\s+")); System.out.println("After formatting the arg list, the size of arg list is size { " + formattedArgList.size() + " }");
formattedArgList = RemoveFillerWords(formattedArgList); formattedArgList = RemoveFillerWords(formattedArgList);
actionWord = actionWord.toLowerCase();
String actionWord = formattedArgList.get(0);
System.out.println("The action word for this operation is " + actionWord.toUpperCase());
System.out.println("Parsing bank command on action word { " + actionWord + " } with arg list { " + formattedArgList + " }");
switch(actionWord) switch(actionWord)
{ {
case "create": case "create":
CreateCommand(context.getSource().getPlayer(), formattedArgList); System.out.println("Calling create command...");
CreateCommand(context.getSource().getPlayer(), formattedArgList.subList(1, formattedArgList.size()));
break; break;
case "close": case "close":
CloseCommand(context.getSource().getPlayer(), formattedArgList); CloseCommand(context.getSource().getPlayer(), formattedArgList);
@ -207,7 +144,7 @@ public class BankCommands {
BalanceCommand(context.getSource().getPlayer(), formattedArgList); BalanceCommand(context.getSource().getPlayer(), formattedArgList);
break; break;
case "help": case "help":
HelpCommand(context.getSource().getPlayer(), "help"); HelpCommand(context.getSource().getPlayer(), formattedArgList);
break; break;
case "move": case "move":
MoveCommand(context.getSource().getPlayer(), formattedArgList); MoveCommand(context.getSource().getPlayer(), formattedArgList);
@ -219,10 +156,17 @@ public class BankCommands {
ReportCommand(context.getSource().getPlayer(), formattedArgList); ReportCommand(context.getSource().getPlayer(), formattedArgList);
break; break;
case "examples": case "examples":
HelpCommand(context.getSource().getPlayer(), "examples"); HelpCommand(context.getSource().getPlayer(), List.of("examples"));
break; break;
case "syntax": case "syntax":
HelpCommand(context.getSource().getPlayer(), "syntax"); HelpCommand(context.getSource().getPlayer(), List.of("syntax"));
break;
case "list":
ListAllBanks(context.getSource().getPlayer(), formattedArgList);
break;
case "account":
case "accounts":
ManageAccounts(context.getSource().getPlayer(), formattedArgList.subList(1, formattedArgList.size()));
break; break;
default: default:
if (context.getSource().isExecutedByPlayer()) { if (context.getSource().isExecutedByPlayer()) {
@ -234,7 +178,42 @@ public class BankCommands {
} }
// Possible code paths: // Possible code paths:
// REQUIRED (path 1) = {AMOUNT} [FROM:{INTERNAL ACCOUNT #|ALIAS}] TO:{INTERNAL ACCOUNT #|ALIAS} ***Note: TO{} can be assumed to be SELECTED default if not specified // REQUIRED = {Routing # or Bank name}
// OPTIONAL = []
public void ManageAccounts(ServerPlayerEntity sourcePlayer, List<String> argList) {
System.out.println("Manage accounts arg list is { " + argList + " }");
if (argList.size() > 0) {
// TODO: For now we assume they reference the bank name and not routing #
Boolean success = false;
String bankName = argList.get(0).toUpperCase();
IndividualBank bank = BankManager.GetInstance().GetBankByName(bankName);
System.out.println("Test print on memory");
Boolean isNull = bank == null;
System.out.println("isNull: " + isNull);
if (bank != null) {
System.out.println("Grabbing user account information");
List<IndividualAccount> userAccounts = bank.GetAccountsOfUser(sourcePlayer.getUuidAsString());
sourcePlayer.sendMessage(Text.of("------------[BANK INFO FOR " + bankName.toUpperCase() + "]------------"));
for (int i = 0; i < userAccounts.size(); i++) {
sourcePlayer.sendMessage(Text.of("ACCOUNT NUMBER: " + userAccounts.get(i).GetAccountNumber()));
sourcePlayer.sendMessage(Text.of("HOLDERS: " + userAccounts.get(i).GetAccountHolders()));
sourcePlayer.sendMessage(Text.of("BALANCE: " + userAccounts.get(i).GetAccountBalance()));
sourcePlayer.sendMessage(Text.of("\n"));
}
} else {
sourcePlayer.sendMessage(Text.of("That bank does not exist"));
}
} else {
sourcePlayer.sendMessage(Text.of("Unrecognized move command. Please use \"/bank help ACCOUNTS\" for more information."));
}
}
public void ListAllBanks(ServerPlayerEntity sourcePlayer, List<String> argList) {
sourcePlayer.sendMessage(Text.of("Here is a list of available banks on the server: " + BankManager.GetInstance().GetAllBankNames()));
}
// Possible code paths:
// REQUIRED (path 1) = {AMOUNT} [FROM:{INTERNAL ACCOUNT #|ALIAS}] TO:{INTERNAL ACCOUNT #|ALIAS} ***Note: can be assumed to be SELECTED default if not specified
// REQUIRED (path 2) = {INTERNAL ACCOUNT #|ALIAS} {EXTERNAL BANK/FACTION ID} // REQUIRED (path 2) = {INTERNAL ACCOUNT #|ALIAS} {EXTERNAL BANK/FACTION ID}
// OPTIONAL = [] // OPTIONAL = []
public void MoveCommand(ServerPlayerEntity sourcePlayer, List<String> argList) { public void MoveCommand(ServerPlayerEntity sourcePlayer, List<String> argList) {
@ -327,8 +306,12 @@ public class BankCommands {
// Create command - valid arg list types: // Create command - valid arg list types:
// /... CREATE {CA/checking/savings/checking-account/savings-account/report} // /... CREATE {CA/checking/savings/checking-account/savings-account/report}
public int CreateCommand(ServerPlayerEntity sourcePlayer, List<String> argList) { public int CreateCommand(ServerPlayerEntity sourcePlayer, List<String> argList) {
System.out.println("Attempting account creation given arg list { " + argList + " }.");
System.out.println("argList size is " + argList.size());
if (argList.size() > 0) { if (argList.size() > 0) {
String action = argList.get(0).toLowerCase(); String action = argList.get(0).toLowerCase();
System.out.println("action word is " + action);
switch (action) { switch (action) {
// Checking & Savings are handled in the same function so we can just "alias" all of these to the same call! // Checking & Savings are handled in the same function so we can just "alias" all of these to the same call!
@ -338,14 +321,15 @@ public class BankCommands {
case "sa": case "sa":
case "savings": case "savings":
case "savings-account": case "savings-account":
argList.remove(0); // Remove action word (all the above aliases) System.out.println("Creating account. Removing index 0 in argList. New argList is { " + argList + " }");
CreateAccount(sourcePlayer, argList); CreateAccount(sourcePlayer, argList);
break; break;
case "rep": case "rep":
case "report": case "report":
argList.remove(0); // Remove action word (all the above aliases)
GenerateAccountReport(sourcePlayer, argList); GenerateAccountReport(sourcePlayer, argList);
break; break;
default:
// Unrecognized creation type
} }
} else { } else {
sourcePlayer.sendMessage(Text.of("Unrecognized create command formed on bank. Please run \"/bank help CREATE\" for more information")); sourcePlayer.sendMessage(Text.of("Unrecognized create command formed on bank. Please run \"/bank help CREATE\" for more information"));
@ -415,7 +399,6 @@ public class BankCommands {
* *
* *
* CALL THROUGHS TO BANK MGR HERE * CALL THROUGHS TO BANK MGR HERE
* CALL THROUGHS TO BANK MGR HERE
* *
*/ */
} else { } else {
@ -427,22 +410,33 @@ public class BankCommands {
// Possible code paths: // Possible code paths:
// REQUIRED = {} // REQUIRED = {}
// OPTIONAL = [command|subcommand] // OPTIONAL = [command|subcommand]
public int HelpCommand(ServerPlayerEntity sourcePlayer, String helpCommand) { public int HelpCommand(ServerPlayerEntity sourcePlayer, List<String> helpCommand) {
if (helpCommand.length() > 0) { System.out.println("Running help command");
// Specific command help message // TODO: Make a prettier way of printing this to the player with color
if (helpCommand.size() == 0) {
/* // General help command
* for (Entry<String, String> helpCmd : HELP_COMMANDS.entrySet()) {
* A ChatUtil message needs to be created to better display messages to players. Once that is created; forward this string to that sourcePlayer.sendMessage(Text.of(helpCmd.getKey() + " --> " + helpCmd.getValue()));
* sourcePlayer.sendMessage(Text.of("\n"));
*/ }
} else { } else {
// General help message // Iterate over list; verifying what commands are found
/* List<String> unknownCmds = new ArrayList<String>();
* for (int i = 0; i < helpCommand.size(); i++) {
* A ChatUtil message needs to be created to better display messages to players. Once that is created; forward this string to that String newHelpCmd = helpCommand.get(i);
* if (HELP_COMMANDS.containsKey(newHelpCmd)) {
*/ // Print help for this specific command
sourcePlayer.sendMessage(Text.of(newHelpCmd + " -> " + HELP_COMMANDS.get(newHelpCmd)));
} else {
// Add to unknown list at end
unknownCmds.add(newHelpCmd);
}
}
// After all prints have finished tell the player the commands they plugged in that we did not recognize
if (unknownCmds.size() > 0) {
sourcePlayer.sendMessage(Text.of("The following commands do not exist or were mispelt: " + unknownCmds));
}
} }
return 0; return 0;
} }
@ -450,6 +444,7 @@ public class BankCommands {
// Possible args: // Possible args:
// /bank create {SAVINGS/CHECKING} [optional: alias] // /bank create {SAVINGS/CHECKING} [optional: alias]
public void CreateAccount(ServerPlayerEntity player, List<String> accountArgs) { public void CreateAccount(ServerPlayerEntity player, List<String> accountArgs) {
System.out.println("Attempting to create checking account with arg list { " + accountArgs + " }");
if (accountArgs.size() > 0) { if (accountArgs.size() > 0) {
String accountType = accountArgs.get(0); String accountType = accountArgs.get(0);
String accountAlias = "NO_ALIAS"; String accountAlias = "NO_ALIAS";
@ -459,12 +454,9 @@ public class BankCommands {
accountAlias = accountArgs.get(1).toLowerCase(); accountAlias = accountArgs.get(1).toLowerCase();
} }
/* System.out.println("ACCOUNT CREATION REQUESTED WITH TYPE " + accountType + " AND ALIAS " + accountAlias);
* // FIXME: This is just a patch at the moment to let players make bank accounts in server bank
* Finally - calls to BankManager here for more BankManager.GetInstance().InitiateBankAccountCreation(null, player, accountType);
*
*/
} else { } else {
player.sendMessage(Text.of("Unrecognized create account command. Please run /bank help create for more information")); player.sendMessage(Text.of("Unrecognized create account command. Please run /bank help create for more information"));
} }
@ -486,100 +478,4 @@ public class BankCommands {
player.sendMessage(Text.of("Unrecognized report field data. Please run /bank help report for more information")); player.sendMessage(Text.of("Unrecognized report field data. Please run /bank help report for more information"));
} }
} }
// public Integer GetBalance(CommandContext<ServerCommandSource> context) {
// Integer ret = -1;
// if (context.getSource().isExecutedByPlayer()) {
// ServerPlayerEntity player = context.getSource().getPlayer();
// BankManager playerBank = new BankManager(player.getUuidAsString());
// player.sendMessage(Text.literal(String.valueOf(playerBank.GetBalance())));
// return 0;
// }
// return ret;
// }
// //SetBalance will be a ServerCommand only Perm level Op
// public Integer SetBalance(Integer newBalance, String reason, String otherParty, CommandContext<ServerCommandSource> context) {
// Integer ret = -1;
// if (context.getSource().hasPermissionLevel(1)) {
// ServerPlayerEntity player = context.getSource().getPlayer();
// BankManager playerBank = new BankManager(player.getUuidAsString());
// playerBank.SetBalance(newBalance, reason, otherParty);
// player.sendMessage(Text.literal(String.valueOf(playerBank.GetBalance())));
// }
// return ret;
// }
// //AddMoney will be a ServerCommand Only Perm level Op
// public Integer AddMoney(String reason, long payment, String otherParty, CommandContext<ServerCommandSource> context) {
// Integer ret = -1;
// if (context.getSource().hasPermissionLevel(1)) {
// ret = 0;
// ServerPlayerEntity player = context.getSource().getPlayer();
// BankManager playerBank = new BankManager(player.getUuidAsString());
// playerBank.AddMoney(reason, payment, otherParty);
// player.sendMessage(Text.literal(String.valueOf(playerBank.GetBalance())));
// }
// return ret;
// }
// //SubtractBalance will be a ServerCommand Perm leve Op
// public Integer SubtractBalance(String reason, long payment, String otherParty, CommandContext<ServerCommandSource> context) {
// Integer ret = -1;
// if (context.getSource().hasPermissionLevel(1)) {
// ret = 0;
// ServerPlayerEntity player = context.getSource().getPlayer();
// BankManager playerBank = new BankManager(player.getUuidAsString());
// playerBank.SubtractBalance(reason, payment, otherParty);
// player.sendMessage(Text.literal(String.valueOf(playerBank.GetBalance())));
// }
// return ret;
// }
// public Integer Wire(String reason, long payment, String otherParty, CommandContext<ServerCommandSource> context) {
// Integer ret = -1;
// if (context.getSource().isExecutedByPlayer()) {
// ret = 0;
// ServerPlayerEntity player = context.getSource().getPlayer();
// BankManager playerBank = new BankManager(player.getUuidAsString());
// playerBank.Wire(reason, payment, otherParty);
// player.sendMessage(Text.literal(String.valueOf(playerBank.GetBalance())));
// }
// return ret;
// }
} }

View File

@ -182,6 +182,7 @@ public class ConfigManager {
Boolean ret = false; Boolean ret = false;
File dir = new File(dirName); File dir = new File(dirName);
System.out.println("Attempting to create dir with name " + dirName);
try { try {
if ( ! dir.exists()) { if ( ! dir.exists()) {

View File

@ -24,6 +24,7 @@ import org.slf4j.LoggerFactory;
import jesse.keeblarcraft.AttributeMgr.AttributeMgr; import jesse.keeblarcraft.AttributeMgr.AttributeMgr;
import jesse.keeblarcraft.AttributeMgr.AttributeTree; import jesse.keeblarcraft.AttributeMgr.AttributeTree;
import jesse.keeblarcraft.BankMgr.BankManager;
import jesse.keeblarcraft.Commands.CustomCommandManager; import jesse.keeblarcraft.Commands.CustomCommandManager;
import jesse.keeblarcraft.CustomBlocks.BlockList; import jesse.keeblarcraft.CustomBlocks.BlockList;
import jesse.keeblarcraft.CustomItems.ItemManager; import jesse.keeblarcraft.CustomItems.ItemManager;
@ -90,6 +91,9 @@ public class Keeblarcraft implements ModInitializer {
// Register attributes // Register attributes
AttributeMgr.RegisterAttributes(); AttributeMgr.RegisterAttributes();
// Register the banking system
BankManager.GetInstance().InitializeBanks();
/// THE BELOW ITEMS MUST BE DONE LAST IN THE STEPS /// THE BELOW ITEMS MUST BE DONE LAST IN THE STEPS
// Register items // Register items