Compare commits
14 Commits
main
...
PickAxe_In
Author | SHA1 | Date | |
---|---|---|---|
0e9f2d3286 | |||
fc7a9e2697 | |||
![]() |
cb9c3c124e | ||
![]() |
f7126a0555 | ||
![]() |
30ec133358 | ||
![]() |
b4234d4b6b | ||
![]() |
b048e34eda | ||
![]() |
afbb2533e7 | ||
![]() |
8ece2f2d45 | ||
![]() |
3abdf9b184 | ||
![]() |
a42d196c3c | ||
![]() |
87afc5c8ab | ||
![]() |
d8a6b7ecd9 | ||
![]() |
5cae7ec313 |
10
build.gradle
10
build.gradle
@ -10,6 +10,10 @@ base {
|
|||||||
archivesName = project.archives_base_name
|
archivesName = project.archives_base_name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fabricApi {
|
||||||
|
configureDataGeneration()
|
||||||
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// Add repositories to retrieve artifacts from in here.
|
// Add repositories to retrieve artifacts from in here.
|
||||||
// You should only use this when depending on other mods because
|
// You should only use this when depending on other mods because
|
||||||
@ -22,6 +26,8 @@ repositories {
|
|||||||
// includeGroup("cc.tweaked")
|
// includeGroup("cc.tweaked")
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
maven {url = "https://maven.kyrptonaught.dev"}
|
||||||
|
maven { url = 'https://maven.minecraftforge.net/' } // for Terrablender
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
@ -33,7 +39,6 @@ loom {
|
|||||||
sourceSet sourceSets.client
|
sourceSet sourceSets.client
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -46,6 +51,9 @@ dependencies {
|
|||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
//modCompileOnly "cc.tweaked:cc-tweaked-1.20-fabric-api:1.105.0"
|
//modCompileOnly "cc.tweaked:cc-tweaked-1.20-fabric-api:1.105.0"
|
||||||
//modRuntimeOnly "cc.tweaked:cc-tweaked-1.20-fabric-api:1.105.0"
|
//modRuntimeOnly "cc.tweaked:cc-tweaked-1.20-fabric-api:1.105.0"
|
||||||
|
modImplementation 'net.kyrptonaught:customportalapi:0.0.1-beta65-1.20'
|
||||||
|
include 'net.kyrptonaught:customportalapi:0.0.1-beta65-1.20'
|
||||||
|
modImplementation 'com.github.glitchfiend:TerraBlender-fabric:1.20.1-3.0.1.7'
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
rm ~/.minecraft/mods/keeblarcraft* # What else could be named this? Really now?
|
rm ~/.minecraft/mods/keeblarcraft* # What else could be named this? Really now?
|
||||||
cp build/devlibs/*sources.jar ~/.minecraft/mods
|
cp build/libs/keeblarcraft-0.0.1.jar ~/.minecraft/mods
|
||||||
echo Moved minecraft to mods dir
|
cp build/libs/keeblarcraft-0.0.1.jar run/mods
|
||||||
|
echo Moved minecraft to mods dir
|
||||||
|
188
run.sh
Executable file
188
run.sh
Executable file
@ -0,0 +1,188 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
BASH_PATH=$(which bash)
|
||||||
|
|
||||||
|
#########
|
||||||
|
# GLOBALS
|
||||||
|
#########
|
||||||
|
REPO_TOP=$(dirname $(readlink -f "${BASH_SOURCE[0]}"))
|
||||||
|
SCRIPT_NAME=$(basename $0)
|
||||||
|
SERVER_MODE=0 # 1=true, 0=false
|
||||||
|
CLIENT_MODE=0 # 1=true, 0=false
|
||||||
|
LOG_LEVEL=1
|
||||||
|
BUILD_PATH="build"
|
||||||
|
RUN_PATH="run"
|
||||||
|
RESET_ALL=0
|
||||||
|
RUN_ALL=1
|
||||||
|
GRADLEW_PATH=${REPO_TOP}/gradlew
|
||||||
|
declare SERVER_PID
|
||||||
|
declare CLIENT_PID
|
||||||
|
|
||||||
|
# $1 is text level
|
||||||
|
# LEVELS:
|
||||||
|
# 1: Info
|
||||||
|
# 2: Debug
|
||||||
|
# 3: Warning
|
||||||
|
function TermWrite() {
|
||||||
|
textLevel=$1
|
||||||
|
text="${2}"
|
||||||
|
prefix="[\033[34m"${SCRIPT_NAME}"\033[0m]: "
|
||||||
|
|
||||||
|
if [[ "${textLevel}" == "2" ]]; then
|
||||||
|
prefix="[\033[33m"${SCRIPT_NAME}"\033[0m]:"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${textLevel}" == "3" ]]; then
|
||||||
|
prefix="[\033[31m"${SCRIPT_NAME}"\033[0m]:"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ ${LOG_LEVEL} -ge ${textLevel} ]]; then
|
||||||
|
printf "${prefix} ${text}\n"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function help() {
|
||||||
|
echo -e "Help for running $0:"
|
||||||
|
echo -e " -s: Build and run the program in server mode"
|
||||||
|
echo -e " -c: Build and run the program in client mode"
|
||||||
|
echo -e " -l [1-3]: Turn up the logging level to see more messages (default: 1)"
|
||||||
|
echo -e " -g <path>: The path to the gradlew executable (default: $(pwd)/gradlew)"
|
||||||
|
echo -e " -r: Reset everything. This will nuke the previous install area and re-build EVERYTHING from scratch"
|
||||||
|
echo -e " -b <path>: Specify the build area (default is cur dir $(pwd)/build)"
|
||||||
|
echo -e " -b2 <path>: Specify the run area (default is cur dir $(pwd)/run)"
|
||||||
|
echo -e " -a: Run everything at once (default option if nothing specified)"
|
||||||
|
echo -e " -h: Bring up this help message"
|
||||||
|
}
|
||||||
|
|
||||||
|
function ExitAll() {
|
||||||
|
TermWrite 1 "Cleaning up..."
|
||||||
|
if [ ! -z $SERVER_PID ]; then
|
||||||
|
TermWrite 1 "Killing PID $SERVER_PID"
|
||||||
|
kill -9 $SERVER_PID
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -z $CLIENT_PID ]; then
|
||||||
|
TermWrite 1 "Killing PID $CLIENT_PID"
|
||||||
|
kill -9 $CLIENT_PID
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Close with exit code 1 because a clean close isn't guarenteed with this
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Capture CTRL+C event into ExitAll function
|
||||||
|
trap ExitAll INT
|
||||||
|
|
||||||
|
while getopts ":schl:g:r:b:b2:" opt; do
|
||||||
|
case ${opt} in
|
||||||
|
s)
|
||||||
|
TermWrite 2 "SERVER MODE ENABLED"
|
||||||
|
SERVER_MODE=1
|
||||||
|
RUN_ALL=0
|
||||||
|
;;
|
||||||
|
c)
|
||||||
|
TermWrite 2 "CLIENT MODE ENABLED"
|
||||||
|
CLIENT_MODE=1
|
||||||
|
RUN_ALL=0
|
||||||
|
;;
|
||||||
|
h)
|
||||||
|
help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
l)
|
||||||
|
if [[ $OPTARG =~ [1-3] ]]; then
|
||||||
|
LOG_LEVEL=$OPTARG
|
||||||
|
TermWrite 2 "LOG LEVEL SET TO $LOG_LEVEL"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
g)
|
||||||
|
if [[ -f "${OPTARG}" ]]; then
|
||||||
|
TermWrite 2 "Set gradlew path to $OPTARG"
|
||||||
|
GRADLEW_PATH="$OPTARG"
|
||||||
|
else
|
||||||
|
TermWrite 3 "The path you gave to the gradlew executable (${OPTARG}) does not appear to exist. Please check the path!"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
r)
|
||||||
|
RESET_ALL=1
|
||||||
|
;;
|
||||||
|
b)
|
||||||
|
if [[ -f "${OPTARG}" ]]; then
|
||||||
|
TermWrite 2 "Setting build directory to: ${OPTARG}"
|
||||||
|
BUILD_PATH="${OPTARG}"
|
||||||
|
else
|
||||||
|
TermWrite 3 "The specified path (${OPTARG}) does not appear to exist. Please check the path!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
b1)
|
||||||
|
if [[ "${OPTARG}" ]]; then
|
||||||
|
TermWrite 2 "Setting run directory to: ${OPTARG}"
|
||||||
|
RUN_PATH="${OPTARG}"
|
||||||
|
else
|
||||||
|
TermWrite 3 "The specified path (${OPTARG}) does not appear to exist. Please check the path!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
?)
|
||||||
|
help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
TermWrite 2 "CURRENT DIRECTORY: $(pwd)"
|
||||||
|
TermWrite 2 "SERVER MODE? ${SERVER_MODE}"
|
||||||
|
TermWrite 2 "CLIENT MODE? ${CLIENT_MODE}"
|
||||||
|
|
||||||
|
# If the user specified they wish to wipe everything before we begin; then let us do so.
|
||||||
|
if [[ $RESET_ALL -eq 1 ]]; then
|
||||||
|
TermWrite 1 "Removing $BUILD_PATH"
|
||||||
|
rm -rf $BUILD_PATH
|
||||||
|
TermWrite 1 "Removing $RUN_PATH"
|
||||||
|
rm -rf $RUN_PATH
|
||||||
|
|
||||||
|
TermWrite 1 "Running build..."
|
||||||
|
$BASH_PATH $GRADLEW_PATH build
|
||||||
|
TermWrite 1 "Running datagen..."
|
||||||
|
$BASH_PATH $GRADLEW_PATH runDatagen
|
||||||
|
TermWrite 1 "All completed!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $RUN_ALL -eq 0 ]]; then
|
||||||
|
if [[ $SERVER_MODE -eq 1 ]]; then
|
||||||
|
TermWrite 1 "Running ./gradlew build"
|
||||||
|
$BASH_PATH $GRADLEW_PATH build
|
||||||
|
TermWrite 1 "Running ./gradlew runServer"
|
||||||
|
$BASH_PATH $GRADLEW_PATH runServer &
|
||||||
|
SERVER_PID=$!
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $CLIENT_MODE -eq 1 ]]; then
|
||||||
|
TermWrite 1 "Running ./gradlew build"
|
||||||
|
$BASH_PATH $GRADLEW_PATH build
|
||||||
|
TermWrite 1 "Running ./gradlew runClient"
|
||||||
|
$BASH_PATH $GRADLEW_PATH runClient
|
||||||
|
CLIENT_PID=$!
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Run everything
|
||||||
|
TermWrite 1 "Running both client and server processes..."
|
||||||
|
$BASH_PATH $GRADLEW_PATH clean
|
||||||
|
$BASH_PATH $GRADLEW_PATH build
|
||||||
|
$BASH_PATH $GRADLEW_PATH runClient &
|
||||||
|
CLIENT_PID=$!
|
||||||
|
# We do not run the server in the background so the player may run commands in the server terminal
|
||||||
|
$BASH_PATH $GRADLEW_PATH runServer
|
||||||
|
SERVER_PID=$!
|
||||||
|
|
||||||
|
TermWrite 1 "Server and client processes started"
|
||||||
|
fi
|
||||||
|
|
||||||
|
TermWrite 1 "Finished running gradlew command with exit code $?"
|
||||||
|
|
||||||
|
# We wait and hang here until BOTH background processes finish (or until CTRL+C event)
|
||||||
|
wait
|
||||||
|
|
||||||
|
# Clean up and leave
|
||||||
|
ExitAll
|
@ -0,0 +1,3 @@
|
|||||||
|
// 1.20 2024-12-07T18:09:44.8464937 keeblarcraft/Keeblarcraft World Generation
|
||||||
|
4398eda2b0c28b2c754c45f5805534bf1921b243 data\keeblarcraft\worldgen\biome\test_biome.json
|
||||||
|
afc3340283d1101601bd4d2ca96341a58eceaf83 data\keeblarcraft\dimension_type\keeblarcraftdim_type.json
|
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"ambient_light": 0.5,
|
||||||
|
"bed_works": true,
|
||||||
|
"coordinate_scale": 1.0,
|
||||||
|
"effects": "minecraft:overworld",
|
||||||
|
"fixed_time": 12750,
|
||||||
|
"has_ceiling": false,
|
||||||
|
"has_raids": false,
|
||||||
|
"has_skylight": true,
|
||||||
|
"height": 480,
|
||||||
|
"infiniburn": "#minecraft:infiniburn_overworld",
|
||||||
|
"logical_height": 256,
|
||||||
|
"min_y": 0,
|
||||||
|
"monster_spawn_block_light_limit": 0,
|
||||||
|
"monster_spawn_light_level": {
|
||||||
|
"type": "minecraft:uniform",
|
||||||
|
"value": {
|
||||||
|
"max_inclusive": 0,
|
||||||
|
"min_inclusive": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"natural": false,
|
||||||
|
"piglin_safe": false,
|
||||||
|
"respawn_anchor_works": false,
|
||||||
|
"ultrawarm": false
|
||||||
|
}
|
@ -0,0 +1,99 @@
|
|||||||
|
{
|
||||||
|
"carvers": {
|
||||||
|
"air": [
|
||||||
|
"minecraft:cave",
|
||||||
|
"minecraft:cave_extra_underground",
|
||||||
|
"minecraft:canyon"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"downfall": 0.6,
|
||||||
|
"effects": {
|
||||||
|
"fog_color": 1800383,
|
||||||
|
"foliage_color": 13763580,
|
||||||
|
"grass_color": 1818548,
|
||||||
|
"sky_color": 11803583,
|
||||||
|
"water_color": 15414436,
|
||||||
|
"water_fog_color": 1800383
|
||||||
|
},
|
||||||
|
"features": [
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
"minecraft:lake_lava_underground",
|
||||||
|
"minecraft:lake_lava_surface"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"minecraft:amethyst_geode",
|
||||||
|
"minecraft:forest_rock"
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
"minecraft:ore_dirt",
|
||||||
|
"minecraft:ore_gravel",
|
||||||
|
"minecraft:ore_granite_upper",
|
||||||
|
"minecraft:ore_granite_lower",
|
||||||
|
"minecraft:ore_diorite_upper",
|
||||||
|
"minecraft:ore_diorite_lower",
|
||||||
|
"minecraft:ore_andesite_upper",
|
||||||
|
"minecraft:ore_andesite_lower",
|
||||||
|
"minecraft:ore_tuff"
|
||||||
|
],
|
||||||
|
[],
|
||||||
|
[
|
||||||
|
"minecraft:spring_water",
|
||||||
|
"minecraft:spring_lava"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"minecraft:glow_lichen",
|
||||||
|
"minecraft:trees_plains",
|
||||||
|
"minecraft:forest_flowers",
|
||||||
|
"minecraft:patch_large_fern",
|
||||||
|
"minecraft:brown_mushroom_normal",
|
||||||
|
"minecraft:red_mushroom_normal",
|
||||||
|
"minecraft:patch_sugar_cane",
|
||||||
|
"minecraft:patch_pumpkin"
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"minecraft:freeze_top_layer"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"has_precipitation": true,
|
||||||
|
"spawn_costs": {},
|
||||||
|
"spawners": {
|
||||||
|
"ambient": [],
|
||||||
|
"axolotls": [],
|
||||||
|
"creature": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:sheep",
|
||||||
|
"maxCount": 4,
|
||||||
|
"minCount": 4,
|
||||||
|
"weight": 12
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "minecraft:pig",
|
||||||
|
"maxCount": 4,
|
||||||
|
"minCount": 4,
|
||||||
|
"weight": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "minecraft:chicken",
|
||||||
|
"maxCount": 4,
|
||||||
|
"minCount": 4,
|
||||||
|
"weight": 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "minecraft:cow",
|
||||||
|
"maxCount": 4,
|
||||||
|
"minCount": 4,
|
||||||
|
"weight": 8
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"misc": [],
|
||||||
|
"monster": [],
|
||||||
|
"underground_water_creature": [],
|
||||||
|
"water_ambient": [],
|
||||||
|
"water_creature": []
|
||||||
|
},
|
||||||
|
"temperature": 0.7
|
||||||
|
}
|
@ -0,0 +1,140 @@
|
|||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @class AccountNumberGenerator
|
||||||
|
///
|
||||||
|
/// @brief Utility class for the banking system. Can generate new account
|
||||||
|
/// numbers based on parameters and parse the account number
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public class AccountNumberGenerator {
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn AccountNumberGenerator
|
||||||
|
///
|
||||||
|
/// @param[in] symbol is the bank/finance institution symbol
|
||||||
|
///
|
||||||
|
/// @param[in] routingNumber is the bank routing number
|
||||||
|
///
|
||||||
|
/// @param[in] accountType is the type of account being generated
|
||||||
|
///
|
||||||
|
/// @param[in] username is the players username who needs the account
|
||||||
|
///
|
||||||
|
/// @brief Creates a new account number for a user
|
||||||
|
///
|
||||||
|
/// @return String representation of account number
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public static String GenerateNewAccountNumber(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)
|
||||||
|
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
|
||||||
|
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
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the below functions must be given a key generated from the above function or they will combust into
|
||||||
|
// not less than one million pieces! :)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetFinancialSymbolFromId
|
||||||
|
///
|
||||||
|
/// @param[in] accountId is the generated account number
|
||||||
|
///
|
||||||
|
/// @brief Gets the financial symbol from the account id
|
||||||
|
///
|
||||||
|
/// @return String representation of financial symbol
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public static String GetFinancialSymbolFromId(String accountId) {
|
||||||
|
return accountId.substring(0, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetRoutingNumberFromId
|
||||||
|
///
|
||||||
|
/// @param[in] accountId is the generated account number
|
||||||
|
///
|
||||||
|
/// @brief Gets the routing number from the account id
|
||||||
|
///
|
||||||
|
/// @return Returns the integer of the account number
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public static Integer GetRoutingNumberFromId(String accountId) {
|
||||||
|
return Integer.parseInt(accountId.substring(5, 9));
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetAccountNumberFromId
|
||||||
|
///
|
||||||
|
/// @param[in] accountId is the generated account number
|
||||||
|
///
|
||||||
|
/// @brief Gets the smaller account identifier from the entire account
|
||||||
|
/// identifier. This would be the ACCOUNT TYPE + GENERATED NUMBER
|
||||||
|
/// on the end of the whole identifier (so no financial symbol and
|
||||||
|
/// no routing number)
|
||||||
|
///
|
||||||
|
/// @return String representation of small account number
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public static String GetAccountNumberFromId(String accountId) {
|
||||||
|
return accountId.substring(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetAccountTypeFromId
|
||||||
|
///
|
||||||
|
/// @param[in] accountId is the generated account number
|
||||||
|
///
|
||||||
|
/// @brief Gets the account type from account ID
|
||||||
|
///
|
||||||
|
/// @note The string representation of a valid account ID will have
|
||||||
|
/// '0' - '9' (range) in this position; so, subtracting 48 from
|
||||||
|
/// the ASCII returns the actual account number as an integer.
|
||||||
|
///
|
||||||
|
/// @return Integer representing account type (0-9)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public static Integer GetAccountTypeFromId(String accountId) {
|
||||||
|
return ((int) accountId.charAt(10)) - 48; // ASCII 0 starts at 48. One must subtract 48 to be correct.
|
||||||
|
}
|
||||||
|
}
|
@ -1,256 +1,302 @@
|
|||||||
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 java.util.Map.Entry;
|
||||||
|
|
||||||
import jesse.CommonServerUtils;
|
import org.apache.logging.log4j.core.jmx.Server;
|
||||||
|
|
||||||
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;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
public class BankManager {
|
// The bank manager takes care of routing any and all transactions throughout the server.
|
||||||
BankManagerFile bankInfo = new BankManagerFile(); // not sure why we make another one but i guess so we
|
// It is a singleton object that is active throughout the mods lifetime and will cache players accounts
|
||||||
ConfigManager config = new ConfigManager(); // for read and write privs
|
// when they log in to avoid constant look-ups through JSON.
|
||||||
CommonServerUtils commonServerUtils = new CommonServerUtils();
|
public final class BankManager {
|
||||||
|
private static BankManager static_inst;
|
||||||
|
|
||||||
public BankManager(String uuid) {
|
public static BankManager GetInstance() {
|
||||||
Boolean existingFile = false;
|
if (static_inst == null) {
|
||||||
try {
|
static_inst = new BankManager();
|
||||||
bankInfo = config.GetJsonObjectFromFile("bank/" + uuid + ".json", BankManagerFile.class);
|
}
|
||||||
existingFile = true;
|
return static_inst;
|
||||||
} catch (Exception e) {
|
}
|
||||||
// Do nothing. This means the file does not exist
|
|
||||||
|
private class PlayerBankConfig {
|
||||||
|
List<String> activeBanks = new ArrayList<String>(); // List of all banks a player has accounts in
|
||||||
|
String defaultSelectedBank;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Key = player uuid
|
||||||
|
// Val = player config
|
||||||
|
HashMap<String, PlayerBankConfig> playerConfigs = new HashMap<String, PlayerBankConfig>(); // Stores global detail information for bank mgr to use
|
||||||
|
|
||||||
|
private static Integer KEEBLARCRAFT_SERVER_BANK_ID = 1000; // Server global bank (default bank on server)
|
||||||
|
ConfigManager config = new ConfigManager();
|
||||||
|
|
||||||
|
// KEY = Bank routing number
|
||||||
|
// Val = Bank object
|
||||||
|
private HashMap<Integer, IndividualBank> banks = new HashMap<Integer, IndividualBank>();
|
||||||
|
|
||||||
|
// KEY = Bank name
|
||||||
|
// Val = Bank routing number
|
||||||
|
private HashMap<String, Integer> bankNameFastMap = new HashMap<String, Integer>();
|
||||||
|
|
||||||
|
public BankManager() {}
|
||||||
|
|
||||||
|
// TODO: THIS NEEDS TO READ IN FROM A FILE TO STOP NUKING BANKS ON REBOOT
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn InitializeBanks
|
||||||
|
///
|
||||||
|
/// @brief Initializes all the banks on the server at construction time
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void InitializeBanks() {
|
||||||
|
banks.put(KEEBLARCRAFT_SERVER_BANK_ID, new IndividualBank(Integer.toString(KEEBLARCRAFT_SERVER_BANK_ID), "KeeblarcraftGlobal"));
|
||||||
|
|
||||||
|
// Initialize fast map
|
||||||
|
for (Entry<Integer, IndividualBank> bank : banks.entrySet()) {
|
||||||
|
bankNameFastMap.put(bank.getValue().GetBankName(), bank.getValue().GetRoutingNumber());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetAllBankNames
|
||||||
|
///
|
||||||
|
/// @return List of all the banks that exist on a server
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public List<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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetBankByRoutingNumber
|
||||||
|
///
|
||||||
|
/// @return The IndividualBank object by routing number if the bank exists
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public IndividualBank GetBankByRoutingNumber(Integer number) {
|
||||||
|
IndividualBank bank = null;
|
||||||
|
if (banks.containsKey(number)) {
|
||||||
|
bank = banks.get(number);
|
||||||
|
}
|
||||||
|
return bank;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetBankByName
|
||||||
|
///
|
||||||
|
/// @return The Individualbank object by name if the bank exists
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public IndividualBank GetBankByName(String name) {
|
||||||
|
IndividualBank bank = null;
|
||||||
|
System.out.println("GetBankByName called with value " + name);
|
||||||
|
if (bankNameFastMap.containsKey(name)) {
|
||||||
|
System.out.println("Value of bank with name is " + bankNameFastMap.get(name));
|
||||||
|
System.out.println("Banks map size is " + banks.size());
|
||||||
|
bank = banks.get(bankNameFastMap.get(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the event the above code failed out, this means a new file has to be
|
System.out.println("Returning bank information");
|
||||||
// created for the player's uuid
|
return bank;
|
||||||
if (!existingFile) {
|
}
|
||||||
System.out.println(ChatUtil.ColoredString("Trying to create new file", CONSOLE_COLOR.BLUE));
|
|
||||||
try {
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
FlashConfig(bankInfo.uuid);
|
/// @fn ChangeDefaultPlayerAccount
|
||||||
} catch (Exception e) {
|
///
|
||||||
System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED));
|
/// @param[in] player Player object to change default accounts of
|
||||||
|
///
|
||||||
|
/// @param[in] The new default account global account identifier
|
||||||
|
///
|
||||||
|
/// @return Changes the players default account at a selected bank
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void ChangeDefaultPlayerAccount(ServerPlayerEntity player, String newDefaultAccount) {
|
||||||
|
String bankName = AccountNumberGenerator.GetFinancialSymbolFromId(newDefaultAccount);
|
||||||
|
System.out.println("ChangeDefaultPlayerAccount: Received bankName " + bankName);
|
||||||
|
System.out.println(bankNameFastMap);
|
||||||
|
|
||||||
|
// Verify bank exists first
|
||||||
|
if (bankNameFastMap.containsKey(bankName)) {
|
||||||
|
Integer routNum = bankNameFastMap.get(bankName);
|
||||||
|
IndividualBank bank = banks.get(routNum);
|
||||||
|
|
||||||
|
// Verify this person has access to this account
|
||||||
|
if(bank.IsAccountHolder(newDefaultAccount, player.getUuidAsString())) {
|
||||||
|
// Finally update config to this account since checks pass
|
||||||
|
playerConfigs.get(player.getUuidAsString()).defaultSelectedBank = newDefaultAccount;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
System.out.println(ChatUtil.ColoredString("Moving on", CONSOLE_COLOR.BLUE));
|
player.sendMessage(Text.of("Could not change default selected bank. Bank does not exist!"));
|
||||||
}
|
|
||||||
|
|
||||||
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
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
private class BankManagerMetaData {
|
/// @fn AdminChangeFunds
|
||||||
public BankManagerMetaData(long money, String reason, long payment, String otherParty, Integer time) {
|
///
|
||||||
this.balance = money;
|
/// @param[in] initiator The player object who is initiating this call
|
||||||
this.reason = reason;
|
///
|
||||||
this.payment = payment;
|
/// @param[in] accountId The account to change funds of
|
||||||
this.otherParty = otherParty;
|
///
|
||||||
this.time = time;
|
/// @param[in] amount The amount to change funds of in changeType
|
||||||
}
|
///
|
||||||
|
/// @param[in] changeType The type of funds change being initiated
|
||||||
|
///
|
||||||
|
/// @param[in] optionalReason The optional reason of changing funds
|
||||||
|
///
|
||||||
|
/// @brief Command manager to initiate a funds change from an admins
|
||||||
|
/// perspective (safe guards dropped). Valid changeTypes are
|
||||||
|
/// found inside the switch-case statement in the below function
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void AdminChangeFunds(ServerPlayerEntity initiator, String accountId, Integer amount, String changeType, String optionalReason) {
|
||||||
|
// Check to make sure account id exists
|
||||||
|
Integer routingNum = AccountNumberGenerator.GetRoutingNumberFromId(accountId);
|
||||||
|
IndividualBank bankFromRout = GetBankByRoutingNumber(routingNum);
|
||||||
|
|
||||||
long balance = 0;
|
System.out.println("Is bank null? " + (bankFromRout == null ? "YES" : "NO"));
|
||||||
String reason; //not sure why my compiler is saying unused
|
System.out.println("Bank specified: " + bankFromRout);
|
||||||
long payment;
|
System.out.println("Routing number: " + routingNum);
|
||||||
String otherParty;
|
// Verify bank exists
|
||||||
Integer time;
|
if (bankFromRout != null) {
|
||||||
}
|
// Verify account exists
|
||||||
|
System.out.println("accountNumber is " + accountId);
|
||||||
|
String accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
|
||||||
|
System.out.println("changeType is " + changeType);
|
||||||
|
|
||||||
// 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
|
switch (changeType) {
|
||||||
public class BankManagerFile {
|
case "add":
|
||||||
// Players uuid is the name of the file
|
bankFromRout.AddMoneyToAccount(accountNumber, amount);
|
||||||
String uuid;
|
break;
|
||||||
|
case "subtract":
|
||||||
// Contents of file
|
bankFromRout.SubtractMoneyFromAccount(accountNumber, amount);
|
||||||
/*
|
break;
|
||||||
* Example:
|
case "set":
|
||||||
* player_uuid_here:
|
bankFromRout.SetMoneyOnAccount(accountNumber, amount);
|
||||||
* {
|
break;
|
||||||
* "1":
|
default:
|
||||||
* {
|
System.out.println("The operation that was specified by the developer does not exist. Valid operations are add/subtract/set");
|
||||||
* "balance": "10";
|
break;
|
||||||
* "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 {
|
} else {
|
||||||
bankInfo.bank.put(bankInfo.uuid, new BankManagerMetaData(payment, reason, payment, otherParty, 0));
|
initiator.sendMessage(Text.of("That bank does not exist!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashConfig(PlayerListNameChecker(otherParty));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SubtractBalance(String reason, long payment, String otherParty) {
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
if (bankInfo.bank.size() > 0) {
|
/// @fn InitiateBankFundsTransfer
|
||||||
for (Entry<String, BankManagerMetaData> entry : bankInfo.bank.entrySet()) {
|
///
|
||||||
entry.getValue().balance -= payment;//not working?
|
/// @param[in] fromPlayer is the player funds are coming out of
|
||||||
entry.getValue().reason = "SERVER: " + reason;
|
///
|
||||||
entry.getValue().payment = payment;
|
/// @param[in] toAccount is the account the funds are going to
|
||||||
entry.getValue().otherParty = otherParty;
|
///
|
||||||
entry.getValue().time = 0;
|
/// @param[in] amount is the amount of money coming from the player
|
||||||
|
///
|
||||||
|
/// @brief Initiate a funds transfer between accounts or banks
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void InitiateBankFundsTransfer(ServerPlayerEntity fromPlayer, String toAccount, Integer amount) {
|
||||||
|
// Get player default selection
|
||||||
|
String fromAccount = playerConfigs.get(fromPlayer.getUuidAsString()).defaultSelectedBank;
|
||||||
|
|
||||||
|
String fromAccountSymbol = AccountNumberGenerator.GetFinancialSymbolFromId(fromAccount);
|
||||||
|
String toAccountSymbol = AccountNumberGenerator.GetFinancialSymbolFromId(toAccount);
|
||||||
|
|
||||||
|
System.out.println("InitiateBankFundsTransfer: FROM_ACCOUNT, FROM_ACCOUNT_SYMBOL, TO_ACCOUNT_SYMBOL: " + fromAccount + ", " + fromAccountSymbol + ", " + toAccountSymbol);
|
||||||
|
|
||||||
|
Integer destRoutingNumber = bankNameFastMap.get(toAccountSymbol);
|
||||||
|
Integer fromRoutingNumber = bankNameFastMap.get(fromAccountSymbol);
|
||||||
|
IndividualBank destBank = banks.get(destRoutingNumber);
|
||||||
|
IndividualBank fromBank = banks.get(fromRoutingNumber);
|
||||||
|
|
||||||
|
// Verify banks exist
|
||||||
|
if (destBank != null && fromBank != null) {
|
||||||
|
if (fromBank.IsValidWithdrawal(amount, fromAccount)) {
|
||||||
|
fromBank.SubtractMoneyFromAccount(fromAccount, amount);
|
||||||
|
destBank.AddMoneyToAccount(toAccount, amount);
|
||||||
|
|
||||||
|
fromPlayer.sendMessage(Text.of("[" + fromAccountSymbol + "]: Your wire has processed."));
|
||||||
|
} else {
|
||||||
|
fromPlayer.sendMessage(Text.of("[" + fromAccountSymbol + "]: You are not allowed to make this withdrawal."));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bankInfo.bank.put(bankInfo.uuid, new BankManagerMetaData(0, reason, payment, otherParty, 0));
|
fromPlayer.sendMessage(Text.of("Something went wrong! Either your bank or their bank does not exist. You shouldn't get this error!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
FlashConfig(PlayerListNameChecker(otherParty));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Wire(String reason, long payment, String otherParty) {
|
public void InitiateBankAccountClosure(String bankIdentifier, ServerPlayerEntity player, String bankAccountId) {
|
||||||
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();
|
/// @fn GetDefaultSelectedAccount
|
||||||
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
|
/// @param[in] playerUuid is the player to get their default account
|
||||||
for (Entry<String, BankManagerMetaData> entry : newBankInfo.bank.entrySet()) {
|
///
|
||||||
entry.getValue().balance += payment;
|
/// @param[in] bankIdentifier is the bank the default account is at
|
||||||
entry.getValue().reason = reason;
|
///
|
||||||
entry.getValue().payment = payment;
|
/// @brief Gets a players default account
|
||||||
entry.getValue().otherParty = otherParty;
|
///
|
||||||
entry.getValue().time = 0;
|
/// @return The global account identifier of the default selected account
|
||||||
}
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//cannot use regular flash config since the hard coded values need to add agurment for the uuid
|
public String GetDefaultSelectedAccount(String playerUuid, String bankIdentifier) {
|
||||||
//needs to be inside the player check
|
String account = "";
|
||||||
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 {
|
if (playerConfigs.containsKey(playerUuid)) {
|
||||||
System.out.println(ChatUtil.ColoredString("Player Not Found: " + otherParty, CONSOLE_COLOR.RED));
|
account = playerConfigs.get(playerUuid).defaultSelectedBank;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
}
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn InitiateBankAccountCreation
|
||||||
|
///
|
||||||
|
/// @param[in] bankIdentifier is the bank routing number
|
||||||
|
///
|
||||||
|
/// @param[in] player is the player object trying to create account
|
||||||
|
///
|
||||||
|
/// @paran[in] accountType Is the type of account the player wants to make
|
||||||
|
///
|
||||||
|
/// @brief Initiates a bank account creation with a bank
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void InitiateBankAccountCreation(String bankIdentifier, ServerPlayerEntity player, String accountType) {
|
||||||
|
Boolean success = false;
|
||||||
|
System.out.println("initiating bank creation");
|
||||||
|
boolean defaultServerBank = bankIdentifier == null || bankIdentifier == "";
|
||||||
|
System.out.println("value of bankIdentifier is " + defaultServerBank);
|
||||||
|
|
||||||
|
System.out.println("The player name is " + player.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 {
|
} else {
|
||||||
System.out.println(ChatUtil.ColoredString("You need to finance better", CONSOLE_COLOR.RED));
|
System.out.println("Creating bank on non-server owned bank");
|
||||||
return;
|
// Create an account via a specified bank identifier
|
||||||
}
|
Integer routingNumber = Integer.parseInt(bankIdentifier);
|
||||||
}
|
|
||||||
|
|
||||||
String GetUuidByName(MinecraftServer server, String playerName) {
|
if (banks.containsKey(routingNumber)) {
|
||||||
PlayerManager playerManager = server.getPlayerManager();
|
banks.get(routingNumber).CreateAccount(player.getUuidAsString(), player.getDisplayName().getString(), accountType);
|
||||||
ServerPlayerEntity player = playerManager.getPlayer(playerName);
|
} else {
|
||||||
if (player.getUuid() != null) {
|
player.sendMessage(Text.of("That bank does not exist"));
|
||||||
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) {
|
if (success) {
|
||||||
try {
|
player.sendMessage(Text.of("The banking operation was successful and your banking information has been updated"));
|
||||||
config.WriteToJsonFile("bank/" + uuid + ".json", bankInfo);
|
} else {
|
||||||
} catch (FILE_WRITE_EXCEPTION e) {
|
player.sendMessage(Text.of("The banking operating FAILED. You may need to visit the bank for more information!"));
|
||||||
System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
237
src/main/java/jesse/keeblarcraft/BankMgr/IndividualAccount.java
Normal file
237
src/main/java/jesse/keeblarcraft/BankMgr/IndividualAccount.java
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
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 globalAccountNumber;
|
||||||
|
private String bankLetterIdentifier;
|
||||||
|
private String accountNumber;
|
||||||
|
private String accountNumberAlias;
|
||||||
|
private Integer routingNumber; // Will always be the bank it's in
|
||||||
|
private List<String> accountHolders;
|
||||||
|
private List<String> accountHolderUuids;
|
||||||
|
private Integer accountBalance;
|
||||||
|
private Boolean allowNegativeBalance;
|
||||||
|
private Boolean accountLocked;
|
||||||
|
private Integer accountType; // TODO: Replace with enum in future. Valid is "checking" and "savings" right now
|
||||||
|
|
||||||
|
|
||||||
|
public IndividualAccount() {}
|
||||||
|
|
||||||
|
public IndividualAccount(String accountNumber, Integer routingNumber, List<String> holders,
|
||||||
|
List<String> accountHolderUuids, Boolean allowNegativeBalance, Integer initialBalance,
|
||||||
|
String alias, Integer accountType, String bankLetterIdentifier) {
|
||||||
|
|
||||||
|
System.out.println("Called to create new IndividualAccount with following values: " + accountNumber + " " + routingNumber + " " + holders + " " +
|
||||||
|
accountHolderUuids + " " + allowNegativeBalance + " " + initialBalance + " " + alias + " " + accountType);
|
||||||
|
this.accountNumber = accountNumber;
|
||||||
|
this.routingNumber = routingNumber;
|
||||||
|
this.accountHolders = holders;
|
||||||
|
this.accountHolderUuids = accountHolderUuids;
|
||||||
|
this.allowNegativeBalance = allowNegativeBalance;
|
||||||
|
this.accountBalance = initialBalance;
|
||||||
|
this.accountNumberAlias = alias;
|
||||||
|
this.accountType = accountType;
|
||||||
|
this.bankLetterIdentifier = bankLetterIdentifier;
|
||||||
|
this.globalAccountNumber = bankLetterIdentifier + "-" + routingNumber + "-" + accountNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn AddAccountHolder
|
||||||
|
///
|
||||||
|
/// @param[in] newHolder to be added to account
|
||||||
|
///
|
||||||
|
/// @param[in] newHolderUuid to be added to account
|
||||||
|
///
|
||||||
|
/// @brief Adds another UUID who can access the bank account
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void AddAccountHolder(String newHolder, String newHolderUuid) {
|
||||||
|
if (!accountHolders.contains(newHolder)) {
|
||||||
|
accountHolders.add(newHolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!accountHolderUuids.contains(newHolderUuid)) {
|
||||||
|
accountHolderUuids.add(newHolderUuid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn SetMoney
|
||||||
|
///
|
||||||
|
/// @param[in] amount is the new account balance
|
||||||
|
///
|
||||||
|
/// @brief Set the balance of the bank account. NOT RECOMMENDED OUTSIDE
|
||||||
|
/// OF ADMINISTRATIVE USE!!!
|
||||||
|
///
|
||||||
|
/// @note This will forcefully ignore account settings like not being
|
||||||
|
/// able to go negative. This is not recommended to use
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void SetMoney(Integer amount) {
|
||||||
|
System.out.println("Previous balance on account: " + this.accountBalance + ". New balance: " + amount);
|
||||||
|
this.accountBalance = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn AliasAccount
|
||||||
|
///
|
||||||
|
/// @param[in] newAlias to name the account
|
||||||
|
///
|
||||||
|
/// @brief Sets new alias of this account
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void AliasAccount(String newAlias) {
|
||||||
|
this.accountNumberAlias = newAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IsLocked
|
||||||
|
///
|
||||||
|
/// @brief Returns if account is locked
|
||||||
|
///
|
||||||
|
/// @return True if locked, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean IsLocked() {
|
||||||
|
return accountLocked;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn LockAccount
|
||||||
|
///
|
||||||
|
/// @brief Locks an account
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void LockAccount() {
|
||||||
|
accountLocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn Deposit
|
||||||
|
///
|
||||||
|
/// @param[in] amount is amount to be added
|
||||||
|
///
|
||||||
|
/// @brief Deposits (adds) amount of money to account
|
||||||
|
///
|
||||||
|
/// @return True if succeeds, false if fails
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean Deposit(Integer amount) {
|
||||||
|
Boolean success = false;
|
||||||
|
if (!accountLocked)
|
||||||
|
{
|
||||||
|
accountBalance += amount;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn Withdraw
|
||||||
|
///
|
||||||
|
/// @param[in] amount is amount to be subtracted
|
||||||
|
///
|
||||||
|
/// @brief Withdraws (subtracts) amount from account balance
|
||||||
|
///
|
||||||
|
/// @return True if succeeds, false if fails
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn CanWithdraw
|
||||||
|
///
|
||||||
|
/// @return True if account can afford withdrawal, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean CanWithdraw(Integer amount) {
|
||||||
|
Boolean canWithdraw = false;
|
||||||
|
|
||||||
|
if (!accountLocked && (accountBalance - amount >= 0 || allowNegativeBalance)) {
|
||||||
|
canWithdraw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return canWithdraw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IsHolder
|
||||||
|
///
|
||||||
|
/// @return True if name is on name list
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean IsHolder(String name) {
|
||||||
|
Boolean ret = false;
|
||||||
|
|
||||||
|
if (accountHolders.contains(name)) {
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn AllowsNegative
|
||||||
|
///
|
||||||
|
/// @return True if account allows negative balances, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean AllowsNegative() {
|
||||||
|
return this.allowNegativeBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetAccountHolders
|
||||||
|
///
|
||||||
|
/// @return List of everyone who has access to this account
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public List<String> GetAccountHolders() {
|
||||||
|
return accountHolders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetAccountBalance
|
||||||
|
///
|
||||||
|
/// @return Account balance
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Integer GetAccountBalance() {
|
||||||
|
return accountBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetAccountNumber
|
||||||
|
///
|
||||||
|
/// @return String representation of account number (SHORT account number)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public String GetAccountNumber() {
|
||||||
|
return accountNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetRoutingNumber
|
||||||
|
///
|
||||||
|
/// @return Routing number of account
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Integer GetRoutingNumber() {
|
||||||
|
return routingNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetGlobalAccountNumber
|
||||||
|
///
|
||||||
|
/// @return Gets global (ENTIRE) account number
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public String GetGlobalAccountNumber() {
|
||||||
|
return globalAccountNumber;
|
||||||
|
}
|
||||||
|
}
|
575
src/main/java/jesse/keeblarcraft/BankMgr/IndividualBank.java
Normal file
575
src/main/java/jesse/keeblarcraft/BankMgr/IndividualBank.java
Normal file
@ -0,0 +1,575 @@
|
|||||||
|
package jesse.keeblarcraft.BankMgr;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import static java.util.Map.entry;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
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
|
||||||
|
//
|
||||||
|
// The bank will keep track of all accounts within its facilities. In addition to accounts, the bank
|
||||||
|
// maintains its own identifier which is unique and other misc things.
|
||||||
|
public class IndividualBank {
|
||||||
|
private Map<String, Integer> ACCOUNT_TYPES = Map.ofEntries(
|
||||||
|
entry("checking", 0),
|
||||||
|
entry("savings", 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
private ConfigManager config = new ConfigManager();
|
||||||
|
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
|
||||||
|
private String bankFourLetterIdentifier;
|
||||||
|
private String registeredBankName;
|
||||||
|
|
||||||
|
private static String CONFIG_LOCATION = "config/keeblarcraft/bank/";
|
||||||
|
|
||||||
|
// Think FDIC but from the servers account (keeblarcraft insurance corporation)
|
||||||
|
// KBIC will ensure an amount of money based on its trustworthiness to a bank and the number of holders it has.
|
||||||
|
private Integer kbicInsuredAmount;
|
||||||
|
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 class Accounts {
|
||||||
|
// Key = account identifier
|
||||||
|
// Val = account object
|
||||||
|
private HashMap<String, IndividualAccount> accountsList = new HashMap<String, IndividualAccount>();
|
||||||
|
|
||||||
|
// Key = user uuid
|
||||||
|
// Val = List of account identifiers
|
||||||
|
private HashMap<String, List<String>> accountsListFromName = new HashMap<String, List<String>>(); // This is a list that just points to a list of account numbers by person. USEFUL
|
||||||
|
}
|
||||||
|
|
||||||
|
Accounts accounts;
|
||||||
|
private List<String> lockedUsers; // A list of users who are locked out of the bank and are incapable of performing more actions within it
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IndividualBank
|
||||||
|
///
|
||||||
|
/// @param[in] routingNumber is the routing number this bank is constructed
|
||||||
|
/// with
|
||||||
|
///
|
||||||
|
/// @param[in] nameOfBank Will be the display name of this bank to players
|
||||||
|
///
|
||||||
|
/// @brief Constructor for this bank
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public IndividualBank(String routingNumber, String nameOfBank) {
|
||||||
|
accounts = new Accounts();
|
||||||
|
lockedUsers = new ArrayList<String>();
|
||||||
|
registeredBankName = nameOfBank.toUpperCase();
|
||||||
|
bankFourLetterIdentifier = nameOfBank.substring(0, 4).toLowerCase();
|
||||||
|
this.routingNumber = Integer.parseInt(routingNumber);
|
||||||
|
|
||||||
|
System.out.println("CREATING BANK ACCOUNT WITH ROUTING NUMBER " + routingNumber + " AND NAME " + nameOfBank);
|
||||||
|
|
||||||
|
boolean existingFile = false;
|
||||||
|
try {
|
||||||
|
// Read in the global accounts list
|
||||||
|
String accountsListDir = CONFIG_LOCATION + routingNumber.toString() + "/accounts/";
|
||||||
|
System.out.println("accountsListDir + bankName is " + accountsListDir + nameOfBank);
|
||||||
|
accounts = config.GetJsonObjectFromFile(accountsListDir + nameOfBank, Accounts.class);
|
||||||
|
existingFile = 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(CONFIG_LOCATION + 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
|
||||||
|
// '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
|
||||||
|
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 #
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
numberOfAccounts = accounts.accountsList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetBankName
|
||||||
|
///
|
||||||
|
/// @return Returns this banks name
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public String GetBankName() {
|
||||||
|
return registeredBankName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetAccountsOfUser
|
||||||
|
///
|
||||||
|
/// @param[in] uuid is the players UUID to check
|
||||||
|
///
|
||||||
|
/// @brief Gets all the accounts a user has at this bank by UUID
|
||||||
|
///
|
||||||
|
/// @return List of all bank accounts. List will be EMPTY if no accounts
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public List<IndividualAccount> GetAccountsOfUser(String uuid) {
|
||||||
|
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 ? "YES" : "NO"));
|
||||||
|
System.out.println("List of account size: " + listOfAccounts.size());
|
||||||
|
if (listOfAccounts != null && listOfAccounts.size() > 0) {
|
||||||
|
for (int i = 0; i < listOfAccounts.size(); i++) {
|
||||||
|
accountsFromUser.add(accounts.accountsList.get(listOfAccounts.get(i)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return accountsFromUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetBankBalance
|
||||||
|
///
|
||||||
|
/// @return The banks balance
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Integer GetBankBalance() {
|
||||||
|
return bankMoney;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn AddBankBalance
|
||||||
|
///
|
||||||
|
/// @param[in] amount Amount to add to the banks balance
|
||||||
|
///
|
||||||
|
/// @brief Adds to the banks balance
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void AddBankBalance(Integer amount) {
|
||||||
|
bankMoney += amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn SubtractBankBalance
|
||||||
|
///
|
||||||
|
/// @param[in] amount Amount to subtract from banks balance
|
||||||
|
///
|
||||||
|
/// @brief Subtracts from the banks balance
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void SubtractBankBalance(Integer amount) {
|
||||||
|
bankMoney -= amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn SetBankBalance
|
||||||
|
///
|
||||||
|
/// @param[in] amount Amount to give the bank
|
||||||
|
///
|
||||||
|
/// @brief Set the banks balance
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void SetBankBalance(Integer amount) {
|
||||||
|
bankMoney = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IsBankInsured
|
||||||
|
///
|
||||||
|
/// @return True if bank is insured, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean IsBankInsured() {
|
||||||
|
return kbicInsured;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn InsuranceAmount
|
||||||
|
///
|
||||||
|
/// @brief Get the insurance amount at this bank
|
||||||
|
///
|
||||||
|
/// @return Insurance amount
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Integer InsuranceAmount() {
|
||||||
|
Integer insuredAmnt = 0;
|
||||||
|
if (kbicInsured) {
|
||||||
|
insuredAmnt = kbicInsuredAmount;
|
||||||
|
} else {
|
||||||
|
insuredAmnt = 0;
|
||||||
|
}
|
||||||
|
return insuredAmnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn UpdateBankAccounts
|
||||||
|
///
|
||||||
|
/// @brief Flashes bank account information to disk; updates volatile
|
||||||
|
/// memory of banking information for this bank
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void UpdateBankAccounts(String newHolderName, String newHolderUuid, String accountIdentifier, IndividualAccount newAccountOnly) {
|
||||||
|
// Update the fast-access map first
|
||||||
|
System.out.println("UpdateBankAccounts called with information " + newHolderName + " " + newHolderUuid + " " + accountIdentifier);
|
||||||
|
if (accounts.accountsListFromName.containsKey(newHolderUuid)) {
|
||||||
|
// Check if user is already in map
|
||||||
|
accounts.accountsListFromName.get(newHolderUuid).add(accountIdentifier);
|
||||||
|
} else {
|
||||||
|
// Add new entry to map
|
||||||
|
List<String> userAccountList = new ArrayList<String>(); // Lists are immutable; must make ArrayList
|
||||||
|
userAccountList.add(accountIdentifier);
|
||||||
|
accounts.accountsListFromName.put(newHolderUuid, userAccountList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update regular account list
|
||||||
|
if (accounts.accountsList.containsKey(accountIdentifier)) {
|
||||||
|
// This path assumes we are adding a holder as opposed to adding an account (else, how else would this work?)
|
||||||
|
System.out.println("Account found in accounts list, adding this person as a holder instead");
|
||||||
|
accounts.accountsList.get(accountIdentifier).AddAccountHolder(newHolderName, newHolderUuid);
|
||||||
|
} else {
|
||||||
|
// Non-existent account means a new one!
|
||||||
|
System.out.println("Brand new account creation, adding!");
|
||||||
|
accounts.accountsList.put(accountIdentifier, newAccountOnly);
|
||||||
|
numberOfAccounts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Flashing configuration file");
|
||||||
|
FlashConfig("bank/" + routingNumber + "/accounts");
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetRoutingNumber
|
||||||
|
///
|
||||||
|
/// @return Routing number
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Integer GetRoutingNumber() {
|
||||||
|
return this.routingNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn AddMoneyToAccount
|
||||||
|
///
|
||||||
|
/// @param[in] accountId is the account to add money to at this bank
|
||||||
|
///
|
||||||
|
/// @param[in] amount is the amount of money to add to this account
|
||||||
|
///
|
||||||
|
/// @brief Adds money to an account at this bank if it exists
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void AddMoneyToAccount(String accountId, Integer amount) {
|
||||||
|
IndividualAccount account = accounts.accountsList.get(accountId);
|
||||||
|
System.out.println("Received account # " + accountId + " and money amnt " + amount);
|
||||||
|
|
||||||
|
if (account != null) {
|
||||||
|
account.Deposit(amount);
|
||||||
|
FlashConfig("bank/" + routingNumber + "/accounts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn SubtractMoneyFromAccount
|
||||||
|
///
|
||||||
|
/// @param[in] accountId is the account to subtract money to at this bank
|
||||||
|
///
|
||||||
|
/// @param[in] amount is the amount of money to subtract to this account
|
||||||
|
///
|
||||||
|
/// @brief Subtracts money from an account at this bank if it exists
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void SubtractMoneyFromAccount(String accountId, Integer amount) {
|
||||||
|
IndividualAccount account = accounts.accountsList.get(accountId);
|
||||||
|
|
||||||
|
for (Entry<String, IndividualAccount> debug : accounts.accountsList.entrySet()) {
|
||||||
|
System.out.println("ACCOUNT ID: " + debug.getKey());
|
||||||
|
System.out.println("ACCOUNT NUM: " + debug.getValue().GetAccountNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account != null) {
|
||||||
|
account.Withdraw(amount);
|
||||||
|
FlashConfig("bank/" + routingNumber + "/accounts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn SetMoneyOnAccount
|
||||||
|
///
|
||||||
|
/// @param[in] accountId is the account number
|
||||||
|
///
|
||||||
|
/// @param[in] amount is the new balance to give this account
|
||||||
|
///
|
||||||
|
/// @brief Sets a balance on an account if it exists
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void SetMoneyOnAccount(String accountId, Integer amount) {
|
||||||
|
IndividualAccount account = accounts.accountsList.get(accountId);
|
||||||
|
System.out.println("Is account null? " + (account == null ? "YES" : "NO"));
|
||||||
|
System.out.println("Received account # " + accountId + " and money amnt " + amount);
|
||||||
|
|
||||||
|
for (Entry<String, IndividualAccount> debug : accounts.accountsList.entrySet()) {
|
||||||
|
System.out.println("ACCOUNT ID: " + debug.getKey());
|
||||||
|
System.out.println("ACCOUNT NUM: " + debug.getValue().GetAccountNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account != null) {
|
||||||
|
account.SetMoney(amount);
|
||||||
|
FlashConfig("bank/" + routingNumber + "/accounts");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn CreateAccount
|
||||||
|
///
|
||||||
|
/// @param[in] holderUuid is the new holders UUID of this account
|
||||||
|
///
|
||||||
|
/// @param[in] holderName is the display name of the holder
|
||||||
|
///
|
||||||
|
/// @param[in] accountTypeStr is the account type as a string (will be number)
|
||||||
|
///
|
||||||
|
/// @brief Create a new account at this bank
|
||||||
|
///
|
||||||
|
/// @return True if account can be created, false if it fails
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean CreateAccount(String holderUuid, String holderName, String accountTypeStr) {
|
||||||
|
Boolean success = false;
|
||||||
|
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
|
||||||
|
System.out.println("Is user bank locked? " + lockedUsers.contains(holderName));
|
||||||
|
if (!lockedUsers.contains(holderName)) {
|
||||||
|
Integer maxAttempts = 15; // Reasonably a unique bank account should pop up within 1000 generations. If not, the user may try again.
|
||||||
|
String accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(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
|
||||||
|
// entire life time of the server. BUT, you never know!
|
||||||
|
while (maxAttempts != 0 && !accounts.accountsList.containsKey(AccountNumberGenerator.GetAccountNumberFromId(accountId))) {
|
||||||
|
accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountTypeStr), holderName);
|
||||||
|
System.out.println("Account generator came back with bank account id { " + accountId + " }");
|
||||||
|
maxAttempts--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final check to add the account
|
||||||
|
String actualAccountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
|
||||||
|
System.out.println("Bank account identifier is { " + actualAccountNumber + " }. Is this already an existing account? " + accounts.accountsList.containsKey(actualAccountNumber));
|
||||||
|
if (!accounts.accountsList.containsKey(actualAccountNumber)) {
|
||||||
|
IndividualAccount newAccount = new IndividualAccount(actualAccountNumber, this.routingNumber, List.of(holderName),
|
||||||
|
List.of(holderUuid), false, 0,
|
||||||
|
"", ACCOUNT_TYPES.get(accountTypeStr), bankFourLetterIdentifier);
|
||||||
|
System.out.println("Updating accounts list for this bank");
|
||||||
|
UpdateBankAccounts(holderName, holderUuid, actualAccountNumber, newAccount);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn AliasAccount
|
||||||
|
///
|
||||||
|
/// @param[in] accountId to alias
|
||||||
|
///
|
||||||
|
/// @param[in] newAlias is name to give this account
|
||||||
|
///
|
||||||
|
/// @brief Alias an account
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void AliasAccount(String accountId, String newAlias) {
|
||||||
|
String accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
|
||||||
|
if (accounts.accountsList.containsKey(accountNumber)) {
|
||||||
|
accounts.accountsList.get(accountNumber).AliasAccount(newAlias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn LockAccountHolder
|
||||||
|
///
|
||||||
|
/// @param[in] holderName is player to lock account
|
||||||
|
///
|
||||||
|
/// @brief Locks all accounts under a name for this user
|
||||||
|
///
|
||||||
|
/// @return True if lock succeeds, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean LockAccountHolder(String holderName) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
Integer accountIter = 0;
|
||||||
|
for (Entry<String, List<String>> holderAccounts : accounts.accountsListFromName.entrySet()) {
|
||||||
|
accounts.accountsList.get(holderAccounts.getValue().get(accountIter++)).LockAccount();
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn CloseAccount
|
||||||
|
///
|
||||||
|
/// @param[in] accountId is id of account to be closed
|
||||||
|
///
|
||||||
|
/// @brief Closes an account
|
||||||
|
///
|
||||||
|
/// @note Balance of account must be 0 to close successfully
|
||||||
|
///
|
||||||
|
/// @return True if can close, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean CloseAccount(String accountId) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
String accountNumber = AccountNumberGenerator.GetAccountNumberFromId(accountId);
|
||||||
|
|
||||||
|
if (accounts.accountsList.get(accountNumber).GetAccountBalance() == 0) {
|
||||||
|
accounts.accountsList.remove(accountNumber);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn HasAccount
|
||||||
|
///
|
||||||
|
/// @param[in] accountIdentifier account number to check to see if it exists
|
||||||
|
/// at this bank
|
||||||
|
///
|
||||||
|
/// @brief See if an account identifier belongs to this bank
|
||||||
|
///
|
||||||
|
/// @return True if this bank has this account identifier, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean HasAccount(String accountIdentifier) {
|
||||||
|
Boolean containsAccount = false;
|
||||||
|
if (accounts.accountsList.containsKey(accountIdentifier)) {
|
||||||
|
containsAccount = true;
|
||||||
|
}
|
||||||
|
return containsAccount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IsValidWithdrawal
|
||||||
|
///
|
||||||
|
/// @param[in] withdrawalAmount The amount to be withdrawn
|
||||||
|
///
|
||||||
|
/// @param[in] accountIdentifier account to withdraw from
|
||||||
|
///
|
||||||
|
/// @brief Verifies if a withdrawal will succeed on an account prior to
|
||||||
|
/// the actual withdrawal itself
|
||||||
|
///
|
||||||
|
/// @return True if this account can afford this withdrawal. False if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean IsValidWithdrawal(Integer withdrawalAmount, String accountIdentifier) {
|
||||||
|
Boolean isValid = false;
|
||||||
|
|
||||||
|
if (accounts.accountsList.containsKey(accountIdentifier)) {
|
||||||
|
IndividualAccount account = accounts.accountsList.get(accountIdentifier);
|
||||||
|
|
||||||
|
if (account.CanWithdraw(withdrawalAmount)) {
|
||||||
|
isValid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IsAccountHolder
|
||||||
|
///
|
||||||
|
/// @param[in] accountIdentifier Account to check
|
||||||
|
///
|
||||||
|
/// @param[in] uuid Is players UUID to see if they are on this account
|
||||||
|
///
|
||||||
|
/// @brief Check if a player is on this account
|
||||||
|
///
|
||||||
|
/// @return True if player is on this account. False if not or account
|
||||||
|
/// does not exist
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean IsAccountHolder(String accountIdentifier, String uuid) {
|
||||||
|
Boolean isHolder = false;
|
||||||
|
|
||||||
|
// Verify account exists first
|
||||||
|
if (accounts.accountsList.containsKey(accountIdentifier)) {
|
||||||
|
isHolder = accounts.accountsList.get(accountIdentifier).IsHolder(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn FlashConfig
|
||||||
|
///
|
||||||
|
/// @param[in] dirName is config to flash to. Banking is not trivial and will
|
||||||
|
/// require separate files to be updated at different locations!
|
||||||
|
///
|
||||||
|
/// @brief Flashes the config to the disk
|
||||||
|
///
|
||||||
|
/// @note dirName should be the relative full path to dir
|
||||||
|
/// @note Function will be removed in near future for SQL but is
|
||||||
|
/// expensive to run as it flashes everything even if un-updated
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void FlashConfig(String dirName) {
|
||||||
|
for (Entry<String, IndividualAccount> singleAccount : accounts.accountsList.entrySet()) {
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -44,18 +44,18 @@ public class AttributeCommands {
|
|||||||
(
|
(
|
||||||
EntityArgumentType.getPlayer(context, "targetPlayer"),
|
EntityArgumentType.getPlayer(context, "targetPlayer"),
|
||||||
StringArgumentType.getString(context, "attributeName"),
|
StringArgumentType.getString(context, "attributeName"),
|
||||||
context)
|
context
|
||||||
)
|
)
|
||||||
.build();
|
).build();
|
||||||
|
|
||||||
var attributeNameDelete = CommandManager.argument("attributeName", StringArgumentType.greedyString())
|
var attributeNameDelete = CommandManager.argument("attributeName", StringArgumentType.greedyString())
|
||||||
.executes(context -> DeleteAttribute
|
.executes(context -> DeleteAttribute
|
||||||
(
|
(
|
||||||
EntityArgumentType.getPlayer(context, "targetPlayer"),
|
EntityArgumentType.getPlayer(context, "targetPlayer"),
|
||||||
StringArgumentType.getString(context, "attributeName"),
|
StringArgumentType.getString(context, "attributeName"),
|
||||||
context)
|
context
|
||||||
)
|
)
|
||||||
.build();
|
).build();
|
||||||
|
|
||||||
// Build out the argument tree here
|
// Build out the argument tree here
|
||||||
dispatcher.getRoot().addChild(attributeNode);
|
dispatcher.getRoot().addChild(attributeNode);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,8 @@ public class CustomCommandManager {
|
|||||||
NoteCommands noteCommands = new NoteCommands();
|
NoteCommands noteCommands = new NoteCommands();
|
||||||
BankCommands bankCommands = new BankCommands();
|
BankCommands bankCommands = new BankCommands();
|
||||||
AttributeCommands attributeCommands = new AttributeCommands();
|
AttributeCommands attributeCommands = new AttributeCommands();
|
||||||
|
FactionCommands factionCommands = new FactionCommands();
|
||||||
|
MiscCommands miscCommands = new MiscCommands();
|
||||||
|
|
||||||
// REGISTER COMMANDS BELOW
|
// REGISTER COMMANDS BELOW
|
||||||
System.out.println(ChatUtil.ColoredString("REGISTERING CUSTOM COMMAND EXTENSIONS BELOW", CONSOLE_COLOR.BLUE));
|
System.out.println(ChatUtil.ColoredString("REGISTERING CUSTOM COMMAND EXTENSIONS BELOW", CONSOLE_COLOR.BLUE));
|
||||||
@ -29,6 +31,7 @@ public class CustomCommandManager {
|
|||||||
noteCommands.RegisterNoteCommands();
|
noteCommands.RegisterNoteCommands();
|
||||||
bankCommands.RegisterCommands();
|
bankCommands.RegisterCommands();
|
||||||
attributeCommands.RegisterCommands();
|
attributeCommands.RegisterCommands();
|
||||||
|
factionCommands.RegisterFactionCommands();
|
||||||
|
miscCommands.RegisterCommands();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,110 @@
|
|||||||
package jesse.keeblarcraft.Commands;
|
package jesse.keeblarcraft.Commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.FactionMgr.FactionManager;
|
||||||
|
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||||
|
import net.minecraft.server.command.CommandManager;
|
||||||
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
public class FactionCommands {
|
public class FactionCommands {
|
||||||
|
|
||||||
// Register function for commands
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn RegisterFactionCommands
|
||||||
|
///
|
||||||
|
/// @brief Registers all commands for factions
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
public void RegisterFactionCommands() {
|
public void RegisterFactionCommands() {
|
||||||
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
|
var factionNode = CommandManager.literal("faction").build();
|
||||||
|
|
||||||
|
var createFaction = CommandManager.literal("create").build();
|
||||||
|
var disbandFaction = CommandManager.literal("disband").build();
|
||||||
|
var promote = CommandManager.literal("promote").build();
|
||||||
|
var demote = CommandManager.literal("demote").build();
|
||||||
|
|
||||||
|
// The below nodes are duplicates but are necessary to make the execute path jump correctly
|
||||||
|
var createFactionName = CommandManager.argument("faction_name", StringArgumentType.greedyString())
|
||||||
|
.executes(context -> CreateFaction
|
||||||
|
(
|
||||||
|
context,
|
||||||
|
StringArgumentType.getString(context, "faction_name")
|
||||||
|
)
|
||||||
|
).build();
|
||||||
|
|
||||||
|
var disbandFactionName = CommandManager.argument("faction_name", StringArgumentType.greedyString())
|
||||||
|
.executes(context -> DeleteFaction
|
||||||
|
(
|
||||||
|
context,
|
||||||
|
StringArgumentType.getString(context, "faction_name")
|
||||||
|
)
|
||||||
|
).build();
|
||||||
|
|
||||||
|
var leaveFaction = CommandManager.literal("leave").executes(context -> LeaveFaction(context)
|
||||||
|
).build();
|
||||||
|
|
||||||
|
|
||||||
|
var listAll = CommandManager.literal("list")
|
||||||
|
.executes(context -> ListAllFactions(context.getSource().getPlayer())).build();
|
||||||
|
|
||||||
|
|
||||||
|
// Root node
|
||||||
|
dispatcher.getRoot().addChild(factionNode);
|
||||||
|
|
||||||
|
// List command
|
||||||
|
factionNode.addChild(listAll);
|
||||||
|
factionNode.addChild(createFaction);
|
||||||
|
factionNode.addChild(disbandFaction);
|
||||||
|
factionNode.addChild(leaveFaction);
|
||||||
|
|
||||||
|
createFaction.addChild(createFactionName);
|
||||||
|
disbandFaction.addChild(disbandFactionName);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PRIVATE HANDLERS BELOW
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
private int CreateFaction() {
|
/// @fn CreateFaction
|
||||||
int retValue = -1;
|
///
|
||||||
|
/// @param[in] context is the context of where this command runs from
|
||||||
|
///
|
||||||
|
/// @param[in] newFactionName is the faction name to be created
|
||||||
|
///
|
||||||
|
/// @brief Command to create a faction
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private int CreateFaction(CommandContext<ServerCommandSource> context, String newFactionName) {
|
||||||
|
int retValue = 0;
|
||||||
|
|
||||||
|
System.out.println("CreateFaction getting player obj");
|
||||||
|
ServerPlayerEntity player = context.getSource().getPlayer();
|
||||||
|
System.out.println("CreateFaction called");
|
||||||
|
if (newFactionName.length() >= 4) {
|
||||||
|
FactionManager.GetInstance().CreateFaction(newFactionName, player);
|
||||||
|
} else {
|
||||||
|
player.sendMessage(Text.of("Your faction must be at least 4 letters long!"));
|
||||||
|
}
|
||||||
|
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int DeleteFaction() {
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
int retValue = -1;
|
/// @fn DeleteFaction
|
||||||
|
///
|
||||||
|
/// @param[in] context is the context of where this command runs from
|
||||||
|
///
|
||||||
|
/// @param[in] newFactionName is the faction name to be deleted
|
||||||
|
///
|
||||||
|
/// @brief Command to create a faction
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private int DeleteFaction(CommandContext<ServerCommandSource> context, String factionName) {
|
||||||
|
int retValue = 0;
|
||||||
|
|
||||||
|
ServerPlayerEntity player = context.getSource().getPlayer();
|
||||||
|
FactionManager.GetInstance().DeleteFaction(factionName, player);
|
||||||
|
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
@ -26,6 +115,21 @@ public class FactionCommands {
|
|||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn LeaveFaction
|
||||||
|
///
|
||||||
|
/// @param[in] context is the context of where this command runs from
|
||||||
|
///
|
||||||
|
/// @brief Command to leave a faction
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private int LeaveFaction(CommandContext<ServerCommandSource> context) {
|
||||||
|
ServerPlayerEntity player = context.getSource().getPlayer();
|
||||||
|
|
||||||
|
FactionManager.GetInstance().LeaveFaction(player);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private int KickPlayerFromFaction() {
|
private int KickPlayerFromFaction() {
|
||||||
int retValue = -1;
|
int retValue = -1;
|
||||||
|
|
||||||
@ -87,9 +191,25 @@ public class FactionCommands {
|
|||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int ListAllFactions() {
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn ListAllFactions
|
||||||
|
///
|
||||||
|
/// @param[in] player is the command runner
|
||||||
|
///
|
||||||
|
/// @brief Command to see all factions on the server
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private int ListAllFactions(ServerPlayerEntity player) {
|
||||||
int retValue = -1;
|
int retValue = -1;
|
||||||
|
|
||||||
|
System.out.println("Listing factions");
|
||||||
|
List<String> facs = FactionManager.GetInstance().ListOfFactions();
|
||||||
|
|
||||||
|
if (facs != null) {
|
||||||
|
player.sendMessage(Text.of("All factions on server: " + facs));
|
||||||
|
} else {
|
||||||
|
player.sendMessage(Text.of("There are no factions on this server yet!"));
|
||||||
|
}
|
||||||
|
|
||||||
return retValue;
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
178
src/main/java/jesse/keeblarcraft/Commands/MiscCommands.java
Normal file
178
src/main/java/jesse/keeblarcraft/Commands/MiscCommands.java
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
package jesse.keeblarcraft.Commands;
|
||||||
|
|
||||||
|
import org.apache.logging.log4j.core.jmx.Server;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.Keeblarcraft;
|
||||||
|
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
|
||||||
|
import jesse.keeblarcraft.ConfigMgr.GeneralConfig;
|
||||||
|
import jesse.keeblarcraft.EventMgr.DimensionLoadingEvent;
|
||||||
|
import jesse.keeblarcraft.Utils.DirectionalVec;
|
||||||
|
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.ChestBlock;
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.command.argument.EntityArgumentType;
|
||||||
|
import net.minecraft.inventory.EnderChestInventory;
|
||||||
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
|
import net.minecraft.nbt.NbtList;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.server.command.CommandManager;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
|
||||||
|
public class MiscCommands {
|
||||||
|
ConfigManager config = new ConfigManager();
|
||||||
|
|
||||||
|
public void RegisterCommands() {
|
||||||
|
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
|
|
||||||
|
// var magicInv = CommandManager.literal("magic-inv").build();
|
||||||
|
// var claim = CommandManager.literal("claim").executes(context -> ClaimInventory(context.getSource().getPlayer())).build();
|
||||||
|
|
||||||
|
// dispatcher.getRoot().addChild(magicInv);
|
||||||
|
// magicInv.addChild(claim);
|
||||||
|
// });
|
||||||
|
|
||||||
|
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
|
|
||||||
|
// var eChest = CommandManager.literal("enderchest").build();
|
||||||
|
// var player = CommandManager.argument("PLAYER", EntityArgumentType.player()).executes(
|
||||||
|
// context -> GetEnderchestOfPlayer(context.getSource().getPlayer(), EntityArgumentType.getPlayer(context, "PLAYER"))
|
||||||
|
// ).build();
|
||||||
|
|
||||||
|
// dispatcher.getRoot().addChild(eChest);
|
||||||
|
// eChest.addChild(player);
|
||||||
|
|
||||||
|
// // Alias
|
||||||
|
// dispatcher.register(CommandManager.literal("echest").redirect(eChest));
|
||||||
|
// });
|
||||||
|
|
||||||
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
|
|
||||||
|
var forceSpawn = CommandManager.literal("set-global-spawn").executes(context -> ForceGlobalSpawn(context.getSource().getPlayer())).build();
|
||||||
|
|
||||||
|
dispatcher.getRoot().addChild(forceSpawn);
|
||||||
|
});
|
||||||
|
|
||||||
|
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
|
|
||||||
|
var warp = CommandManager.literal("warp").build();
|
||||||
|
|
||||||
|
var warpLoc = CommandManager.argument("LOCATION", StringArgumentType.string())
|
||||||
|
.executes(context -> Warp(context.getSource().getPlayer(), StringArgumentType.getString(context, "LOCATION"))).build();
|
||||||
|
|
||||||
|
dispatcher.getRoot().addChild(warp);
|
||||||
|
warp.addChild(warpLoc);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Warp(ServerPlayerEntity player, String location) {
|
||||||
|
|
||||||
|
if (player.hasPermissionLevel(4)) {
|
||||||
|
System.out.println("Player is opped");
|
||||||
|
// hard coding spawn as only valid warp location. a more robust warp system can come later
|
||||||
|
DirectionalVec coords = GeneralConfig.GetInstance().GetSpawnCoords();
|
||||||
|
|
||||||
|
// DIRTY HACK: I am unsure how to compare the straight registry key. So for now, we will just iterate over all the worlds in the server. This really should
|
||||||
|
// not be a big deal since I have never seen a server with hundreds of worlds... but you never know I guess.
|
||||||
|
for (ServerWorld world : player.getServer().getWorlds()) {
|
||||||
|
System.out.println("Matched!");
|
||||||
|
if (world.getRegistryKey().toString().equals(coords.world.toString())) {
|
||||||
|
try {
|
||||||
|
player.teleport(world, coords.x, coords.y, coords.z, coords.yaw, coords.pitch);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
System.out.println("KEY {" + world.getRegistryKey() + "} DID NOT MATCH OURS {" + coords.world + "}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("POST TELEPORT");
|
||||||
|
} else {
|
||||||
|
player.sendMessage(Text.of("This command is only available to server admins at the moment!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ForceGlobalSpawn(ServerPlayerEntity player) {
|
||||||
|
if (player.hasPermissionLevel(4)) {
|
||||||
|
Vec3d coords = player.getPos();
|
||||||
|
DirectionalVec spawnVec = new DirectionalVec();
|
||||||
|
spawnVec.x = coords.x;
|
||||||
|
spawnVec.y = coords.y;
|
||||||
|
spawnVec.z = coords.z;
|
||||||
|
spawnVec.pitch = player.getPitch();
|
||||||
|
spawnVec.yaw = player.getYaw();
|
||||||
|
spawnVec.world = player.getWorld().getRegistryKey();
|
||||||
|
System.out.println("REG KEY OF SET: " + player.getWorld().getRegistryKey().toString());
|
||||||
|
System.out.println("REG KEY OF SET: " + player.getWorld().getRegistryKey());
|
||||||
|
player.sendMessage(Text.of("Global spawn has been set to [X, Y, Z]--[YAW, PITCH]: [" +
|
||||||
|
spawnVec.x + " " + spawnVec.y + " " + spawnVec.z + "]--" + "[" + spawnVec.yaw + " " + spawnVec.pitch + "]" + " IN WORLD " +
|
||||||
|
player.getWorld().asString()));
|
||||||
|
|
||||||
|
GeneralConfig.GetInstance().SetSpawnCoords(spawnVec);
|
||||||
|
} else {
|
||||||
|
player.sendMessage(Text.of("You do not have permission to use this command."));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetEnderchestOfPlayer(ServerPlayerEntity cmdInitiator, ServerPlayerEntity targetPlayer) {
|
||||||
|
|
||||||
|
// if (cmdInitiator.hasPermissionLevel(4)) {
|
||||||
|
// EnderChestInventory enderInv = targetPlayer.getEnderChestInventory();
|
||||||
|
// enderInv.
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// public int ClaimInventory(ServerPlayerEntity player) {
|
||||||
|
// Vec3d playerPosition = player.getPos();
|
||||||
|
// BlockPos blockPosition = new BlockPos((int) playerPosition.x + 4, (int) playerPosition.y, (int) playerPosition.z).east();
|
||||||
|
// BlockPos blockPosition2 = new BlockPos((int) playerPosition.x + 3, (int) playerPosition.y, (int) playerPosition.z).east();
|
||||||
|
|
||||||
|
|
||||||
|
// // Verify we can place the blocks before loading cached inventory
|
||||||
|
// if (player.getWorld().setBlockState(blockPosition, chestState)
|
||||||
|
// && player.getWorld().setBlockState(blockPosition2, chestState)) {
|
||||||
|
|
||||||
|
// // The below code WILL remove the inventory from the dimension cache. Only get
|
||||||
|
// // it when we succeed in placing chests!
|
||||||
|
// NbtList nbtInventory = DimensionLoadingEvent.GetInstance().GetInventory(player.getUuidAsString());
|
||||||
|
// if (nbtInventory != null) {
|
||||||
|
// BlockEntity block = player.getWorld().getBlockEntity(blockPosition);
|
||||||
|
// BlockEntity block2 = player.getWorld().getBlockEntity(blockPosition2);
|
||||||
|
|
||||||
|
// if (block != null && block2 != null) {
|
||||||
|
// block.markDirty();
|
||||||
|
// block2.markDirty();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// player.sendMessage(Text.of("Look around, your magic inventory chest was placed near you!"));
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// player.sendMessage(Text.of("Well, this is embarassing! Could not place magic inventory chest near you!"));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
}
|
@ -27,22 +27,23 @@ public class NoteCommands {
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
public NoteCommands() {
|
public NoteCommands() {
|
||||||
// Check if directory exists
|
// Check if directory exists
|
||||||
if (notesConfig.DoesDirectoryExist(NOTES_GLOBAL_DIRECTORY) == false) {
|
// if (notesConfig.DoesDirectoryExist(NOTES_GLOBAL_DIRECTORY) == false) {
|
||||||
// Attempt to create the directory
|
// // Attempt to create the directory
|
||||||
try {
|
// try {
|
||||||
if (notesConfig.CreateDirectory(NOTES_GLOBAL_DIRECTORY) == true) {
|
// if (notesConfig.CreateDirectory(NOTES_GLOBAL_DIRECTORY) == true) {
|
||||||
System.out.println(ChatUtil.ColoredString("Created notes directory successfully!", CONSOLE_COLOR.BLUE)); //TODO: Success!
|
// System.out.println(ChatUtil.ColoredString("Created notes directory successfully!", CONSOLE_COLOR.BLUE)); //TODO: Success!
|
||||||
} else {
|
// } else {
|
||||||
System.out.println(ChatUtil.ColoredString("ERROR: Notes directory FAILED to create!! Either the directory already exists or we are missing permissions!", CONSOLE_COLOR.RED)); //TODO: Critical failure --not specfic enough to mark it as a red or blue
|
// System.out.println(ChatUtil.ColoredString("ERROR: Notes directory FAILED to create!! Either the directory already exists or we are missing permissions!", CONSOLE_COLOR.RED)); //TODO: Critical failure --not specfic enough to mark it as a red or blue
|
||||||
}
|
// }
|
||||||
} catch (DIRECTORY_CREATE_EXCEPTION e) {
|
// } catch (DIRECTORY_CREATE_EXCEPTION e) {
|
||||||
System.out.println(ChatUtil.ColoredString("Directory creation failed", CONSOLE_COLOR.RED));
|
// System.out.println(ChatUtil.ColoredString("Directory creation failed", CONSOLE_COLOR.RED));
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
System.out.println(ChatUtil.ColoredString("Notes directory already exists. Skipping creation...", CONSOLE_COLOR.BLUE)); //TODO: Success!
|
// System.out.println(ChatUtil.ColoredString("Notes directory already exists. Skipping creation...", CONSOLE_COLOR.BLUE)); //TODO: Success!
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: Rework note commands upon story mode release
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
/// @fn RegisterNoteCommands
|
/// @fn RegisterNoteCommands
|
||||||
///
|
///
|
||||||
@ -50,69 +51,69 @@ public class NoteCommands {
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
public void RegisterNoteCommands() {
|
public void RegisterNoteCommands() {
|
||||||
// Command: "/addnote note goes here"
|
// Command: "/addnote note goes here"
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
|
||||||
dispatcher.register(CommandManager.literal("addnote")
|
|
||||||
.then(CommandManager.argument("value", StringArgumentType.greedyString())
|
|
||||||
.executes(context -> AddNote(StringArgumentType.getString(context, "value"), context))));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Command: "/delnote noteIdHere"
|
|
||||||
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
// dispatcher.register(CommandManager.literal("delnote")
|
// dispatcher.register(CommandManager.literal("addnote")
|
||||||
// .then(CommandManager.argument("value", StringArgumentType.greedyString())
|
// .then(CommandManager.argument("value", StringArgumentType.greedyString())
|
||||||
// .executes(context -> AddNote(StringArgumentType.getString(context, "value"), context))));
|
// .executes(context -> AddNote(StringArgumentType.getString(context, "value"), context))));
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// Command: "/purgenotes"
|
// // Command: "/delnote noteIdHere"
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
// // CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
dispatcher.register(CommandManager.literal("purgenotes")
|
// // dispatcher.register(CommandManager.literal("delnote")
|
||||||
.executes(context -> PurgeAllNotes(context)));
|
// // .then(CommandManager.argument("value", StringArgumentType.greedyString())
|
||||||
});
|
// // .executes(context -> AddNote(StringArgumentType.getString(context, "value"), context))));
|
||||||
|
// // });
|
||||||
|
|
||||||
// Command: "/modifynote noteIdHere new_note_string_here"
|
// // Command: "/purgenotes"
|
||||||
// Alises: "/editnote"
|
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
// dispatcher.register(CommandManager.literal("purgenotes")
|
||||||
final var mNote = dispatcher.register(CommandManager.literal("editnote")
|
// .executes(context -> PurgeAllNotes(context)));
|
||||||
.then(CommandManager.argument("note_id", IntegerArgumentType.integer())
|
// });
|
||||||
.then(CommandManager.argument("new_note", StringArgumentType.string())
|
|
||||||
.executes(context -> ModifyNote(
|
|
||||||
IntegerArgumentType.getInteger(context, "note_id"),
|
|
||||||
StringArgumentType.getString(context, "new_note"),
|
|
||||||
context)))));
|
|
||||||
|
|
||||||
dispatcher.register(CommandManager.literal("editnote").redirect(mNote));
|
// // Command: "/modifynote noteIdHere new_note_string_here"
|
||||||
});
|
// // Alises: "/editnote"
|
||||||
|
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
|
// final var mNote = dispatcher.register(CommandManager.literal("editnote")
|
||||||
|
// .then(CommandManager.argument("note_id", IntegerArgumentType.integer())
|
||||||
|
// .then(CommandManager.argument("new_note", StringArgumentType.string())
|
||||||
|
// .executes(context -> ModifyNote(
|
||||||
|
// IntegerArgumentType.getInteger(context, "note_id"),
|
||||||
|
// StringArgumentType.getString(context, "new_note"),
|
||||||
|
// context)))));
|
||||||
|
|
||||||
// Command Root: "/delnote noteIdHere"
|
// dispatcher.register(CommandManager.literal("editnote").redirect(mNote));
|
||||||
// Aliases: "/rmnote", "/deletenote"
|
// });
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
|
||||||
final var rootDeleteCmd = dispatcher.register(CommandManager.literal("delnote")
|
|
||||||
.then(CommandManager.argument("value", IntegerArgumentType.integer())
|
|
||||||
.executes(context -> DeleteNote(IntegerArgumentType.getInteger(context, "value"), context))));
|
|
||||||
|
|
||||||
// Alias redirects
|
// // Command Root: "/delnote noteIdHere"
|
||||||
dispatcher.register(CommandManager.literal("rmnote").redirect(rootDeleteCmd));
|
// // Aliases: "/rmnote", "/deletenote"
|
||||||
dispatcher.register(CommandManager.literal("deletenote").redirect(rootDeleteCmd));
|
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
});
|
// final var rootDeleteCmd = dispatcher.register(CommandManager.literal("delnote")
|
||||||
|
// .then(CommandManager.argument("value", IntegerArgumentType.integer())
|
||||||
|
// .executes(context -> DeleteNote(IntegerArgumentType.getInteger(context, "value"), context))));
|
||||||
|
|
||||||
// Command Root: "/notegui"
|
// // Alias redirects
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
// dispatcher.register(CommandManager.literal("rmnote").redirect(rootDeleteCmd));
|
||||||
dispatcher.register(CommandManager.literal("notegui")
|
// dispatcher.register(CommandManager.literal("deletenote").redirect(rootDeleteCmd));
|
||||||
.executes(context -> { OpenNoteGui(context);
|
// });
|
||||||
return 0;
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
|
|
||||||
// Command Root: "/notelist"
|
// // Command Root: "/notegui"
|
||||||
// Aliases: "/listnotes"
|
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
// dispatcher.register(CommandManager.literal("notegui")
|
||||||
final var rootListNotes = dispatcher.register(CommandManager.literal("notelist")
|
// .executes(context -> { OpenNoteGui(context);
|
||||||
.executes(context -> { ListNotes(context);
|
// return 0;
|
||||||
return 0;
|
// }));
|
||||||
}));
|
// });
|
||||||
|
|
||||||
dispatcher.register(CommandManager.literal("listnotes").redirect(rootListNotes));
|
// // Command Root: "/notelist"
|
||||||
});
|
// // Aliases: "/listnotes"
|
||||||
|
// CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
|
||||||
|
// final var rootListNotes = dispatcher.register(CommandManager.literal("notelist")
|
||||||
|
// .executes(context -> { ListNotes(context);
|
||||||
|
// return 0;
|
||||||
|
// }));
|
||||||
|
|
||||||
|
// dispatcher.register(CommandManager.literal("listnotes").redirect(rootListNotes));
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -28,10 +28,14 @@ import java.util.List;
|
|||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import jesse.keeblarcraft.Utils.ChatUtil;
|
import jesse.keeblarcraft.Utils.ChatUtil;
|
||||||
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
|
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
|
||||||
import jesse.keeblarcraft.Utils.CustomExceptions.*;
|
import jesse.keeblarcraft.Utils.CustomExceptions.*;
|
||||||
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
import net.minecraft.nbt.NbtIo;
|
||||||
|
import net.minecraft.nbt.NbtList;
|
||||||
|
|
||||||
public class ConfigManager {
|
public class ConfigManager {
|
||||||
|
|
||||||
@ -87,6 +91,97 @@ public class ConfigManager {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn WriteNbtListToFile
|
||||||
|
///
|
||||||
|
/// @param[in] fileName is the file location to write to
|
||||||
|
///
|
||||||
|
/// @param[in] key is the compound key type to store
|
||||||
|
///
|
||||||
|
/// @param[in] data is the NbtList to write
|
||||||
|
///
|
||||||
|
/// @brief Writes NbtList data to disk
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void WriteNbtListToFile(String fileName, String key, NbtList data) {
|
||||||
|
fileName = "config/keeblarcraft/" + fileName;
|
||||||
|
|
||||||
|
File file = new File(fileName);
|
||||||
|
if (!file.exists()) {
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
NbtCompound compound = new NbtCompound();
|
||||||
|
compound.put(key, data);
|
||||||
|
NbtIo.writeCompressed(compound, file);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn ReadAllNbtListFromDirectory
|
||||||
|
///
|
||||||
|
/// @param[in] dir is the directory path to read from
|
||||||
|
///
|
||||||
|
/// @param[in] listType is the NBT Compound list type
|
||||||
|
///
|
||||||
|
/// @brief Reads in NBTList data from a directory; using file names as key.
|
||||||
|
/// If a file is read in correctly, the file is deleted
|
||||||
|
///
|
||||||
|
/// @return A map of NbtList data with the key being the file name (minus ext)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public HashMap<String, NbtList> ReadAllNbtListFromDirectory(String dir, int listType) {
|
||||||
|
HashMap<String, NbtList> list = new HashMap<String, NbtList>();
|
||||||
|
dir = "config/keeblarcraft/" + dir;
|
||||||
|
|
||||||
|
File directory = new File(dir);
|
||||||
|
|
||||||
|
File[] files = directory.listFiles();
|
||||||
|
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
String key = file.getName().substring(0, file.getName().length() - 4);
|
||||||
|
NbtList nbtList = ReadNbtListFromFile(file, key, listType);
|
||||||
|
|
||||||
|
if (nbtList != null) {
|
||||||
|
// Subtract out '.nbt' from name
|
||||||
|
list.put(key, nbtList);
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn ReadNbtListFromFile
|
||||||
|
///
|
||||||
|
/// @param[in] file handler object to read nbt list data from
|
||||||
|
///
|
||||||
|
/// @param[in] key for the nbt compound object
|
||||||
|
///
|
||||||
|
/// @param[in] listType is the NBT Compound list type
|
||||||
|
///
|
||||||
|
/// @brief Reads in NBTList data from a single file
|
||||||
|
///
|
||||||
|
/// @return NbtList data
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public NbtList ReadNbtListFromFile(File file, String key, int listType) {
|
||||||
|
NbtList list = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
NbtCompound c = NbtIo.readCompressed(file);
|
||||||
|
list = c.getList(key, listType);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
// WriteToFile
|
// WriteToFile
|
||||||
//
|
//
|
||||||
// Will write or append to file (valid modes: "w" or "a") if file is available. Returns false if not
|
// Will write or append to file (valid modes: "w" or "a") if file is available. Returns false if not
|
||||||
@ -130,13 +225,14 @@ public class ConfigManager {
|
|||||||
// NOTE: THIS DOES NOT SAFE UPDATE THE KEY OBJECT. PRE-EXISTING DATA WILL BE DELETED FOREVER
|
// NOTE: THIS DOES NOT SAFE UPDATE THE KEY OBJECT. PRE-EXISTING DATA WILL BE DELETED FOREVER
|
||||||
public void WriteToJsonFile(String fileName, Object data) throws FILE_WRITE_EXCEPTION {
|
public void WriteToJsonFile(String fileName, Object data) throws FILE_WRITE_EXCEPTION {
|
||||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
fileName = "config/keeblarcraft/" + fileName;
|
||||||
try {
|
try {
|
||||||
FileWriter writer = new FileWriter(fileName);
|
FileWriter writer = new FileWriter(fileName);
|
||||||
gson.toJson(data, writer);
|
gson.toJson(data, writer);
|
||||||
writer.flush();
|
writer.flush();
|
||||||
writer.close();
|
writer.close();
|
||||||
} catch (JsonIOException | IOException e) {
|
} catch (JsonIOException | IOException e) {
|
||||||
System.out.println(ChatUtil.ColoredString("Could not successfully write to json file", CONSOLE_COLOR.RED));
|
System.out.println(ChatUtil.ColoredString("Could not successfully write to json file [" + fileName + "]", CONSOLE_COLOR.RED));
|
||||||
throw new FILE_WRITE_EXCEPTION();
|
throw new FILE_WRITE_EXCEPTION();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,6 +243,8 @@ public class ConfigManager {
|
|||||||
public <T> T GetJsonObjectFromFile(String fileName, Class<T> classToConvertTo) throws JsonSyntaxException {
|
public <T> T GetJsonObjectFromFile(String fileName, Class<T> classToConvertTo) throws JsonSyntaxException {
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
String ret = "";
|
String ret = "";
|
||||||
|
fileName = "config/keeblarcraft/" + fileName;
|
||||||
|
System.out.println("Call to GetJsonObjectFromFile with path + file being " + fileName);
|
||||||
|
|
||||||
// hot fix: Not sure how to return "false" for invalid conversion when I'm forced to convert or just catch... Look into a better
|
// hot fix: Not sure how to return "false" for invalid conversion when I'm forced to convert or just catch... Look into a better
|
||||||
// return value in the future - but for now throw JsonSyntaxException no matter what exception is caught
|
// return value in the future - but for now throw JsonSyntaxException no matter what exception is caught
|
||||||
@ -182,6 +280,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()) {
|
||||||
|
148
src/main/java/jesse/keeblarcraft/ConfigMgr/GeneralConfig.java
Normal file
148
src/main/java/jesse/keeblarcraft/ConfigMgr/GeneralConfig.java
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
package jesse.keeblarcraft.ConfigMgr;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.Utils.DirectionalVec;
|
||||||
|
import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION;
|
||||||
|
|
||||||
|
public class GeneralConfig {
|
||||||
|
private static GeneralConfig static_inst;
|
||||||
|
ConfigManager cfgMgr = new ConfigManager();
|
||||||
|
private ImplementedConfig config;
|
||||||
|
|
||||||
|
public static GeneralConfig GetInstance() {
|
||||||
|
if (static_inst == null) {
|
||||||
|
static_inst = new GeneralConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetConfig
|
||||||
|
///
|
||||||
|
/// @brief Returns the mods general configuration file object
|
||||||
|
///
|
||||||
|
/// @return The configuration object
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public ImplementedConfig GetConfig() {
|
||||||
|
if (config == null) {
|
||||||
|
config = new ImplementedConfig();
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GeneralConfig
|
||||||
|
///
|
||||||
|
/// @brief Constructs the general configuration file for the project
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public GeneralConfig() {
|
||||||
|
Boolean existingFile = false;
|
||||||
|
try {
|
||||||
|
config = cfgMgr.GetJsonObjectFromFile("general.json", ImplementedConfig.class);
|
||||||
|
|
||||||
|
System.out.println("Read in config. Random value: " + config.global_spawn.x);
|
||||||
|
existingFile = true;
|
||||||
|
} catch(Exception e) {
|
||||||
|
System.out.println("FAILED TO READ IN GENERALCONFIG");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!existingFile) {
|
||||||
|
config = new ImplementedConfig();
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config == null) {
|
||||||
|
config = new ImplementedConfig();
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetSpawnCoords
|
||||||
|
///
|
||||||
|
/// @brief Gets the coordinates for the global spawn
|
||||||
|
///
|
||||||
|
/// @return A vector containing how a player should spawn in or null if not
|
||||||
|
/// set yet.
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public DirectionalVec GetSpawnCoords() {
|
||||||
|
System.out.println("Among us");
|
||||||
|
System.out.println("GetSpawnCoords called. is global_spawn null? " + (config.global_spawn == null ? "YES": "NO"));
|
||||||
|
return config.global_spawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn SetSpawnCoords
|
||||||
|
///
|
||||||
|
/// @brief Sets the coordinates for the global spawn
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void SetSpawnCoords(DirectionalVec vec) {
|
||||||
|
config.global_spawn = vec;
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IsNewPlayer
|
||||||
|
///
|
||||||
|
/// @param[in] uuid is the player uuid
|
||||||
|
///
|
||||||
|
/// @brief Checks to see if player uuid has ever joined. If not, then add
|
||||||
|
/// to global list of uuids who have joined.
|
||||||
|
///
|
||||||
|
/// @return True if player is new, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean IsNewPlayer(String uuid) {
|
||||||
|
System.out.println("IsNewPlayer called. List has: " + config.playerList);
|
||||||
|
Boolean isNew = !config.playerList.contains(uuid);
|
||||||
|
|
||||||
|
System.out.println("Value of isNew is " + isNew);
|
||||||
|
|
||||||
|
if (isNew) {
|
||||||
|
config.playerList.add(uuid);
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
return isNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetMOTD
|
||||||
|
///
|
||||||
|
/// @brief String object with the MOTD of the server
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public String GetMOTD() {
|
||||||
|
return config.MOTD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @class ImplementedConfig is the configuration class holder
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private class ImplementedConfig {
|
||||||
|
public String MOTD = "Welcome to the server! Have fun!";
|
||||||
|
|
||||||
|
// This is lazy, but this will fill with every unique UUID that has joined the server. This is how I am checking
|
||||||
|
// to see if a player has just joined the server for a first time or not
|
||||||
|
public List<String> playerList = new ArrayList<>();
|
||||||
|
DirectionalVec global_spawn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn FlashConfig
|
||||||
|
///
|
||||||
|
/// @brief String object with the MOTD of the server
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private void FlashConfig() {
|
||||||
|
System.out.println("Attempting to write generalconfig to file. Is null? " + (config == null ? "YES" : "NO"));
|
||||||
|
try {
|
||||||
|
cfgMgr.WriteToJsonFile("general.json", config);
|
||||||
|
} catch (FILE_WRITE_EXCEPTION e) {
|
||||||
|
System.out.println("Caught FileWriteException from general config writing. uh oh!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
// package jesse.keeblarcraft.CustomBlocks.BlockEntities;
|
||||||
|
|
||||||
|
// import jesse.keeblarcraft.Keeblarcraft;
|
||||||
|
// import jesse.keeblarcraft.CustomBlocks.BlockManager;
|
||||||
|
// import jesse.keeblarcraft.world.ImplementedInventory;
|
||||||
|
|
||||||
|
// import net.minecraft.block.BlockState;
|
||||||
|
// import net.minecraft.block.entity.BlockEntity;
|
||||||
|
// import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
// import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
// import net.minecraft.inventory.Inventories;
|
||||||
|
// import net.minecraft.item.ItemStack;
|
||||||
|
// import net.minecraft.nbt.NbtCompound;
|
||||||
|
// import net.minecraft.registry.RegistryWrapper;
|
||||||
|
// import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||||
|
// import net.minecraft.screen.PropertyDelegate; // for syncing client + server
|
||||||
|
// import net.minecraft.screen.ScreenHandler;
|
||||||
|
// import net.minecraft.text.Text;
|
||||||
|
// import net.minecraft.util.collection.DefaultedList;
|
||||||
|
// import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
// public class MagicChestBlockEntity extends BlockEntity implements NamedScreenHandlerFactory, ImplementedInventory {
|
||||||
|
// private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(256, ItemStack.EMPTY);
|
||||||
|
|
||||||
|
// protected final PropertyDelegate propertyDelegate;
|
||||||
|
// private int progress = 0;
|
||||||
|
// private int maxProgress = 72;
|
||||||
|
|
||||||
|
// public MagicChestBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
// super(Keeblarcraft.MAGIC_CHEST_BLOCK_ENTITY, pos, state);
|
||||||
|
// this.propertyDelegate = new PropertyDelegate() {
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public int get(int index) {
|
||||||
|
// return switch(index) {
|
||||||
|
// case 0 -> MagicChestBlockEntity.this.progress;
|
||||||
|
// case 1 -> MagicChestBlockEntity.this.maxProgress;
|
||||||
|
// default -> 0;
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public void set(int index, int value) {
|
||||||
|
// switch (index) {
|
||||||
|
// case 0 -> MagicChestBlockEntity.this.progress = value;
|
||||||
|
// case 1 -> MagicChestBlockEntity.this.maxProgress = value;
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // MUST be size of how many integers we are synchronizing
|
||||||
|
// @Override
|
||||||
|
// public int size() {
|
||||||
|
// return 2;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
|
||||||
|
// // Screen handler will sync the inventory
|
||||||
|
// return new MagicChestScreenHandler(syncId, playerInventory, this);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public DefaultedList<ItemStack> getItems() {
|
||||||
|
// return inventory;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public Text getDisplayName() {
|
||||||
|
// return Text.translatable(getCachedState().getBlock().getTranslationKey());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public void readNbt(NbtCompound nbt) {
|
||||||
|
// super.readNbt(nbt);
|
||||||
|
// Inventories.readNbt(nbt, this.inventory);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public void writeNbt(NbtCompound nbt) {
|
||||||
|
// super.writeNbt(nbt);
|
||||||
|
// Inventories.writeNbt(nbt, this.inventory);
|
||||||
|
// }
|
||||||
|
// }
|
@ -0,0 +1,43 @@
|
|||||||
|
// package jesse.keeblarcraft.CustomBlocks.Blocks;
|
||||||
|
|
||||||
|
// import jesse.keeblarcraft.CustomBlocks.BlockEntities.MagicChestBlockEntity;
|
||||||
|
// import net.minecraft.block.BlockRenderType;
|
||||||
|
// import net.minecraft.block.BlockState;
|
||||||
|
// import net.minecraft.block.BlockWithEntity;
|
||||||
|
// import net.minecraft.block.entity.BlockEntity;
|
||||||
|
// import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
// import net.minecraft.screen.NamedScreenHandlerFactory;
|
||||||
|
// import net.minecraft.util.ActionResult;
|
||||||
|
// import net.minecraft.util.Hand;
|
||||||
|
// import net.minecraft.util.hit.BlockHitResult;
|
||||||
|
// import net.minecraft.util.math.BlockPos;
|
||||||
|
// import net.minecraft.world.World;
|
||||||
|
|
||||||
|
// public class MagicChestBlock extends BlockWithEntity {
|
||||||
|
// public MagicChestBlock(Settings settings) {
|
||||||
|
// super(settings);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
|
||||||
|
// return new MagicChestBlockEntity(pos, state);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public BlockRenderType getRenderType(BlockState state) {
|
||||||
|
// return BlockRenderType.MODEL;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
// public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
|
||||||
|
// if (!world.isClient) {
|
||||||
|
// NamedScreenHandlerFactory screenHandlerFactory = ((MagicChestBlockEntity) world.getBlockEntity(pos));
|
||||||
|
|
||||||
|
// if (screenHandlerFactory != null) {
|
||||||
|
// player.openHandledScreen(screenHandlerFactory);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return ActionResult.SUCCESS;
|
||||||
|
// }
|
||||||
|
// }
|
@ -0,0 +1,29 @@
|
|||||||
|
package jesse.keeblarcraft.CustomItems;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.client.item.TooltipContext;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.PickaxeItem;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Formatting;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class LongReachPicks extends Item {
|
||||||
|
//Creation of Items
|
||||||
|
public final static Item longDiamondPick = new PickaxeItem(PickAxeMaker.LONG_DIAMOND_PICK, 2, 2, new Item.Settings());
|
||||||
|
|
||||||
|
LongReachPicks(Settings settings) {
|
||||||
|
super(settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> tooltip, TooltipContext context) {
|
||||||
|
tooltip.add(Text.translatable("longpick.tooltip").formatted(Formatting.GOLD));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package jesse.keeblarcraft.CustomItems;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import net.fabricmc.yarn.constants.MiningLevels;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.item.ToolMaterial;
|
||||||
|
import net.minecraft.recipe.Ingredient;
|
||||||
|
|
||||||
|
public enum PickAxeMaker implements ToolMaterial {
|
||||||
|
LONG_DIAMOND_PICK(MiningLevels.DIAMOND, 650, 4.5f, 3.0f, 26, () -> Ingredient.ofItems(Items.ENDER_EYE));
|
||||||
|
|
||||||
|
private final int miningLevel;
|
||||||
|
private final int itemDurability;
|
||||||
|
private final float miningSpeed;
|
||||||
|
private final float attackDamage;
|
||||||
|
public final int enchantability;
|
||||||
|
private final Supplier<Ingredient> repairIngredient;
|
||||||
|
|
||||||
|
PickAxeMaker(int MiningLevel, int ItemDurability, float MiningSpeed, float AttackDamage, int Enchantability, Supplier<Ingredient> RepairIngredient) {
|
||||||
|
this.miningLevel = MiningLevel;
|
||||||
|
this.itemDurability = ItemDurability;
|
||||||
|
this.miningSpeed = MiningSpeed;
|
||||||
|
this.attackDamage = AttackDamage;
|
||||||
|
this.enchantability = Enchantability;
|
||||||
|
this.repairIngredient = RepairIngredient;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getAttackDamage() {
|
||||||
|
return this.attackDamage;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDurability() {
|
||||||
|
return this.itemDurability;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getEnchantability() {
|
||||||
|
return this.enchantability;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMiningLevel() {
|
||||||
|
return this.miningLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getMiningSpeedMultiplier() {
|
||||||
|
return this.miningSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Ingredient getRepairIngredient() {
|
||||||
|
return this.repairIngredient.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package jesse.keeblarcraft.CustomItems;
|
||||||
|
|
||||||
|
|
||||||
|
public class PickAxeRegister {
|
||||||
|
|
||||||
|
public static void registerHandhelds() {
|
||||||
|
ItemManager.RegisterItem("longdiamondpick", LongReachPicks.longDiamondPick);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,127 @@
|
|||||||
|
package jesse.keeblarcraft.EventMgr;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
|
||||||
|
import jesse.keeblarcraft.Utils.ChatUtil;
|
||||||
|
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
|
||||||
|
import jesse.keeblarcraft.world.dimension.ModDimensions;
|
||||||
|
import net.minecraft.nbt.NbtElement;
|
||||||
|
import net.minecraft.nbt.NbtList;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
|
||||||
|
public class DimensionLoadingEvent {
|
||||||
|
private static DimensionLoadingEvent static_inst;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetInstance
|
||||||
|
///
|
||||||
|
/// @brief Static instance getter for this class
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public static DimensionLoadingEvent GetInstance() {
|
||||||
|
if (static_inst == null) {
|
||||||
|
static_inst = new DimensionLoadingEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper class to manage the single inventory cache of dimension loading
|
||||||
|
private static class InventoryWrapper {
|
||||||
|
public HashMap<String, NbtList> inventories = new HashMap<String, NbtList>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static InventoryWrapper iw = new InventoryWrapper();
|
||||||
|
|
||||||
|
private static String CONFIG_LOCATION = "misc/dim_loading_cached_inventories/";
|
||||||
|
ConfigManager config = new ConfigManager();
|
||||||
|
|
||||||
|
public DimensionLoadingEvent() {
|
||||||
|
// read config
|
||||||
|
iw.inventories = config.ReadAllNbtListFromDirectory(CONFIG_LOCATION, NbtElement.COMPOUND_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn HandleWorldMove
|
||||||
|
///
|
||||||
|
/// @param[in] player is the player object
|
||||||
|
///
|
||||||
|
/// @param[in] origin is the FROM destination world
|
||||||
|
///
|
||||||
|
/// @param[in] destination is the TO destination world
|
||||||
|
///
|
||||||
|
/// @brief Callback handler for player world move events on server
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void HandleWorldMove(ServerPlayerEntity player, ServerWorld origin, ServerWorld destination) {
|
||||||
|
System.out.println("World move event called!");
|
||||||
|
|
||||||
|
// Player is ENTERING the custom dimension; strip their inventory!
|
||||||
|
if (destination.getDimensionEntry().matchesKey(ModDimensions.KEEBLAR_DIM_TYPE) && (!iw.inventories.containsKey(player.getUuidAsString()))) {
|
||||||
|
// Make sure player is in map. For now we only care about storing OVERWORLD inventory. We DO NOT care about
|
||||||
|
// the dimension inventory!
|
||||||
|
// if (!iw.inventories.containsKey(player.getUuidAsString())) {
|
||||||
|
// Copy the nbt into the list
|
||||||
|
NbtList inventoryNbt = new NbtList();
|
||||||
|
player.getInventory().writeNbt(inventoryNbt);
|
||||||
|
|
||||||
|
iw.inventories.put(player.getUuidAsString(), inventoryNbt);
|
||||||
|
player.getInventory().clear();
|
||||||
|
// }
|
||||||
|
// Player is LEAVING the custom dimension. Give them their stuff back
|
||||||
|
} else if (origin.getDimensionEntry().matchesKey(ModDimensions.KEEBLAR_DIM_TYPE) && iw.inventories.containsKey(player.getUuidAsString())) {
|
||||||
|
// if (iw.inventories.containsKey(player.getUuidAsString())) {
|
||||||
|
player.getInventory().readNbt(iw.inventories.get(player.getUuidAsString()));
|
||||||
|
iw.inventories.remove(player.getUuidAsString());
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn SaveInventories
|
||||||
|
///
|
||||||
|
/// @brief Flashes the configuration file on disk (call before server exit
|
||||||
|
/// to not lose memory!)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void SaveInventories() {
|
||||||
|
System.out.println("Call to save inventories. Flashing IW.Inventories with size " + iw.inventories.size());
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetInventories
|
||||||
|
///
|
||||||
|
/// @param Player uuid
|
||||||
|
///
|
||||||
|
/// @brief Gets a player inventory from the map. Calling this action also
|
||||||
|
/// removes the inventory from the stored map so be sure to use
|
||||||
|
/// it if you call it!
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public NbtList GetInventory(String uuid) {
|
||||||
|
NbtList nbt = iw.inventories.get(uuid);
|
||||||
|
iw.inventories.remove(uuid);
|
||||||
|
return nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn FlashConfig
|
||||||
|
///
|
||||||
|
/// @brief Flashes configuration file to disk
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void FlashConfig() {
|
||||||
|
try {
|
||||||
|
// config.WriteToJsonFile(CONFIG_LOCATION, iw);
|
||||||
|
// First, ensure list is size > 0
|
||||||
|
for (Entry<String, NbtList> list : iw.inventories.entrySet()) {
|
||||||
|
if (list.getValue().size() > 0) {
|
||||||
|
config.WriteNbtListToFile(CONFIG_LOCATION + list.getKey() + ".nbt", list.getKey(), list.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(ChatUtil.ColoredString("Could not flash dimension loading configuration file", CONSOLE_COLOR.RED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package jesse.keeblarcraft.EventMgr;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.AttributeMgr.AttributeMgr;
|
||||||
|
import jesse.keeblarcraft.AttributeMgr.AttributeTree;
|
||||||
|
import jesse.keeblarcraft.ConfigMgr.GeneralConfig;
|
||||||
|
import jesse.keeblarcraft.Utils.DirectionalVec;
|
||||||
|
import net.fabricmc.fabric.api.networking.v1.PacketSender;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
|
import net.minecraft.server.network.ServerPlayNetworkHandler;
|
||||||
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.server.world.ServerWorld;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
public class PlayerJoinListener {
|
||||||
|
private static PlayerJoinListener static_inst;
|
||||||
|
|
||||||
|
// Get the static instance for this class
|
||||||
|
public static PlayerJoinListener GetInstance() {
|
||||||
|
if (static_inst == null) {
|
||||||
|
static_inst = new PlayerJoinListener();
|
||||||
|
}
|
||||||
|
return static_inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn HandleServerJoinEvent
|
||||||
|
///
|
||||||
|
/// @param[in] handler is the network handler
|
||||||
|
///
|
||||||
|
/// @param[in] sender is the packet sender
|
||||||
|
///
|
||||||
|
/// @param[in] server is the MinecraftServer instance
|
||||||
|
///
|
||||||
|
/// @brief Callback function for player join event in minecraft server
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void HandleServerJoinEvent(ServerPlayNetworkHandler handler, PacketSender sender, MinecraftServer server) {
|
||||||
|
var player = handler.player;
|
||||||
|
|
||||||
|
// Handle skill tree map instance
|
||||||
|
if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == false) {
|
||||||
|
AttributeMgr.activeTrees.put(player.getUuidAsString(), new AttributeTree(player.getUuidAsString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle first time joining events (world spawn teleport, MOTD, etc)
|
||||||
|
System.out.println("Running first time login stuff");
|
||||||
|
IsFirstTimeLogin(player, server);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IsFirstTimeLogin
|
||||||
|
///
|
||||||
|
/// @param[in] player is the player who is joining
|
||||||
|
///
|
||||||
|
/// @param[in] server is the MinecraftServer instance
|
||||||
|
///
|
||||||
|
/// @brief Check to see if player is first time log-in. If so, we teleport
|
||||||
|
/// them to spawn. This function may be expanded in future
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private void IsFirstTimeLogin(ServerPlayerEntity player, MinecraftServer server) {
|
||||||
|
// Send the MOTD + Spawn in global spawn
|
||||||
|
player.sendMessage(Text.of(GeneralConfig.GetInstance().GetMOTD()));
|
||||||
|
if (GeneralConfig.GetInstance().IsNewPlayer(player.getUuidAsString())) {
|
||||||
|
DirectionalVec coords = GeneralConfig.GetInstance().GetSpawnCoords();
|
||||||
|
if (coords != null) {
|
||||||
|
for (ServerWorld world : player.getServer().getWorlds()) {
|
||||||
|
if (world.getRegistryKey().toString().equals(coords.world.toString())) {
|
||||||
|
try {
|
||||||
|
player.teleport(world, coords.x, coords.y, coords.z, coords.yaw, coords.pitch);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
511
src/main/java/jesse/keeblarcraft/FactionMgr/FactionConfig.java
Normal file
511
src/main/java/jesse/keeblarcraft/FactionMgr/FactionConfig.java
Normal file
@ -0,0 +1,511 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* FactionConfig
|
||||||
|
*
|
||||||
|
* This class is the configuration file for factions
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package jesse.keeblarcraft.FactionMgr;
|
||||||
|
|
||||||
|
import static java.util.Map.entry;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
// This class is written to a config file typically and represents
|
||||||
|
// all the details surrounding a faction
|
||||||
|
public class FactionConfig {
|
||||||
|
// Key = Faction identifier
|
||||||
|
// Val = Faction object
|
||||||
|
HashMap<String, WriteableFaction> allFactions = new HashMap<String, WriteableFaction>();
|
||||||
|
|
||||||
|
// Enum may be extended in future
|
||||||
|
public static enum VALID_FACTION_ROLES {
|
||||||
|
OWNER,
|
||||||
|
COOWNER,
|
||||||
|
MANAGEMENT,
|
||||||
|
EMPLOYEE
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<VALID_FACTION_ROLES, Integer> ROLE_LEVELS = Map.ofEntries
|
||||||
|
(
|
||||||
|
entry (VALID_FACTION_ROLES.EMPLOYEE, 0),
|
||||||
|
entry (VALID_FACTION_ROLES.MANAGEMENT, 1),
|
||||||
|
entry (VALID_FACTION_ROLES.COOWNER, 2),
|
||||||
|
entry (VALID_FACTION_ROLES.OWNER, 3)
|
||||||
|
);
|
||||||
|
|
||||||
|
// The below map is 100x easier to just have statically typed here and maintained manually than expensively getting value by key (I am also lazy)
|
||||||
|
private static Map<Integer, VALID_FACTION_ROLES> ROLES_BY_LEVEL = Map.ofEntries
|
||||||
|
(
|
||||||
|
entry (0, VALID_FACTION_ROLES.EMPLOYEE),
|
||||||
|
entry (1, VALID_FACTION_ROLES.MANAGEMENT),
|
||||||
|
entry (2, VALID_FACTION_ROLES.COOWNER),
|
||||||
|
entry (3, VALID_FACTION_ROLES.OWNER)
|
||||||
|
);
|
||||||
|
|
||||||
|
public class WriteableFaction {
|
||||||
|
// Key = Player UUID
|
||||||
|
// Val = Faction role of player
|
||||||
|
HashMap<String, VALID_FACTION_ROLES> factionPlayerList = new HashMap<String, VALID_FACTION_ROLES>();
|
||||||
|
// Key = Player DISPLAY name
|
||||||
|
// Val = Faction role of player
|
||||||
|
HashMap<String, VALID_FACTION_ROLES> DISPLAY_ONLY_LIST = new HashMap<String, VALID_FACTION_ROLES>();
|
||||||
|
|
||||||
|
// List contains UUID of players who are openly invited to this faction
|
||||||
|
List<String> openInvites = new ArrayList<String>();
|
||||||
|
|
||||||
|
Integer factionBankBalance;
|
||||||
|
Integer factionPower;
|
||||||
|
String factionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn CreateFaction
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] creatorUuid is the caller of the command's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] creatorDisplayName is the caller's display name
|
||||||
|
///
|
||||||
|
/// @brief Creates a faction on the server
|
||||||
|
///
|
||||||
|
/// @return True if a faction can be created, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean CreateFaction(String factionName, String creatorUuid, String creatorDisplayName) {
|
||||||
|
Boolean success = false;
|
||||||
|
if (!IsValid(factionName)) {
|
||||||
|
WriteableFaction newFaction = new WriteableFaction();
|
||||||
|
newFaction.factionPlayerList.put(creatorUuid, VALID_FACTION_ROLES.OWNER);
|
||||||
|
newFaction.DISPLAY_ONLY_LIST.put(creatorDisplayName, VALID_FACTION_ROLES.OWNER);
|
||||||
|
newFaction.factionBankBalance = 0;
|
||||||
|
newFaction.factionPower = 1;
|
||||||
|
allFactions.put(factionName, newFaction);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn DeleteFaction
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] creatorUuid is the caller of the command's UUID
|
||||||
|
///
|
||||||
|
/// @brief Deletes a faction on the server
|
||||||
|
///
|
||||||
|
/// @return True if a faction can be deleted, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean DeleteFaction(String factionName, String callerUuid) {
|
||||||
|
Boolean success = false;
|
||||||
|
// faction must exist
|
||||||
|
if (IsValid(factionName)) {
|
||||||
|
// faction must contain player
|
||||||
|
if (allFactions.get(factionName).factionPlayerList.containsKey(callerUuid)) {
|
||||||
|
// player must be owner of faction
|
||||||
|
if (allFactions.get(factionName).factionPlayerList.get(callerUuid) == VALID_FACTION_ROLES.OWNER) {
|
||||||
|
//TODO: BankManager will connect with this in future and the money of the faction must go somewhere!
|
||||||
|
allFactions.remove(factionName);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn CanInvite
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] creatorUuid is the caller of the command's UUID
|
||||||
|
///
|
||||||
|
/// @brief Determines if the player is capable of inviting another player
|
||||||
|
/// to the faction
|
||||||
|
///
|
||||||
|
/// @return True if player can invite another player, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private Boolean CanInvite(String factionName, String callerUuid) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (IsValid(factionName)) {
|
||||||
|
if (allFactions.get(factionName).factionPlayerList.containsKey(callerUuid)) {
|
||||||
|
VALID_FACTION_ROLES callerRole = allFactions.get(factionName).factionPlayerList.get(callerUuid);
|
||||||
|
if (callerRole == VALID_FACTION_ROLES.MANAGEMENT || callerRole == VALID_FACTION_ROLES.COOWNER || callerRole == VALID_FACTION_ROLES.OWNER) {
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IsOnInviteList
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] playerUuid is the caller of the command's UUID
|
||||||
|
///
|
||||||
|
/// @brief Checks to see if a player has been invited to a faction
|
||||||
|
///
|
||||||
|
/// @return True if player is on invite list, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private Boolean IsOnInviteList(String factionName, String playerUuid) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (IsValid(factionName)) {
|
||||||
|
if (allFactions.get(factionName).openInvites.contains(playerUuid)) {
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn AddToFaction
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] playerUuid is the caller of the command's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] playerDisplayName is the caller's display name
|
||||||
|
///
|
||||||
|
/// @brief Adds a player to a faction
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private void AddToFaction(String factionName, String playerUuid, String playerDisplayName) {
|
||||||
|
if (allFactions.containsKey(factionName)) {
|
||||||
|
allFactions.get(factionName).factionPlayerList.put(playerUuid, VALID_FACTION_ROLES.EMPLOYEE);
|
||||||
|
allFactions.get(factionName).DISPLAY_ONLY_LIST.put(playerDisplayName, VALID_FACTION_ROLES.EMPLOYEE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn InvitePlayerToFaction
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] callerUuid is the player inviting another player's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] invitedUuid is the player being invited's UUID
|
||||||
|
///
|
||||||
|
/// @brief Invites a player to a faction
|
||||||
|
///
|
||||||
|
/// @return True if player successfully can invite another player
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean InvitePlayerToFaction(String factionName, String callerUuid, String invitedUuid) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (CanInvite(factionName, callerUuid)) {
|
||||||
|
allFactions.get(factionName).openInvites.add(invitedUuid);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn JoinFaction
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] playerUuid is the player inviting another player's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] playerDisplayName is the player being invited's UUID
|
||||||
|
///
|
||||||
|
/// @brief Function to determine if a player can join a faction
|
||||||
|
///
|
||||||
|
/// @return True if they join, false if they cannot
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean JoinFaction(String factionName, String playerUuid, String playerDisplayName) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (IsOnInviteList(factionName, playerUuid) ) {
|
||||||
|
AddToFaction(factionName, playerUuid, playerDisplayName);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn LeaveFaction
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] playerUuid is the player inviting another player's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] playerName is the player being invited's UUID
|
||||||
|
///
|
||||||
|
/// @brief Function to let player leave a faction
|
||||||
|
///
|
||||||
|
/// @return True if they leave, false if they did not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean LeaveFaction(String factionName, String playerUuid, String playerName) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (IsValid(factionName)) {
|
||||||
|
allFactions.get(factionName).factionPlayerList.remove(playerUuid);
|
||||||
|
allFactions.get(factionName).DISPLAY_ONLY_LIST.remove(playerName);
|
||||||
|
|
||||||
|
// TODO: In future add ability if owner leave then promote next person
|
||||||
|
// Delete faction if all the players are gone
|
||||||
|
if (allFactions.get(factionName).factionPlayerList.size() == 0) {
|
||||||
|
allFactions.remove(factionName);
|
||||||
|
}
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn HasPlayer
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] playerUuid is the player inviting another player's UUID
|
||||||
|
///
|
||||||
|
/// @brief Determines if a faction has a specific player by UUID
|
||||||
|
///
|
||||||
|
/// @return True if they have the player, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private Boolean HasPlayer(String factionName, String playerUuid) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (IsValid(factionName)) {
|
||||||
|
success = allFactions.get(factionName).factionPlayerList.containsKey(playerUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn IsValid
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @brief Determines if a faction exists
|
||||||
|
///
|
||||||
|
/// @return True if a faction exists with the specified name, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean IsValid(String factionName) {
|
||||||
|
if (allFactions.containsKey(factionName)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn FindFactionOfPlayer
|
||||||
|
///
|
||||||
|
/// @param[in] playerUuid is the uuid of the player to find
|
||||||
|
///
|
||||||
|
/// @brief Determine the faction of a specified player
|
||||||
|
///
|
||||||
|
/// @return Returns the faction name of the player if the player is in
|
||||||
|
/// any faction. If the player is not found in any faction, an
|
||||||
|
/// empty string is returned
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public String FindFactionOfPlayer(String playerUuid) {
|
||||||
|
String faction = "";
|
||||||
|
|
||||||
|
System.out.println("Attempting to find player factions with uuid " + playerUuid);
|
||||||
|
for (Entry<String, WriteableFaction> entry : allFactions.entrySet()) {
|
||||||
|
if (entry.getValue().factionPlayerList.containsKey(playerUuid)) {
|
||||||
|
System.out.println("FAC [" + entry.getKey() + "]: PLAY-LIST: " + entry.getValue().factionPlayerList);
|
||||||
|
faction = entry.getKey();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return faction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn PromotePlayer
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] callerUuid is the caller of the command's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] promoteeUuid is the player to be promoted's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] promoteeDisplayName is the player ot be promoted's display name
|
||||||
|
///
|
||||||
|
/// @brief Attempts to promote a player in a faction. Whether or not a
|
||||||
|
/// player is promoted is determined by their level in the faction
|
||||||
|
/// and the promoter's level in the faction. Factors that can affect
|
||||||
|
/// this are:
|
||||||
|
/// 1. Both the caller and promotee must exist inside
|
||||||
|
/// the same faction
|
||||||
|
/// 2. The promoter must be a higher rank than the promotee
|
||||||
|
/// 3. The promotee's post-promotion rank still must be below
|
||||||
|
/// the promoter's rank
|
||||||
|
///
|
||||||
|
/// @return True if the player was successfully promoted, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean PromotePlayer(String factionName, String callerUuid, String promoteeUuid, String promoteeDisplayName) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (CanInvite(factionName, callerUuid) && HasPlayer(factionName, promoteeUuid)) {
|
||||||
|
VALID_FACTION_ROLES callerRole = allFactions.get(factionName).factionPlayerList.get(callerUuid);
|
||||||
|
VALID_FACTION_ROLES promoteeRole = allFactions.get(factionName).factionPlayerList.get(promoteeUuid);
|
||||||
|
Integer callerRoleLevel = ROLE_LEVELS.get(callerRole);
|
||||||
|
Integer promoteeRoleLevel = ROLE_LEVELS.get(promoteeRole);
|
||||||
|
|
||||||
|
// Factions is setup so that anyone can promote anybody UNDERNEATH them. However, you CANNOT promote a player to your level!
|
||||||
|
if (callerRoleLevel > promoteeRoleLevel + 1) {
|
||||||
|
// Get the new employee role
|
||||||
|
promoteeRole = ROLES_BY_LEVEL.get(promoteeRoleLevel + 1);
|
||||||
|
|
||||||
|
// Update role in faction
|
||||||
|
allFactions.get(factionName).factionPlayerList.put(promoteeUuid, promoteeRole);
|
||||||
|
allFactions.get(factionName).DISPLAY_ONLY_LIST.put(promoteeDisplayName, promoteeRole);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn CanKickPlayer
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] callerUuid is the caller of the command's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] kickeeUuid is the player to be kickee's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] kickeeDisplayName is the player ot be kickeeDisplayName's
|
||||||
|
/// display name
|
||||||
|
///
|
||||||
|
/// @brief Determines whether or not a player can be kicked. The caller
|
||||||
|
/// must be a higher rank to kick a player (and they both must
|
||||||
|
/// exist inside the faction)
|
||||||
|
///
|
||||||
|
/// @return True if the player was successfully kicked, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean CanKickPlayer(String factionName, String callerUuid, String kickeeUuid, String kickeeDisplayName) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (IsValid(factionName) && HasPlayer(factionName, kickeeUuid)) {
|
||||||
|
VALID_FACTION_ROLES callerRole = allFactions.get(factionName).factionPlayerList.get(callerUuid);
|
||||||
|
VALID_FACTION_ROLES kickeeRole = allFactions.get(factionName).factionPlayerList.get(kickeeUuid);
|
||||||
|
Integer callerRoleLevel = ROLE_LEVELS.get(callerRole);
|
||||||
|
Integer kickeeRoleLevel = ROLE_LEVELS.get(kickeeRole);
|
||||||
|
|
||||||
|
if (callerRoleLevel > kickeeRoleLevel) {
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn KickPlayer
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] callerUuid is the caller of the command's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] kickeeUuid is the player to be kickee's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] kickeeDisplayName is the player ot be kickeeDisplayName's
|
||||||
|
/// display name
|
||||||
|
///
|
||||||
|
/// @brief Kicks a player from a faction
|
||||||
|
///
|
||||||
|
/// @return True if the player was successfully kicked, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private Boolean KickPlayer(String factionName, String callerUuid, String kickeeUuid, String kickeeDisplayName) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (CanKickPlayer(factionName, callerUuid, kickeeUuid, kickeeDisplayName)) {
|
||||||
|
allFactions.get(factionName).factionPlayerList.remove(kickeeUuid);
|
||||||
|
allFactions.get(factionName).DISPLAY_ONLY_LIST.remove(kickeeDisplayName);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn DemotePlayer
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the name of the faction
|
||||||
|
///
|
||||||
|
/// @param[in] callerUuid is the caller of the command's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] demoteeUuid is the player to be promoted's UUID
|
||||||
|
///
|
||||||
|
/// @param[in] demoteeDisplayName is the player ot be promoted's display name
|
||||||
|
///
|
||||||
|
/// @brief Attempts to demote a player in a faction. Whether or not a
|
||||||
|
/// player is demoted is determined by their level in the faction
|
||||||
|
/// and the demoter's level in the faction. Factors that can affect
|
||||||
|
/// this are:
|
||||||
|
/// 1. Both the caller and demotee must exist inside
|
||||||
|
/// the same faction
|
||||||
|
/// 2. The demoter must be a higher rank than the promotee
|
||||||
|
/// 3. Should there be no lower rank left to demote to, the
|
||||||
|
/// player is kicked from the faction
|
||||||
|
///
|
||||||
|
/// @return True if the player was successfully demoted, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean DemotePlayer(String factionName, String callerUuid, String demoteeUuid, String demoteeDisplayName) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
if (CanInvite(factionName, callerUuid) && HasPlayer(factionName, demoteeUuid)) {
|
||||||
|
VALID_FACTION_ROLES callerRole = allFactions.get(factionName).factionPlayerList.get(callerUuid);
|
||||||
|
VALID_FACTION_ROLES demoteeRole = allFactions.get(factionName).factionPlayerList.get(demoteeUuid);
|
||||||
|
Integer callerRoleLevel = ROLE_LEVELS.get(callerRole);
|
||||||
|
Integer demoteeRoleLevel = ROLE_LEVELS.get(demoteeRole);
|
||||||
|
|
||||||
|
// Factions is setup so that anyone can demote anybody underneath them & the lowest level will cause a demotion to be a KICK from faction
|
||||||
|
if (callerRoleLevel > demoteeRoleLevel) {
|
||||||
|
// If the role level would be lower than bottom level, KICK player
|
||||||
|
if (demoteeRoleLevel - 1 < ROLE_LEVELS.get(VALID_FACTION_ROLES.EMPLOYEE)) {
|
||||||
|
success = KickPlayer(factionName, callerUuid, demoteeUuid, demoteeDisplayName);
|
||||||
|
} else {
|
||||||
|
// Regular demotion!
|
||||||
|
demoteeRole = ROLES_BY_LEVEL.get(demoteeRoleLevel - 1);
|
||||||
|
|
||||||
|
// Update faction
|
||||||
|
allFactions.get(factionName).factionPlayerList.put(demoteeUuid, demoteeRole);
|
||||||
|
allFactions.get(factionName).DISPLAY_ONLY_LIST.put(demoteeDisplayName, demoteeRole);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn ListOfAllFactions
|
||||||
|
///
|
||||||
|
/// @brief Get a list of all factions on the server
|
||||||
|
///
|
||||||
|
/// @return List of factions
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public List<String> ListOfAllFactions() {
|
||||||
|
List<String> facs = new ArrayList<String>();
|
||||||
|
|
||||||
|
System.out.println("ListOfFactions - map size: " + allFactions.size());
|
||||||
|
for (Entry<String, WriteableFaction> entry : allFactions.entrySet()) {
|
||||||
|
System.out.println("Adding fac " + entry.getKey() + " to fac");
|
||||||
|
facs.add(entry.getKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
return facs;
|
||||||
|
}
|
||||||
|
}
|
232
src/main/java/jesse/keeblarcraft/FactionMgr/FactionManager.java
Normal file
232
src/main/java/jesse/keeblarcraft/FactionMgr/FactionManager.java
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* FactionManager
|
||||||
|
*
|
||||||
|
* Class is responsible for keeping track of factions chosen by the players in the game and saves to the configuration
|
||||||
|
* file for persistent data storage. Class handles checks as well for eligibility purposes (making sure players can join, etc)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package jesse.keeblarcraft.FactionMgr;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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.network.ServerPlayerEntity;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
public class FactionManager {
|
||||||
|
private static String FACTION_CFG_FILE = "config/keeblarcraft/factions/factions.json";
|
||||||
|
ConfigManager config = new ConfigManager();
|
||||||
|
private static FactionManager static_inst;
|
||||||
|
|
||||||
|
public static FactionManager GetInstance() {
|
||||||
|
if (static_inst == null) {
|
||||||
|
static_inst = new FactionManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
return static_inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FactionConfigClassWrapper {
|
||||||
|
FactionConfig factions = new FactionConfig();
|
||||||
|
}
|
||||||
|
FactionConfigClassWrapper factionConfig;// = new FactionConfigClassWrapper();
|
||||||
|
|
||||||
|
|
||||||
|
// Constructor
|
||||||
|
public FactionManager() {
|
||||||
|
// Read in config at start of object
|
||||||
|
System.out.println("FACTIONMANAGER CONSTRUCTOR CALLED");
|
||||||
|
Boolean existingFile = false;
|
||||||
|
factionConfig = new FactionConfigClassWrapper();
|
||||||
|
|
||||||
|
Boolean tmpchck = factionConfig == null;
|
||||||
|
System.out.println("Is factionConfig null still? " + (tmpchck ? "YES" : "NO"));
|
||||||
|
try {
|
||||||
|
factionConfig = config.GetJsonObjectFromFile(FACTION_CFG_FILE, FactionConfigClassWrapper.class);
|
||||||
|
tmpchck = factionConfig == null;
|
||||||
|
System.out.println("Is factionconfig null after trying to load stuff? " + (tmpchck ? "YES" : "NO"));
|
||||||
|
existingFile = true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the file if it didn't exist before
|
||||||
|
if (!existingFile)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
config.CreateDirectory(FACTION_CFG_FILE);
|
||||||
|
FlashConfig();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (factionConfig == null) {
|
||||||
|
// the only way for this to be possible is if the read-in was bad. flash config file then try again
|
||||||
|
factionConfig = new FactionConfigClassWrapper();
|
||||||
|
|
||||||
|
//TODO: Add safe-guard in here to check if default faction dir exists and move it to OLD/CORRUPTED (so data is not nuked from orbit)
|
||||||
|
factionConfig.factions = new FactionConfig();
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn LeaveFaction
|
||||||
|
///
|
||||||
|
/// @param[in] player is the player on the server
|
||||||
|
///
|
||||||
|
/// @brief Leave a faction
|
||||||
|
///
|
||||||
|
/// @return True if player can leave their faction, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean LeaveFaction(ServerPlayerEntity player) {
|
||||||
|
Boolean success = false;
|
||||||
|
|
||||||
|
String playerFac = factionConfig.factions.FindFactionOfPlayer(player.getUuidAsString());
|
||||||
|
|
||||||
|
if (playerFac != "") {
|
||||||
|
success = factionConfig.factions.LeaveFaction(playerFac, player.getUuidAsString(), player.getDisplayName().toString());
|
||||||
|
player.sendMessage(Text.of("[Factions]: You left your faction!"));
|
||||||
|
} else {
|
||||||
|
player.sendMessage(Text.of("[Factions]: You are not in a faction!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn CreateFaction
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the faction to be created
|
||||||
|
///
|
||||||
|
/// @param[in] player is the player on the server
|
||||||
|
///
|
||||||
|
/// @brief Create a new faction
|
||||||
|
///
|
||||||
|
/// @return True if successfully created, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean CreateFaction(String factionName, ServerPlayerEntity creator) {
|
||||||
|
Boolean success = false;
|
||||||
|
String facOfPlayer = factionConfig.factions.FindFactionOfPlayer(creator.getUuidAsString());
|
||||||
|
|
||||||
|
if (facOfPlayer == "") {
|
||||||
|
success = factionConfig.factions.CreateFaction(factionName, creator.getUuidAsString(), creator.getDisplayName().toString());
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
creator.sendMessage(Text.of("[Factions]: Could not create faction - faction already exists."));
|
||||||
|
} else {
|
||||||
|
creator.sendMessage(Text.of("[Factions]: Successfully created faction!"));
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
creator.sendMessage(Text.of("[Factions]: You are already in a faction! You cannot create one."));
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn DeleteFaction
|
||||||
|
///
|
||||||
|
/// @param[in] factionName is the faction to be created
|
||||||
|
///
|
||||||
|
/// @param[in] caller is the player on the server
|
||||||
|
///
|
||||||
|
/// @brief Delete a faction
|
||||||
|
///
|
||||||
|
/// @return True if successfully deleted, false if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean DeleteFaction(String factionName, ServerPlayerEntity caller) {
|
||||||
|
Boolean success = factionConfig.factions.DeleteFaction(factionName, caller.getUuidAsString());
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
caller.sendMessage(Text.of("[Factions]: Could not delete faction. You must be owner & faction must exist."));
|
||||||
|
} else {
|
||||||
|
caller.sendMessage(Text.of("[Factions]: Successfully deleted faction."));
|
||||||
|
FlashConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn ListOfFactions
|
||||||
|
///
|
||||||
|
/// @brief Get a list of all factions on the server
|
||||||
|
///
|
||||||
|
/// @return Faction list. Empty list if no factions
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public List<String> ListOfFactions() {
|
||||||
|
System.out.println("Callthrough of listoffactions");
|
||||||
|
return factionConfig.factions.ListOfAllFactions();
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn GetFactionOfPlayer
|
||||||
|
///
|
||||||
|
/// @param[in] playerUuid is the uuid of the player
|
||||||
|
///
|
||||||
|
/// @brief Gets the faction of a player on the server
|
||||||
|
///
|
||||||
|
/// @return String with faction name. Empty string if no faction tie
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public String GetFactionOfPlayer(String playerUuid) {
|
||||||
|
return factionConfig.factions.FindFactionOfPlayer(playerUuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean PromotePlayer(ServerPlayerEntity caller, String promoteeUuid, String promoteeDisplayName) {
|
||||||
|
Boolean success = factionConfig.factions.PromotePlayer(GetFactionOfPlayer(caller.getUuidAsString()), caller.getUuidAsString(), promoteeUuid, promoteeDisplayName);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
caller.sendMessage(Text.of("[Factions]: Could not promote player - you need to be a higher rank than them and they cannot be promoted to your level!"));
|
||||||
|
} else {
|
||||||
|
caller.sendMessage(Text.of("[Factions]: Successfully promoted player!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn DemotePlayer
|
||||||
|
///
|
||||||
|
/// @param[in] caller is the player who is demoting another player
|
||||||
|
///
|
||||||
|
/// @param[in] demoteeUuid is the player's uuid who is being demoted
|
||||||
|
///
|
||||||
|
/// @param[in] demoteeDisplayName is the players display name who is being demoted
|
||||||
|
///
|
||||||
|
/// @brief Demote a player from a faction
|
||||||
|
///
|
||||||
|
/// @return True if player is demoted. False if not
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public Boolean DemotePlayer(ServerPlayerEntity caller, String demoteeUuid, String demoteeDisplayName) {
|
||||||
|
Boolean success = factionConfig.factions.DemotePlayer(GetFactionOfPlayer(caller.getUuidAsString()), caller.getUuidAsString(), demoteeUuid, demoteeDisplayName);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
caller.sendMessage(Text.of("[Factions]: Could not demote player - you need to be a higher rank than them to demote them!"));
|
||||||
|
} else {
|
||||||
|
caller.sendMessage(Text.of("[Factions]: Successfully demoted player!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn FlashConfig
|
||||||
|
///
|
||||||
|
/// @brief Update the faction configuration file on disk
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public void FlashConfig() {
|
||||||
|
try {
|
||||||
|
config.WriteToJsonFile(FACTION_CFG_FILE, factionConfig);
|
||||||
|
} catch (FILE_WRITE_EXCEPTION e) {
|
||||||
|
System.out.println("config writing of faction file failed. oh well!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
/*
|
|
||||||
*
|
|
||||||
* TeamManager
|
|
||||||
*
|
|
||||||
* Class is responsible for keeping track of teams/factions chosen by the players in the game and saves to the configuration
|
|
||||||
* file for persistent data storage. Class handles checks as well for eligibility purposes (making sure players can join, etc)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
package jesse.keeblarcraft.FactionMgr;
|
|
||||||
|
|
||||||
public class TeamManager {
|
|
||||||
// Class controls managing teams and pulling from configuration file and loading to configuration file
|
|
||||||
|
|
||||||
}
|
|
@ -12,11 +12,25 @@
|
|||||||
package jesse.keeblarcraft;
|
package jesse.keeblarcraft;
|
||||||
|
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.entity.event.v1.ServerEntityWorldChangeEvents;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
|
||||||
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents.ServerStopping;
|
||||||
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
|
||||||
|
import net.kyrptonaught.customportalapi.api.CustomPortalBuilder;
|
||||||
|
import net.minecraft.block.AbstractBlock;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
import net.minecraft.entity.EntityDimensions;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.registry.Registries;
|
import net.minecraft.registry.Registries;
|
||||||
import net.minecraft.registry.Registry;
|
import net.minecraft.registry.Registry;
|
||||||
import net.minecraft.resource.featuretoggle.FeatureSet;
|
import net.minecraft.resource.featuretoggle.FeatureSet;
|
||||||
import net.minecraft.screen.ScreenHandlerType;
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -24,9 +38,15 @@ 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.CustomBlocks.BlockEntities.MagicChestBlockEntity;
|
||||||
|
// import jesse.keeblarcraft.CustomBlocks.Blocks.MagicChestBlock;
|
||||||
import jesse.keeblarcraft.CustomItems.ItemManager;
|
import jesse.keeblarcraft.CustomItems.ItemManager;
|
||||||
|
import jesse.keeblarcraft.CustomItems.PickAxeRegister;
|
||||||
|
import jesse.keeblarcraft.EventMgr.DimensionLoadingEvent;
|
||||||
|
import jesse.keeblarcraft.EventMgr.PlayerJoinListener;
|
||||||
import jesse.keeblarcraft.EventMgr.ServerTickListener;
|
import jesse.keeblarcraft.EventMgr.ServerTickListener;
|
||||||
import jesse.keeblarcraft.GuiMgr.TreeHandler;
|
import jesse.keeblarcraft.GuiMgr.TreeHandler;
|
||||||
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
|
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
|
||||||
@ -44,6 +64,12 @@ public class Keeblarcraft implements ModInitializer {
|
|||||||
Identifier.of(Keeblarcraft.MOD_ID, "tree_gui"),
|
Identifier.of(Keeblarcraft.MOD_ID, "tree_gui"),
|
||||||
new ScreenHandlerType<>(TreeHandler::new, FeatureSet.empty()));
|
new ScreenHandlerType<>(TreeHandler::new, FeatureSet.empty()));
|
||||||
|
|
||||||
|
// public static final Block MAGIC_CHEST_BLOCK = Registry.register(Registries.BLOCK, Identifier.of(Keeblarcraft.MOD_ID, "magic_chest_block"),
|
||||||
|
// new MagicChestBlock(AbstractBlock.Settings.copy(Blocks.CHEST)));
|
||||||
|
|
||||||
|
// public static final BlockEntityType<MagicChestBlockEntity> MAGIC_CHEST_BLOCK_ENTITY = Registry.register(Registry.BLOCK_ENTITY_TYPE,
|
||||||
|
// Identifier.of(Keeblarcraft.MOD_ID, "magic_chest_block_entity"), BlockEntityType.Builder.create(MagicChestBlockEntity::new, MAGIC_CHEST_BLOCK).build());
|
||||||
|
|
||||||
CustomCommandManager cmdMgr = new CustomCommandManager();
|
CustomCommandManager cmdMgr = new CustomCommandManager();
|
||||||
Setup setup = Setup.GetInstance();
|
Setup setup = Setup.GetInstance();
|
||||||
|
|
||||||
@ -63,12 +89,16 @@ public class Keeblarcraft implements ModInitializer {
|
|||||||
// This is a very special case where this must be in this classes' initializer
|
// This is a very special case where this must be in this classes' initializer
|
||||||
// method
|
// method
|
||||||
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
|
||||||
var player = handler.player;
|
// var player = handler.player;
|
||||||
Keeblarcraft.LOGGER.info("Player " + player.getName() + " has logged in. Creating tree...");
|
// Keeblarcraft.LOGGER.info("Player " + player.getName() + " has logged in. Creating tree...");
|
||||||
|
// player.sendMessage(Text.of("Welcome to the Keeblcraft RPG Server!"));
|
||||||
|
|
||||||
if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == false) {
|
// if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == false) {
|
||||||
AttributeMgr.activeTrees.put(player.getUuidAsString(), new AttributeTree(player.getUuidAsString()));
|
// AttributeMgr.activeTrees.put(player.getUuidAsString(), new AttributeTree(player.getUuidAsString()));
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
System.out.println("ServerPlayConnectionEvents.JOIN called");
|
||||||
|
PlayerJoinListener.GetInstance().HandleServerJoinEvent(handler, sender, server);
|
||||||
});
|
});
|
||||||
|
|
||||||
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
|
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
|
||||||
@ -80,6 +110,17 @@ public class Keeblarcraft implements ModInitializer {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ServerEntityWorldChangeEvents.AFTER_PLAYER_CHANGE_WORLD.register((player, origin, destination) -> {
|
||||||
|
System.out.println("Calling back...");
|
||||||
|
DimensionLoadingEvent.GetInstance().HandleWorldMove(player, origin, destination);
|
||||||
|
});
|
||||||
|
|
||||||
|
ServerLifecycleEvents.SERVER_STOPPING.register((server) ->{
|
||||||
|
// Stuff here
|
||||||
|
System.out.println("SERVER_STOPPING callback called.");
|
||||||
|
DimensionLoadingEvent.GetInstance().SaveInventories();
|
||||||
|
});
|
||||||
|
|
||||||
// Initialize our ticks!!
|
// Initialize our ticks!!
|
||||||
ServerTickListener.InitializeServerTicks();
|
ServerTickListener.InitializeServerTicks();
|
||||||
|
|
||||||
@ -90,6 +131,12 @@ public class Keeblarcraft implements ModInitializer {
|
|||||||
// Register attributes
|
// Register attributes
|
||||||
AttributeMgr.RegisterAttributes();
|
AttributeMgr.RegisterAttributes();
|
||||||
|
|
||||||
|
// Register Handhelds <== put any handhelds inside this class and make static
|
||||||
|
PickAxeRegister.registerHandhelds();
|
||||||
|
|
||||||
|
// 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
|
||||||
@ -98,6 +145,17 @@ public class Keeblarcraft implements ModInitializer {
|
|||||||
// Register blocks
|
// Register blocks
|
||||||
BlockList.RegisterBlocks();
|
BlockList.RegisterBlocks();
|
||||||
|
|
||||||
|
// World generation
|
||||||
|
|
||||||
|
// Custom portal generator
|
||||||
|
System.out.println("BUILDING CUSTOM PORTAL");
|
||||||
|
CustomPortalBuilder.beginPortal()
|
||||||
|
.frameBlock(Blocks.GOLD_BLOCK)
|
||||||
|
.lightWithItem(Items.ENDER_EYE)
|
||||||
|
.destDimID(new Identifier(Keeblarcraft.MOD_ID, "keeblarcraftdim"))
|
||||||
|
.tintColor(234, 183, 8)
|
||||||
|
.registerPortal();
|
||||||
|
|
||||||
|
|
||||||
} catch (SETUP_FAILED_EXCEPTION e) {
|
} catch (SETUP_FAILED_EXCEPTION e) {
|
||||||
System.out.println(ChatUtil.ColoredString("ERROR. Setup failed to initialize environment. Mod likely does not have read/write permissions inside area. Mod will now close out.", CONSOLE_COLOR.RED));
|
System.out.println(ChatUtil.ColoredString("ERROR. Setup failed to initialize environment. Mod likely does not have read/write permissions inside area. Mod will now close out.", CONSOLE_COLOR.RED));
|
||||||
|
@ -11,12 +11,7 @@ package jesse.keeblarcraft.Utils;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.text.MutableText;
|
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
public class ChatUtil {
|
public class ChatUtil {
|
||||||
//This is a private class only used internally to get ANSI colors
|
//This is a private class only used internally to get ANSI colors
|
||||||
|
20
src/main/java/jesse/keeblarcraft/Utils/DirectionalVec.java
Normal file
20
src/main/java/jesse/keeblarcraft/Utils/DirectionalVec.java
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package jesse.keeblarcraft.Utils;
|
||||||
|
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @class DirectionalVec
|
||||||
|
///
|
||||||
|
/// @brief DirectionalVec creates a vector of information that can store
|
||||||
|
/// world information and a players vector information of where they
|
||||||
|
/// are in the world + where their camera is looking (yaw & pitch)
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public class DirectionalVec {
|
||||||
|
public RegistryKey<World> world;
|
||||||
|
public double x;
|
||||||
|
public double y;
|
||||||
|
public double z;
|
||||||
|
public float yaw;
|
||||||
|
public float pitch;
|
||||||
|
}
|
219
src/main/java/jesse/keeblarcraft/Utils/HelpBuilder.java
Normal file
219
src/main/java/jesse/keeblarcraft/Utils/HelpBuilder.java
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
package jesse.keeblarcraft.Utils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.text.ClickEvent;
|
||||||
|
import net.minecraft.text.HoverEvent;
|
||||||
|
import net.minecraft.text.MutableText;
|
||||||
|
import net.minecraft.text.Style;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
public class HelpBuilder {
|
||||||
|
private String COLOR_START = "§";
|
||||||
|
private String COLOR_END = "§f";
|
||||||
|
public enum COLOR_CODE {
|
||||||
|
BLUE,
|
||||||
|
GRAY,
|
||||||
|
GOLD,
|
||||||
|
RED,
|
||||||
|
GREEN
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn getColor
|
||||||
|
///
|
||||||
|
/// @param[in] code is the color code that is desired
|
||||||
|
///
|
||||||
|
/// @brief Returns the MINECRAFT color code in string form to help build
|
||||||
|
/// colored messages for players
|
||||||
|
///
|
||||||
|
/// @return String representation of color code
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
private String getColor(COLOR_CODE code) {
|
||||||
|
String colorStr = COLOR_START;
|
||||||
|
switch(code) {
|
||||||
|
case BLUE:
|
||||||
|
return colorStr + "9";
|
||||||
|
case GRAY:
|
||||||
|
return colorStr + "7";
|
||||||
|
case GOLD:
|
||||||
|
return colorStr + "6";
|
||||||
|
case RED:
|
||||||
|
return colorStr + "4";
|
||||||
|
case GREEN:
|
||||||
|
return colorStr + "2";
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this code is reachable, then someone has not properly handled the above switch-case
|
||||||
|
return colorStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn MakeCopyableTxt
|
||||||
|
///
|
||||||
|
/// @param[in] terminalTxt is the text to be seen on screen
|
||||||
|
///
|
||||||
|
/// @param[in] hoverTxt is the desired text to be seen in a new hover event
|
||||||
|
///
|
||||||
|
/// @param[in] copyInt is an integer argument that can be copied when the
|
||||||
|
/// player clicks on the chat message
|
||||||
|
///
|
||||||
|
/// @brief Creates a copyable text block for the player
|
||||||
|
///
|
||||||
|
/// @return MutableText of text intended to be used to send to player
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public MutableText MakeCopyableTxt(String terminalTxt, String hoverTxt, Integer copyInt) {
|
||||||
|
return MakeCopyableTxt(terminalTxt, hoverTxt, Integer.toString(copyInt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn MakeCopyableTxt
|
||||||
|
///
|
||||||
|
/// @param[in] terminalTxt is the text to be seen on screen
|
||||||
|
///
|
||||||
|
/// @param[in] hoverTxt is the desired text to be seen in a new hover event
|
||||||
|
///
|
||||||
|
/// @param[in] expandedList takes in a list of strings that can be copied
|
||||||
|
/// when the player clicks on a chat message
|
||||||
|
///
|
||||||
|
/// @brief Creates a copyable text block for the player
|
||||||
|
///
|
||||||
|
/// @return MutableText of text intended to be used to send to player
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public MutableText MakeCopyableTxt(String terminalTxt, String hoverTxt, List<String> expandedList) {
|
||||||
|
String expanded = "[";
|
||||||
|
int index = 0;
|
||||||
|
for (String str : expandedList) {
|
||||||
|
expanded += str;
|
||||||
|
|
||||||
|
// Add delimiter if next index is not at size
|
||||||
|
if (++index < expandedList.size()) {
|
||||||
|
expanded += ",";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expanded += "]";
|
||||||
|
|
||||||
|
return MakeCopyableTxt(terminalTxt, hoverTxt, expanded);
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn MakeCopyableTxt
|
||||||
|
///
|
||||||
|
/// @param[in] terminalTxt is the text to be seen on screen
|
||||||
|
///
|
||||||
|
/// @param[in] hoverTxt is the desired text to be seen in a new hover event
|
||||||
|
///
|
||||||
|
/// @param[in] copyStr is a regular string that can be copied when the player
|
||||||
|
/// clicks on a chat message
|
||||||
|
///
|
||||||
|
/// @brief Creates a copyable text block for the player
|
||||||
|
///
|
||||||
|
/// @return MutableText of text intended to be used to send to player
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public MutableText MakeCopyableTxt(String terminalTxt, String hoverTxt, String copyStr) {
|
||||||
|
Text copyableText = Text.of(terminalTxt);
|
||||||
|
MutableText testTxt = (MutableText) copyableText;
|
||||||
|
System.out.println("Making hoverable stuff");
|
||||||
|
testTxt.setStyle(Style.EMPTY.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, copyStr))
|
||||||
|
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of(hoverTxt))));
|
||||||
|
System.out.println("Done making hoverable stuff");
|
||||||
|
|
||||||
|
System.out.println("Value of copyAbleText: " + copyableText.getString());
|
||||||
|
System.out.println("Value of testTxt: " + testTxt.getString());
|
||||||
|
|
||||||
|
return testTxt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn ColorMsg
|
||||||
|
///
|
||||||
|
/// @param[in] msg is an integer message that is desired to be colored
|
||||||
|
///
|
||||||
|
/// @param[in] color is the color option
|
||||||
|
///
|
||||||
|
/// @brief Creates a formatted string that will be colored at the
|
||||||
|
/// specification of the developer
|
||||||
|
///
|
||||||
|
/// @return Formatted string of colored text
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public String ColorMsg(Integer msg, COLOR_CODE color) {
|
||||||
|
return getColor(color) + msg + COLOR_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn ColorMsg
|
||||||
|
///
|
||||||
|
/// @param[in] msg is a list of strings that is desired to all be colored
|
||||||
|
/// the same
|
||||||
|
///
|
||||||
|
/// @param[in] color is the color option
|
||||||
|
///
|
||||||
|
/// @brief Creates a formatted list of strings that will be colored
|
||||||
|
/// at the specification of the developer and will be returned as
|
||||||
|
/// a list
|
||||||
|
///
|
||||||
|
/// @return Formatted list of strings
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public List<String> ColorMsg(List<String> msg, COLOR_CODE color) {
|
||||||
|
List<String> retList = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (String str : msg) {
|
||||||
|
retList.add(getColor(color) + str + COLOR_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
return retList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn ColorMsg
|
||||||
|
///
|
||||||
|
/// @param[in] msg to be formatted
|
||||||
|
///
|
||||||
|
/// @param[in] color is the color option
|
||||||
|
///
|
||||||
|
/// @brief Creates a formatted string that will be colored at the
|
||||||
|
/// specification of the developer
|
||||||
|
///
|
||||||
|
/// @return Formatted string of colored text
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public String ColorMsg(String msg, COLOR_CODE color) {
|
||||||
|
return getColor(color) + msg + COLOR_END;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parses a help command and color codes it. assume everything up to first '.' is the
|
||||||
|
// help cmd usage and color it with primaryColor. secondaryColor applied to rest
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @fn FormatMsg
|
||||||
|
///
|
||||||
|
/// @param[in] helpCmd is outsourced as an intentional help message. The
|
||||||
|
/// string expects the initial format to stop with a '.'
|
||||||
|
/// delimiter.
|
||||||
|
///
|
||||||
|
/// @param[in] primaryColor is the color of the string up to the delimiter
|
||||||
|
///
|
||||||
|
/// @param[in] secondaryColor is the color after the delimiter
|
||||||
|
///
|
||||||
|
/// @brief Creates a formatted string
|
||||||
|
///
|
||||||
|
/// @return Formatted string of colored text
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
public String FormatMsg(String helpCmd, COLOR_CODE primaryColor, COLOR_CODE secondaryColor) {
|
||||||
|
String coloredStr = getColor(primaryColor);
|
||||||
|
List<String> splitStr = List.of(helpCmd.split("\\."));
|
||||||
|
|
||||||
|
Boolean isFirst = true;
|
||||||
|
for (String str : splitStr) {
|
||||||
|
if (isFirst) {
|
||||||
|
coloredStr += str;
|
||||||
|
isFirst = false;
|
||||||
|
coloredStr += getColor(secondaryColor);
|
||||||
|
} else {
|
||||||
|
coloredStr += str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return coloredStr + COLOR_END;
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,7 @@ import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
|
|||||||
// If we do not have these, or only partial - then functionality may be disabled for runtime performance
|
// If we do not have these, or only partial - then functionality may be disabled for runtime performance
|
||||||
public final class Setup {
|
public final class Setup {
|
||||||
private static Setup static_inst;
|
private static Setup static_inst;
|
||||||
|
private static String GLOBAL_CONFIG = "config/keeblarcraft/";
|
||||||
|
|
||||||
public Setup() {
|
public Setup() {
|
||||||
System.out.println(ChatUtil.ColoredString("Running system setup and checks...", CONSOLE_COLOR.BLUE));
|
System.out.println(ChatUtil.ColoredString("Running system setup and checks...", CONSOLE_COLOR.BLUE));
|
||||||
@ -50,22 +51,24 @@ public final class Setup {
|
|||||||
|
|
||||||
// First time setup variables
|
// First time setup variables
|
||||||
private static final List<String> DIRECTORY_LIST = new ArrayList<String>() {{
|
private static final List<String> DIRECTORY_LIST = new ArrayList<String>() {{
|
||||||
add("notes"); // Expect 1 file per player!
|
add(GLOBAL_CONFIG); // inside config dir
|
||||||
add("factions"); // Expect 1 file per faction!
|
add(GLOBAL_CONFIG + "notes"); // Expect 1 file per player!
|
||||||
add("story"); // Expect 1 file per story chapter!
|
add(GLOBAL_CONFIG + "factions"); // Expect 1 file per faction!
|
||||||
add("commands"); // Expect 1 file per command that's configurable!
|
add(GLOBAL_CONFIG + "story"); // Expect 1 file per story chapter!
|
||||||
add("events"); // Expect 1 file per event that is configurable!
|
add(GLOBAL_CONFIG + "commands"); // Expect 1 file per command that's configurable!
|
||||||
add("bank");
|
add(GLOBAL_CONFIG + "events"); // Expect 1 file per event that is configurable!
|
||||||
add("attributes");
|
add(GLOBAL_CONFIG + "bank");
|
||||||
|
add(GLOBAL_CONFIG + "attributes");
|
||||||
|
add(GLOBAL_CONFIG + "misc");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// These will be top-level config files above the directories this mod creates
|
// These will be top-level config files above the directories this mod creates
|
||||||
private static final List<String> FILE_LIST = new ArrayList<String>() {{
|
private static final List<String> FILE_LIST = new ArrayList<String>() {{
|
||||||
add("story/general_story_config.json"); // Big config file, determines when players can do certain things at different story levels
|
add(GLOBAL_CONFIG + "story/general_story_config.json"); // Big config file, determines when players can do certain things at different story levels
|
||||||
add("factions/general_factions_config.json"); // General configuration file for factions stuff
|
add(GLOBAL_CONFIG + "factions/general_factions_config.json"); // General configuration file for factions stuff
|
||||||
add("events/general_event_config.json"); // General configuration file for story events!
|
add(GLOBAL_CONFIG + "events/general_event_config.json"); // General configuration file for story events!
|
||||||
add("general.json"); // The super general configuration file! (May be removed)
|
add(GLOBAL_CONFIG + "general.json"); // The super general configuration file! (May be removed)
|
||||||
add("attributes/general_attribute_config.json");
|
add(GLOBAL_CONFIG + "attributes/general_attribute_config.json");
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// RunChecks()
|
// RunChecks()
|
||||||
|
28
src/main/java/jesse/keeblarcraft/datagen/WorldGenerator.java
Normal file
28
src/main/java/jesse/keeblarcraft/datagen/WorldGenerator.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package jesse.keeblarcraft.datagen;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.provider.FabricDynamicRegistryProvider;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.registry.RegistryWrapper;
|
||||||
|
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||||
|
|
||||||
|
public class WorldGenerator extends FabricDynamicRegistryProvider {
|
||||||
|
|
||||||
|
public WorldGenerator(FabricDataOutput output, CompletableFuture<RegistryWrapper.WrapperLookup> registriesFeature) {
|
||||||
|
super(output, registriesFeature);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Keeblarcraft World Generation";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void configure(WrapperLookup registries, Entries entries) {
|
||||||
|
entries.addAll(registries.getWrapperOrThrow(RegistryKeys.PLACED_FEATURE));
|
||||||
|
entries.addAll(registries.getWrapperOrThrow(RegistryKeys.BIOME));
|
||||||
|
entries.addAll(registries.getWrapperOrThrow(RegistryKeys.DIMENSION_TYPE));
|
||||||
|
}
|
||||||
|
}
|
26
src/main/java/jesse/keeblarcraft/world/DataGeneration.java
Normal file
26
src/main/java/jesse/keeblarcraft/world/DataGeneration.java
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package jesse.keeblarcraft.world;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.datagen.WorldGenerator;
|
||||||
|
import jesse.keeblarcraft.world.biome.ModBiomes;
|
||||||
|
import jesse.keeblarcraft.world.dimension.ModDimensions;
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint;
|
||||||
|
import net.fabricmc.fabric.api.datagen.v1.FabricDataGenerator;
|
||||||
|
import net.minecraft.registry.RegistryBuilder;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
|
||||||
|
public class DataGeneration implements DataGeneratorEntrypoint {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) {
|
||||||
|
FabricDataGenerator.Pack pack = fabricDataGenerator.createPack();
|
||||||
|
|
||||||
|
pack.addProvider(WorldGenerator::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void buildRegistry(RegistryBuilder registryBuilder) {
|
||||||
|
registryBuilder.addRegistry(RegistryKeys.BIOME, ModBiomes::bootstrap);
|
||||||
|
registryBuilder.addRegistry(RegistryKeys.DIMENSION_TYPE, ModDimensions::bootstrapType);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
140
src/main/java/jesse/keeblarcraft/world/ImplementedInventory.java
Normal file
140
src/main/java/jesse/keeblarcraft/world/ImplementedInventory.java
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
package jesse.keeblarcraft.world;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.inventory.Inventories;
|
||||||
|
import net.minecraft.inventory.Inventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.collection.DefaultedList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple {@code Inventory} implementation with only default methods + an item
|
||||||
|
* list getter.
|
||||||
|
*
|
||||||
|
* @author Juuz
|
||||||
|
*
|
||||||
|
* @from https://wiki.fabricmc.net/tutorial:inventory
|
||||||
|
*/
|
||||||
|
public interface ImplementedInventory extends Inventory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the item list of this inventory.
|
||||||
|
* Must return the same instance every time it's called.
|
||||||
|
*/
|
||||||
|
DefaultedList<ItemStack> getItems();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an inventory from the item list.
|
||||||
|
*/
|
||||||
|
static ImplementedInventory of(DefaultedList<ItemStack> items) {
|
||||||
|
return () -> items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new inventory with the specified size.
|
||||||
|
*/
|
||||||
|
static ImplementedInventory ofSize(int size) {
|
||||||
|
return of(DefaultedList.ofSize(size, ItemStack.EMPTY));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the inventory size.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default int size() {
|
||||||
|
return getItems().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the inventory is empty.
|
||||||
|
*
|
||||||
|
* @return true if this inventory has only empty stacks, false otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default boolean isEmpty() {
|
||||||
|
for (int i = 0; i < size(); i++) {
|
||||||
|
ItemStack stack = getStack(i);
|
||||||
|
if (!stack.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the item in the slot.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default ItemStack getStack(int slot) {
|
||||||
|
return getItems().get(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes items from an inventory slot.
|
||||||
|
*
|
||||||
|
* @param slot The slot to remove from.
|
||||||
|
* @param count How many items to remove. If there are less items in the slot
|
||||||
|
* than what are requested,
|
||||||
|
* takes all items in that slot.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default ItemStack removeStack(int slot, int count) {
|
||||||
|
ItemStack result = Inventories.splitStack(getItems(), slot, count);
|
||||||
|
if (!result.isEmpty()) {
|
||||||
|
markDirty();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all items from an inventory slot.
|
||||||
|
*
|
||||||
|
* @param slot The slot to remove from.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default ItemStack removeStack(int slot) {
|
||||||
|
return Inventories.removeStack(getItems(), slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the current stack in an inventory slot with the provided stack.
|
||||||
|
*
|
||||||
|
* @param slot The inventory slot of which to replace the itemstack.
|
||||||
|
* @param stack The replacing itemstack. If the stack is too big for
|
||||||
|
* this inventory ({@link Inventory#getMaxCountPerStack()}),
|
||||||
|
* it gets resized to this inventory's maximum amount.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default void setStack(int slot, ItemStack stack) {
|
||||||
|
getItems().set(slot, stack);
|
||||||
|
if (stack.getCount() > stack.getMaxCount()) {
|
||||||
|
stack.setCount(stack.getMaxCount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the inventory.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default void clear() {
|
||||||
|
getItems().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the state as dirty.
|
||||||
|
* Must be called after changes in the inventory, so that the game can properly
|
||||||
|
* save
|
||||||
|
* the inventory contents and notify neighboring blocks of inventory changes.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default void markDirty() {
|
||||||
|
// Override if you want behavior.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the player can use the inventory, false otherwise.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
default boolean canPlayerUse(PlayerEntity player) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
68
src/main/java/jesse/keeblarcraft/world/biome/ModBiomes.java
Normal file
68
src/main/java/jesse/keeblarcraft/world/biome/ModBiomes.java
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package jesse.keeblarcraft.world.biome;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.Keeblarcraft;
|
||||||
|
import net.minecraft.registry.Registerable;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.biome.BiomeEffects;
|
||||||
|
import net.minecraft.world.biome.GenerationSettings;
|
||||||
|
import net.minecraft.world.biome.SpawnSettings;
|
||||||
|
import net.minecraft.world.gen.GenerationStep;
|
||||||
|
import net.minecraft.world.gen.feature.DefaultBiomeFeatures;
|
||||||
|
import net.minecraft.world.gen.feature.VegetationPlacedFeatures;
|
||||||
|
|
||||||
|
public class ModBiomes {
|
||||||
|
public static final RegistryKey<Biome> TEST_BIOME = RegistryKey.of(RegistryKeys.BIOME,
|
||||||
|
new Identifier(Keeblarcraft.MOD_ID, "test_biome"));
|
||||||
|
|
||||||
|
public static void bootstrap(Registerable<Biome> context) {
|
||||||
|
context.register(TEST_BIOME, testBiome(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void globalOverworldGeneration(GenerationSettings.LookupBackedBuilder builder) {
|
||||||
|
DefaultBiomeFeatures.addLandCarvers(builder);
|
||||||
|
DefaultBiomeFeatures.addAmethystGeodes(builder);
|
||||||
|
// DefaultBiomeFeatures.addDungeons(builder);
|
||||||
|
DefaultBiomeFeatures.addMineables(builder);
|
||||||
|
DefaultBiomeFeatures.addSprings(builder);
|
||||||
|
DefaultBiomeFeatures.addFrozenTopLayer(builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Biome testBiome(Registerable<Biome> context) {
|
||||||
|
SpawnSettings.Builder spawnBuilder = new SpawnSettings.Builder();
|
||||||
|
|
||||||
|
DefaultBiomeFeatures.addFarmAnimals(spawnBuilder);
|
||||||
|
// DefaultBiomeFeatures.addBatsAndMonsters(spawnBuilder);
|
||||||
|
|
||||||
|
GenerationSettings.LookupBackedBuilder biomeBuilder =
|
||||||
|
new GenerationSettings.LookupBackedBuilder(context.getRegistryLookup(RegistryKeys.PLACED_FEATURE),
|
||||||
|
context.getRegistryLookup(RegistryKeys.CONFIGURED_CARVER));
|
||||||
|
|
||||||
|
globalOverworldGeneration(biomeBuilder);
|
||||||
|
DefaultBiomeFeatures.addMossyRocks(biomeBuilder);
|
||||||
|
|
||||||
|
biomeBuilder.feature(GenerationStep.Feature.VEGETAL_DECORATION, VegetationPlacedFeatures.TREES_PLAINS);
|
||||||
|
DefaultBiomeFeatures.addForestFlowers(biomeBuilder);
|
||||||
|
DefaultBiomeFeatures.addLargeFerns(biomeBuilder);
|
||||||
|
|
||||||
|
DefaultBiomeFeatures.addDefaultMushrooms(biomeBuilder);
|
||||||
|
DefaultBiomeFeatures.addDefaultVegetation(biomeBuilder);
|
||||||
|
|
||||||
|
return new Biome.Builder()
|
||||||
|
.precipitation(true)
|
||||||
|
.downfall(0.6f)
|
||||||
|
.temperature(0.7f)
|
||||||
|
.generationSettings(biomeBuilder.build())
|
||||||
|
.spawnSettings(spawnBuilder.build())
|
||||||
|
.effects((new BiomeEffects.Builder())
|
||||||
|
.waterColor(0xeb34a4)
|
||||||
|
.waterFogColor(0x1b78bf)
|
||||||
|
.skyColor(0xb41bbf)
|
||||||
|
.grassColor(0x1bbfb4)
|
||||||
|
.foliageColor(0xd203fc)
|
||||||
|
.fogColor(0x1b78bf).build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package jesse.keeblarcraft.world.biome;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import net.minecraft.registry.Registry;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.world.biome.Biome;
|
||||||
|
import net.minecraft.world.biome.BiomeKeys;
|
||||||
|
import net.minecraft.world.biome.source.util.MultiNoiseUtil;
|
||||||
|
import terrablender.api.Region;
|
||||||
|
import terrablender.api.RegionType;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class ModOverworldRegion extends Region {
|
||||||
|
public ModOverworldRegion(Identifier name, int weight) {
|
||||||
|
super(name, RegionType.OVERWORLD, weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addBiomes(Registry<Biome> registry, Consumer<Pair<MultiNoiseUtil.NoiseHypercube,
|
||||||
|
RegistryKey<Biome>>> mapper) {
|
||||||
|
// this.addModifiedVanillaOverworldBiomes(mapper, modifiedVanillaOverworldBuilder -> {
|
||||||
|
// modifiedVanillaOverworldBuilder.replaceBiome(BiomeKeys.FOREST, ModBiomes.TEST_BIOME);
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package jesse.keeblarcraft.world.biome;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.Keeblarcraft;
|
||||||
|
import jesse.keeblarcraft.world.biome.surface.ModMaterialRules;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import terrablender.api.Regions;
|
||||||
|
import terrablender.api.SurfaceRuleManager;
|
||||||
|
import terrablender.api.TerraBlenderApi;
|
||||||
|
|
||||||
|
public class ModTerrablenderAPI implements TerraBlenderApi {
|
||||||
|
@Override
|
||||||
|
public void onTerraBlenderInitialized() {
|
||||||
|
Regions.register(new ModOverworldRegion(new Identifier(Keeblarcraft.MOD_ID, "overworld"), 4));
|
||||||
|
|
||||||
|
SurfaceRuleManager.addSurfaceRules(SurfaceRuleManager.RuleCategory.OVERWORLD, Keeblarcraft.MOD_ID, ModMaterialRules.makeRules());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package jesse.keeblarcraft.world.biome.surface;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.world.biome.ModBiomes;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.world.gen.surfacebuilder.MaterialRules;
|
||||||
|
|
||||||
|
// for landscaping and stuff
|
||||||
|
public class ModMaterialRules {
|
||||||
|
private static final MaterialRules.MaterialRule DIRT = makeStateRule(Blocks.DIRT);
|
||||||
|
private static final MaterialRules.MaterialRule GRASS_BLOCK = makeStateRule(Blocks.GRASS_BLOCK);
|
||||||
|
private static final MaterialRules.MaterialRule STONE_BLOCK = makeStateRule(Blocks.STONE);
|
||||||
|
private static final MaterialRules.MaterialRule GRANITE_BLOCK = makeStateRule(Blocks.GRANITE);
|
||||||
|
// private static final MaterialRules.MaterialRule RUBY = makeStateRule(ModBlocks.RUBY_BLOCK);
|
||||||
|
// private static final MaterialRules.MaterialRule RAW_RUBY = makeStateRule(ModBlocks.RAW_RUBY_BLOCK);
|
||||||
|
|
||||||
|
public static MaterialRules.MaterialRule makeRules() {
|
||||||
|
MaterialRules.MaterialCondition isAtOrAboveWaterLevel = MaterialRules.water(-1, 0);
|
||||||
|
|
||||||
|
MaterialRules.MaterialRule grassSurface = MaterialRules.sequence(MaterialRules.condition(isAtOrAboveWaterLevel, GRASS_BLOCK), DIRT);
|
||||||
|
|
||||||
|
return MaterialRules.sequence(MaterialRules.sequence(MaterialRules.condition(MaterialRules.biome(ModBiomes.TEST_BIOME),
|
||||||
|
MaterialRules.condition(MaterialRules.STONE_DEPTH_FLOOR, STONE_BLOCK)),
|
||||||
|
MaterialRules.condition(MaterialRules.STONE_DEPTH_CEILING, GRANITE_BLOCK)),
|
||||||
|
// Default to a grass and dirt surface
|
||||||
|
MaterialRules.condition(MaterialRules.STONE_DEPTH_FLOOR, grassSurface)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MaterialRules.MaterialRule makeStateRule(Block block) {
|
||||||
|
return MaterialRules.block(block.getDefaultState());
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package jesse.keeblarcraft.world.dimension;
|
||||||
|
|
||||||
|
import java.util.OptionalLong;
|
||||||
|
|
||||||
|
import jesse.keeblarcraft.Keeblarcraft;
|
||||||
|
import net.minecraft.registry.Registerable;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.registry.RegistryKeys;
|
||||||
|
import net.minecraft.registry.tag.BlockTags;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.intprovider.UniformIntProvider;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraft.world.dimension.DimensionOptions;
|
||||||
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import net.minecraft.world.dimension.DimensionTypes;
|
||||||
|
|
||||||
|
public class ModDimensions {
|
||||||
|
public static final RegistryKey<DimensionOptions> KEEBLAR_KEY = RegistryKey.of(RegistryKeys.DIMENSION,
|
||||||
|
new Identifier(Keeblarcraft.MOD_ID, "keeblarcraftdim"));
|
||||||
|
|
||||||
|
public static final RegistryKey<World> KEEBLAR_LEVEL_KEY = RegistryKey.of(RegistryKeys.WORLD,
|
||||||
|
new Identifier(Keeblarcraft.MOD_ID, "keeblarcraftdim"));
|
||||||
|
|
||||||
|
public static final RegistryKey<DimensionType> KEEBLAR_DIM_TYPE = RegistryKey.of(RegistryKeys.DIMENSION_TYPE,
|
||||||
|
new Identifier(Keeblarcraft.MOD_ID, "keeblarcraftdim_type"));
|
||||||
|
|
||||||
|
public static void bootstrapType(Registerable<DimensionType> context) {
|
||||||
|
context.register(KEEBLAR_DIM_TYPE, new DimensionType(
|
||||||
|
OptionalLong.of(12750), // fixedTime
|
||||||
|
true, // hasSkylight
|
||||||
|
false, // hasCeiling
|
||||||
|
false, // ultraWarm
|
||||||
|
false, // natural
|
||||||
|
1.0, // coordinateScale
|
||||||
|
true, // bedWorks
|
||||||
|
false, // respawnAnchorWorks
|
||||||
|
0, // minY
|
||||||
|
480, // height DO NOT LOWER ANYMORE. IN PRODUCTION
|
||||||
|
256, // logicalHeight
|
||||||
|
BlockTags.INFINIBURN_OVERWORLD, // infiniburn
|
||||||
|
DimensionTypes.OVERWORLD_ID, // effectsLocation
|
||||||
|
0.5f, // ambientLight
|
||||||
|
new DimensionType.MonsterSettings(false, false, UniformIntProvider.create(0, 0), 0)));
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
"item.keeblarcraft.metaljacket_chestplate": "MetalJacket Chestplate",
|
"item.keeblarcraft.metaljacket_chestplate": "MetalJacket Chestplate",
|
||||||
"item.keeblarcraft.metaljacket_leggings": "MetalJacket Leggings",
|
"item.keeblarcraft.metaljacket_leggings": "MetalJacket Leggings",
|
||||||
"item.keeblarcraft.metaljacket_boots": "MetalJacket Booties",
|
"item.keeblarcraft.metaljacket_boots": "MetalJacket Booties",
|
||||||
|
"item.keeblarcraft.longdiamondpick": "Long Diamond Pick",
|
||||||
|
|
||||||
"itemgroup.keeblarcraft": "Keeblarcraft Modded Items",
|
"itemgroup.keeblarcraft": "Keeblarcraft Modded Items",
|
||||||
|
|
||||||
@ -12,5 +13,7 @@
|
|||||||
|
|
||||||
"category.keeblarcraft.test": "Keeblarcraft bindings",
|
"category.keeblarcraft.test": "Keeblarcraft bindings",
|
||||||
"key.keeblarcraft.treemap": "Tree GUI",
|
"key.keeblarcraft.treemap": "Tree GUI",
|
||||||
"key.keeblarcraft.globalconfig": "Config menu"
|
"key.keeblarcraft.globalconfig": "Config menu",
|
||||||
|
|
||||||
|
"longpick.tooltip": "LOONG PICK"
|
||||||
}
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"parent": "item/handheld",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "keeblarcraft:item/longdiamondpick"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 296 B |
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"type": "keeblarcraft:keeblarcraftdim_type",
|
||||||
|
"generator": {
|
||||||
|
"type": "minecraft:noise",
|
||||||
|
"settings": "minecraft:overworld",
|
||||||
|
"biome_source": {
|
||||||
|
"type": "minecraft:multi_noise",
|
||||||
|
"biomes": [
|
||||||
|
{
|
||||||
|
"biome": "minecraft:plains",
|
||||||
|
"parameters": {
|
||||||
|
"temperature": 0.3,
|
||||||
|
"humidity": 0.1,
|
||||||
|
"continentalness": 0.2,
|
||||||
|
"erosion": 0.1,
|
||||||
|
"weirdness": 0.1,
|
||||||
|
"depth": 0,
|
||||||
|
"offset": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"biome": "keeblarcraft:test_biome",
|
||||||
|
"parameters": {
|
||||||
|
"temperature": 0,
|
||||||
|
"humidity": 0,
|
||||||
|
"continentalness": 0.1,
|
||||||
|
"erosion": 0,
|
||||||
|
"weirdness": 0,
|
||||||
|
"depth": 0,
|
||||||
|
"offset": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,12 @@
|
|||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"jesse.keeblarcraft.KeeblarcraftClient"
|
"jesse.keeblarcraft.KeeblarcraftClient"
|
||||||
|
],
|
||||||
|
"fabric-datagen": [
|
||||||
|
"jesse.keeblarcraft.world.DataGeneration"
|
||||||
|
],
|
||||||
|
"terrablender": [
|
||||||
|
"jesse.keeblarcraft.world.biome.ModTerrablenderAPI"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"depends": {
|
"depends": {
|
||||||
@ -27,7 +33,7 @@
|
|||||||
"minecraft": "~1.20",
|
"minecraft": "~1.20",
|
||||||
"java": ">=17",
|
"java": ">=17",
|
||||||
"fabric-api": "*",
|
"fabric-api": "*",
|
||||||
"fabric-key-binding-api-v1": "*"
|
"terrablender": "*"
|
||||||
},
|
},
|
||||||
"suggests": {
|
"suggests": {
|
||||||
"another-mod": "*"
|
"another-mod": "*"
|
||||||
|
Loading…
Reference in New Issue
Block a user