[issue/chat-system] GLOBAL CONTENT git br This branch is HIJACKED for all features now until release of server. Inclusion of more financial system; transaction data; and banking information
Some checks failed
build / build (21) (push) Has been cancelled

This commit is contained in:
Jkibbels 2024-11-04 19:45:28 -05:00
parent 5cae7ec313
commit d8a6b7ecd9
6 changed files with 254 additions and 240 deletions

View File

@ -0,0 +1,51 @@
package jesse.keeblarcraft.BankMgr;
import java.util.Random;
/*
Account number composition:
EXAMPLE:
KCSB-9284-0JKI94358732
EXPLANATION:
The composition of the above number is mostly not random. The composition is 'C' = LETTER, and the first 4 represent the 4-letter combination
of the financial establishment (think of the stock market NASDAQ). The first 4 '#' (# = Number) digits represent the ROUTING number of the bank.
The next '#' (in its own brackets) represents ACCOUNT TYPE. This means the mod supports up to 9 configurations; some examples would be CHECKING
or SAVINGS. The next three '#' (in their own brackets too) will be the first three letters of the username of the account holder inside an ASCII
table. If the letter is not UTF 8 compatible - then the default will be '0'. The LAST eight '#' (not in brackets) are randomly generated via Java.
* Please note that the brackets in this example are only for demonstration of separating numbers from each other. They do not show up at all in generation.
CCCC-####-[#][###]########
* Additional note - enums are not implicitly integers under the hood like C++; so, a financial establishment could pass in ANY 0-9 digit for "account type" and
each establishment is allowed to treat that however they want. In one banks case it make checking accounts 3; but in anothers it's 4. This is a general programming
note for now. It is probably best to keep this consistent in your server/mod so tellers can understand them universally.
*/
public class AccountNumberGenerator {
// Callers of this function are required to verify the given number is unique.
public static String NewAccountNumber(String symbol, Integer routingNumber, Integer accountType, String username) {
String generatedAccountNumber = symbol + "-" + routingNumber + "-" + accountType + "-";
// Block to translate part of username into number format
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)
generatedAccountNumber += (int) username.charAt(i);
} else if (username.charAt(i) <= 255) { // Case where length is less than 3 but is still in ASCII table
generatedAccountNumber += (int) username.charAt(i);
} else { // Case where the length is less than 3 and is not standard ASCII
generatedAccountNumber += '0';
}
}
// Guarentee an 8 digit number. 10000000 is floor and max rng int is at most 89999999. Combined they total 99999999
Random rng = new Random();
Integer randInteger = 10000000 + rng.nextInt(89999999);
generatedAccountNumber += randInteger;
return generatedAccountNumber;
}
}

View File

@ -1,256 +1,30 @@
package jesse.keeblarcraft.BankMgr; package jesse.keeblarcraft.BankMgr;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map.Entry;
import jesse.CommonServerUtils;
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;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.network.ServerPlayerEntity;
// The bank manager takes care of routing any and all transactions throughout the server.
// It is a singleton object that is active throughout the mods lifetime and will cache players accounts
// when they log in to avoid constant look-ups through JSON (TODO for this).
//
public class BankManager { public class BankManager {
BankManagerFile bankInfo = new BankManagerFile(); // not sure why we make another one but i guess so we ConfigManager config = new ConfigManager();
ConfigManager config = new ConfigManager(); // for read and write privs
CommonServerUtils commonServerUtils = new CommonServerUtils();
public BankManager(String uuid) {
Boolean existingFile = false;
try {
bankInfo = config.GetJsonObjectFromFile("bank/" + uuid + ".json", BankManagerFile.class);
existingFile = true;
} catch (Exception e) {
// Do nothing. This means the file does not exist
}
// In the event the above code failed out, this means a new file has to be // Contains all account information for a given bank
// created for the player's uuid private class BankAccountInformation {
if (!existingFile) {
System.out.println(ChatUtil.ColoredString("Trying to create new file", CONSOLE_COLOR.BLUE));
try {
FlashConfig(bankInfo.uuid);
} 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));
}
if ("".equals(bankInfo.uuid)) {
System.out.println(ChatUtil.ColoredString("Assigning new config file for this uuid. No previous existing",
CONSOLE_COLOR.BLUE));
bankInfo.uuid = uuid;
}
} }
//this class is the structure for the hashmap in BankManagerFile // Structure of all the players banking information across all banks.
private class BankManagerMetaData { private class PlayerFinances {
public BankManagerMetaData(long money, String reason, long payment, String otherParty, Integer time) {
this.balance = money;
this.reason = reason;
this.payment = payment;
this.otherParty = otherParty;
this.time = time;
}
long balance = 0; // Key = Bank UUID
String reason; //not sure why my compiler is saying unused // Value = The account information for THIS player
long payment; HashMap<String, BankAccountInformation> allBanks;
String otherParty;
Integer time;
} }
// This is the general bank account of the read-in config for the player uuid ||| the class that gets converted into a json for the players file public BankManager() {
public class BankManagerFile {
// Players uuid is the name of the file
String uuid;
// Contents of file
/*
* Example:
* player_uuid_here:
* {
* "1":
* {
* "balance": "10";
* "reason": "tax evasion";
* "payment": $-44
* "other party": "jt";
* "time": "30";
* }
* "2":
* {
* Etc.
* }
* }
*/
public HashMap<String, BankManagerMetaData> bank = new HashMap<String, BankManagerMetaData>();
}
public long GetBalance() {
long ret = 0;
for (Entry<String, BankManagerMetaData> entry : bankInfo.bank.entrySet()) {
ret = entry.getValue().balance;
}
return ret;
}
//https://maven.fabricmc.net/docs/fabric-api-0.34.8+1.17/net/fabricmc/fabric/api/networking/v1/PlayerLookup.html maybe this for getting the players im still not sure
public void SetBalance(Integer newBalance, String reason, String otherParty) {
Integer transactionNumber = bankInfo.bank.size();
bankInfo.bank.put(transactionNumber.toString(),
new BankManagerMetaData(newBalance, reason, newBalance, otherParty, 0));
FlashConfig(PlayerListNameChecker(otherParty));
}
public void AddMoney(String reason, long payment, String otherParty) {
if (bankInfo.bank.size() > 0) {
for (Entry<String, BankManagerMetaData> entry : bankInfo.bank.entrySet()) {
entry.getValue().balance += payment;
entry.getValue().reason = "SERVER: " + reason;
entry.getValue().payment = payment;
entry.getValue().otherParty = otherParty;
entry.getValue().time = 0;
}
} else {
bankInfo.bank.put(bankInfo.uuid, new BankManagerMetaData(payment, reason, payment, otherParty, 0));
}
FlashConfig(PlayerListNameChecker(otherParty));
}
public void SubtractBalance(String reason, long payment, String otherParty) {
if (bankInfo.bank.size() > 0) {
for (Entry<String, BankManagerMetaData> entry : bankInfo.bank.entrySet()) {
entry.getValue().balance -= payment;//not working?
entry.getValue().reason = "SERVER: " + reason;
entry.getValue().payment = payment;
entry.getValue().otherParty = otherParty;
entry.getValue().time = 0;
}
} else {
bankInfo.bank.put(bankInfo.uuid, new BankManagerMetaData(0, reason, payment, otherParty, 0));
}
FlashConfig(PlayerListNameChecker(otherParty));
}
public void Wire(String reason, long payment, String otherParty) {
if (bankInfo.bank.size() > 0) {
for (Entry<String, BankManagerMetaData> entry : bankInfo.bank.entrySet()) {
entry.getValue().balance -= payment;
entry.getValue().reason = reason;
entry.getValue().payment = payment;
entry.getValue().otherParty = otherParty;
entry.getValue().time = 0;
if (payment <= 0) {
// add a error for the PLAYER not the server
return;
}
}
// make a server instance
MinecraftServer server = CommonServerUtils.GetServerInstance();
String[] playerList = server.getPlayerNames();
//NOT SURE IF THIS FOR LOOP IS ONE OFF COULD POSSIBLEY BE SO IF NO ONE IS GETTING MONEY DOUBLE CHECK FOR LOOP
for (int i = 0; i < playerList.length; i++) {
System.out.println(ChatUtil.ColoredString("PLAYERS: " + playerList, CONSOLE_COLOR.YELLOW));
if (playerList[i] == otherParty) {
System.out.println(ChatUtil.ColoredString("Found Player: " + otherParty, CONSOLE_COLOR.GREEN));
// we will use getuuidbyname then set the other VALID players bank BE SURE TO
// MAKE THEM A BANK FIRST IF THEY DONT HAVE ONE fortnite forever
if (config.GetFile("bank/" + GetUuidByName(server, otherParty) + ".json").size() < 1) {
BankManagerFile newBankInfo = new BankManagerFile();
BankManagerMetaData newBank = new BankManagerMetaData(0, "Account Created", 0, "Server", 0);
newBankInfo.bank.put(GetUuidByName(server, otherParty).toString(), newBank);
try {
config.WriteToJsonFile("bank/" + newBankInfo.uuid + ".json", newBankInfo);
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED));
return;
}
}
//since the other player has a account now and we have access to it we can start fucking around
BankManagerFile newBankInfo = new BankManagerFile();
newBankInfo = config.GetJsonObjectFromFile("bank/" + GetUuidByName(server, otherParty) + ".json", BankManagerFile.class);
// for now we will only use adding valance and not subtracting since that dosent make any sense
for (Entry<String, BankManagerMetaData> entry : newBankInfo.bank.entrySet()) {
entry.getValue().balance += payment;
entry.getValue().reason = reason;
entry.getValue().payment = payment;
entry.getValue().otherParty = otherParty;
entry.getValue().time = 0;
}
//cannot use regular flash config since the hard coded values need to add agurment for the uuid
//needs to be inside the player check
FlashConfig(newBankInfo.uuid);
try {
config.WriteToJsonFile("bank/" + newBankInfo.uuid + ".json", bankInfo);
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED));
}
} else {
System.out.println(ChatUtil.ColoredString("Player Not Found: " + otherParty, CONSOLE_COLOR.RED));
return;
}
}
} else {
System.out.println(ChatUtil.ColoredString("You need to finance better", CONSOLE_COLOR.RED));
return;
}
}
String GetUuidByName(MinecraftServer server, String playerName) {
PlayerManager playerManager = server.getPlayerManager();
ServerPlayerEntity player = playerManager.getPlayer(playerName);
if (player.getUuid() != null) {
return player.getUuidAsString();
} else {
return "";
}
}
String PlayerListNameChecker(String otherParty) {
MinecraftServer server = CommonServerUtils.GetServerInstance();
String[] playerList = server.getPlayerNames();
for (int i = 0; i < playerList.length; i++) {
System.out.println(ChatUtil.ColoredString("PLAYERS: " + playerList, CONSOLE_COLOR.YELLOW));
if (playerList[i] == otherParty) {
System.out.println(ChatUtil.ColoredString("Found Player: " + otherParty, CONSOLE_COLOR.GREEN));
// we will use getuuidbyname then set the other VALID players bank BE SURE TO
// MAKE THEM A BANK FIRST IF THEY DONT HAVE ONE fortnite forever
if (config.GetFile("bank/" + GetUuidByName(server, otherParty) + ".json").size() < 1) {
BankManagerFile newBankInfo = new BankManagerFile();
BankManagerMetaData newBank = new BankManagerMetaData(0, "Account Created", 0, "Server", 0);
newBankInfo.bank.put(GetUuidByName(server, otherParty).toString(), newBank);
try {
config.WriteToJsonFile("bank/" + newBankInfo.uuid + ".json", newBankInfo);
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED));
return "";
}
}
else {
System.out.println(ChatUtil.ColoredString("Bank Account Found", CONSOLE_COLOR.GREEN));
}
return GetUuidByName(server, otherParty);
}
}
System.out.println(ChatUtil.ColoredString("For Loop condition bypassed Null Playerlist or Null Server instance", CONSOLE_COLOR.RED));
return "";
}
public void FlashConfig(String uuid) {
try {
config.WriteToJsonFile("bank/" + uuid + ".json", bankInfo);
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED));
}
} }
} }

View File

@ -0,0 +1,107 @@
package jesse.keeblarcraft.BankMgr;
import java.util.List;
// Contains the information of an individuals player's bank account.
// 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
public class IndividualAccount {
private String accountNumber;
private String accountNumberAlias;
private String routingNumber; // Will always be the bank it's in
private List<String> accountHolders;
private Integer accountBalance;
private Boolean allowNegativeBalance;
private Boolean accountLocked;
private String accountType; // TODO: Replace with enum in future. Valid is "checking" and "savings" right now
public IndividualAccount() {}
public IndividualAccount(String accountNumber, String routingNumber, List<String> holders,
Boolean allowNegativeBalance, Integer initialBalance, String alias) {
this.accountNumber = accountNumber;
this.routingNumber = routingNumber;
this.accountHolders = holders;
this.allowNegativeBalance = allowNegativeBalance;
this.accountBalance = initialBalance;
this.accountNumberAlias = alias;
}
public void AliasAccount(String newAlias) {
this.accountNumberAlias = newAlias;
}
public Boolean IsLocked() {
return accountLocked;
}
public Boolean Deposit(Integer amount) {
Boolean success = false;
if (!accountLocked)
{
accountBalance += amount;
success = true;
}
return success;
}
public Boolean Withdraw(Integer amount) {
Boolean success = false;
if (!accountLocked)
{
// Determine remaining balance
Integer remaining = accountBalance - amount;
success = (remaining < 0 && !allowNegativeBalance);
// Complete the transaction if successful
if (success) {
accountBalance = remaining;
}
}
return success;
}
public Boolean CanWithdraw(Integer amount) {
Boolean canWithdraw = false;
if (!accountLocked && accountBalance - amount >= 0) {
canWithdraw = true;
}
return canWithdraw;
}
public Boolean IsHolder(String name) {
Boolean ret = false;
if (accountHolders.contains(name)) {
ret = true;
}
return ret;
}
public Boolean AllowsNegative() {
return this.allowNegativeBalance;
}
public List<String> GetAccountHolders() {
return accountHolders;
}
public Integer GetAccountBalance() {
return accountBalance;
}
public String GetAccountNumber() {
return accountNumber;
}
public String GetRoutingNumber() {
return routingNumber;
}
}

View File

@ -0,0 +1,67 @@
package jesse.keeblarcraft.BankMgr;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
// 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 {
ConfigManager config = new ConfigManager();
private String routingNumber; // this is the banks unique identifier
private String numberOfAccounts; // Total number of accounts the bank has. This includes only active accounts
// 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
private HashMap<Integer, IndividualAccount> accountsList;
private HashMap<String, List<Integer>> accountsListFromName; // This is a list that just points to a list of account numbers by person. USEFUL
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) {
accountsList = new HashMap<Integer, IndividualAccount>();
accountsListFromName = new HashMap<String, List<Integer>>();
// READ IN BANK CONFIG
// 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
}
public Boolean CreateAccount(String holderName, String accountType) {
if (accountType.toLowerCase() != "checking" || accountType.toLowerCase() != "savings") {
return false;
} // TODO: Replace String with enum type in future and remove this early return
Boolean success = false;
// Verify this isn't a blacklisted user
if (!lockedUsers.contains(holderName)) {
}
return success;
}
public Boolean HasAccount(String accountIdentifier) {
Boolean containsAccount = false;
if (accountsList.containsKey(accountIdentifier)) {
containsAccount = true;
}
return true;
}
}

View File

@ -0,0 +1,15 @@
package jesse.keeblarcraft.BankMgr;
// All details that involve a transaction attempt
public class TransactionMetadata {
enum TRANSACTION_TYPE {
DEBIT,
CREDIT
}
public String fromParty; // Account ID
public String toParty; // Account ID
public Integer amount;
public String transactionId;
public TRANSACTION_TYPE transactionType;
}

View File

@ -463,7 +463,7 @@ public class BankCommands {
* *
* Finally - calls to BankManager here for more * Finally - calls to BankManager here for more
* *
*/ */
} 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"));