Compare commits

..

No commits in common. "c8e379e564d60bc96ee0bf5e74e7dc934279df09" and "cb9c3c124e79424d1134b6147ca7d2f9eb98f006" have entirely different histories.

83 changed files with 1861 additions and 3641 deletions

2
.gitignore vendored
View File

@ -5,8 +5,6 @@ build/
out/ out/
classes/ classes/
remappedSrc/
# eclipse # eclipse
*.launch *.launch

View File

@ -32,13 +32,13 @@ DOXYFILE_ENCODING = UTF-8
# title of most generated pages and in a few other places. # title of most generated pages and in a few other places.
# The default value is: My Project. # The default value is: My Project.
PROJECT_NAME = "Keeblarcraft" PROJECT_NAME = "My Project"
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This # The PROJECT_NUMBER tag can be used to enter a project or revision number. This
# could be handy for archiving the generated documentation or if some version # could be handy for archiving the generated documentation or if some version
# control system is used. # control system is used.
PROJECT_NUMBER = 1.0 PROJECT_NUMBER =
# Using the PROJECT_BRIEF tag one can provide an optional one line description # Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a # for a project that appears at the top of each page and should give viewer a

View File

@ -1,5 +1,5 @@
plugins { plugins {
id 'fabric-loom' version '1.9-SNAPSHOT' id 'fabric-loom' version '1.7-SNAPSHOT'
id 'maven-publish' id 'maven-publish'
} }
@ -47,16 +47,13 @@ dependencies {
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// modImplementation "mysql:mysql-connector-java:9.1.0"
include(implementation("mysql:mysql-connector-java:8.0.27"))
// Fabric API. This is technically optional, but you probably want it anyway. // Fabric API. This is technically optional, but you probably want it anyway.
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-beta64.5-1.20.2' modImplementation 'net.kyrptonaught:customportalapi:0.0.1-beta65-1.20'
include 'net.kyrptonaught:customportalapi:0.0.1-beta64.5-1.20.2' include 'net.kyrptonaught:customportalapi:0.0.1-beta65-1.20'
modImplementation 'com.github.glitchfiend:TerraBlender-fabric:1.20.2-3.2.0.14' modImplementation 'com.github.glitchfiend:TerraBlender-fabric:1.20.1-3.0.1.7'
} }
processResources { processResources {
@ -75,10 +72,10 @@ java {
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present. // if it is present.
// If you remove this line, sources will not be generated. // If you remove this line, sources will not be generated.
withSourcesJar()
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_17
withSourcesJar()
} }
jar { jar {

View File

@ -1,17 +1,17 @@
# Done to increase the memory available to gradle. # Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx2G org.gradle.jvmargs=-Xmx1G
org.gradle.parallel=true org.gradle.parallel=true
# Fabric Properties # Fabric Properties
# check these on https://fabricmc.net/develop # check these on https://fabricmc.net/develop
minecraft_version=1.20.2 minecraft_version=1.20
yarn_mappings=1.20.2+build.4 yarn_mappings=1.20+build.1
loader_version=0.16.9 loader_version=0.15.11
# Mod Properties # Mod Properties
mod_version=1.0.0 mod_version=0.0.1
maven_group=jesse.keeblarcraft maven_group=jesse.keeblarcraft
archives_base_name=keeblarcraft archives_base_name=keeblarcraft
# Dependencies # Dependencies
fabric_version=0.91.6+1.20.2 fabric_version=0.83.0+1.20

Binary file not shown.

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

5
gradlew vendored
View File

@ -15,8 +15,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@ -86,8 +84,7 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum

2
gradlew.bat vendored
View File

@ -13,8 +13,6 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################

Binary file not shown.

188
run.sh
View File

@ -1,188 +0,0 @@
#!/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

View File

@ -1,8 +1,8 @@
package jesse.keeblarcraft; package jesse.keeblarcraft;
import jesse.keeblarcraft.gui.ClientHandlers; import jesse.keeblarcraft.gui.ClientHandlers;
// import jesse.keeblarcraft.gui.ScreenManager; import jesse.keeblarcraft.gui.ScreenManager;
// import jesse.keeblarcraft.gui.widgets.TreeWidget; import jesse.keeblarcraft.gui.widgets.TreeWidget;
import jesse.keeblarcraft.Shortcuts.ShortcutManager; import jesse.keeblarcraft.Shortcuts.ShortcutManager;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
@ -14,8 +14,8 @@ public class KeeblarcraftClient implements ClientModInitializer {
ShortcutManager.RegisterKeybinds(); ShortcutManager.RegisterKeybinds();
ClientHandlers.RegisterHandlers(); ClientHandlers.RegisterHandlers();
// ScreenManager.GetInstance(); ScreenManager.GetInstance();
// ScreenManager.AddWidget(TreeWidget.class, 10); ScreenManager.AddWidget(TreeWidget.class, 10);
} }
} }

View File

@ -12,7 +12,7 @@ package jesse.keeblarcraft.Shortcuts;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
// import jesse.keeblarcraft.Keeblarcraft; // import jesse.keeblarcraft.Keeblarcraft;
// import jesse.keeblarcraft.gui.ScreenManager; import jesse.keeblarcraft.gui.ScreenManager;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
@ -83,10 +83,10 @@ public class ShortcutManager {
// treeGui = new ScreenManager(Keeblarcraft.TREE_HANDLER.create(0, client.player.getInventory()), client.player.getInventory(), Text.of("Test")); // treeGui = new ScreenManager(Keeblarcraft.TREE_HANDLER.create(0, client.player.getInventory()), client.player.getInventory(), Text.of("Test"));
// treeGui.AddParent(currentScreen); ///TODO: Put this in the constructor when you figure out how the hell the magic is happening with registration // treeGui.AddParent(currentScreen); ///TODO: Put this in the constructor when you figure out how the hell the magic is happening with registration
// ScreenManager treeGui = ScreenManager.GetInstance(); ScreenManager treeGui = ScreenManager.GetInstance();
// treeGui.AddParent(currentScreen); treeGui.AddParent(currentScreen);
// MinecraftClient.getInstance().setScreen(treeGui); MinecraftClient.getInstance().setScreen(treeGui);
// toggleTreeGui intentionally never bit-flipped to false as a slight implementation bug exists such that pressing the keybind again // toggleTreeGui intentionally never bit-flipped to false as a slight implementation bug exists such that pressing the keybind again
// does NOT call this callback function until the previous screen is CLOSED (which is why this isn't resource leaking...). This will // does NOT call this callback function until the previous screen is CLOSED (which is why this isn't resource leaking...). This will

View File

@ -1,13 +1,11 @@
package jesse.keeblarcraft.gui; package jesse.keeblarcraft.gui;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Keeblarcraft;
import jesse.keeblarcraft.GuiMgr.ScreenHandlerRegistration;
import net.minecraft.client.gui.screen.ingame.HandledScreens; import net.minecraft.client.gui.screen.ingame.HandledScreens;
public class ClientHandlers { public class ClientHandlers {
public static void RegisterHandlers() { public static void RegisterHandlers() {
System.out.println("Registering tree handler screen"); System.out.println("Registering tree handler screen");
// HandledScreens.register(Keeblarcraft.TREE_HANDLER, ScreenManager::new); HandledScreens.register(Keeblarcraft.TREE_HANDLER, ScreenManager::new);
HandledScreens.register(ScreenHandlerRegistration.FACTION_BLOCK_SCREEN_HANDLER, FactionBlockScreen::new);
} }
} }

View File

@ -1,51 +0,0 @@
package jesse.keeblarcraft.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import jesse.keeblarcraft.Keeblarcraft;
import jesse.keeblarcraft.GuiMgr.FactionBlockScreenHandler;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
public class FactionBlockScreen extends HandledScreen<FactionBlockScreenHandler> {
// This is a placeholder image until an actual one is drawn
private static final Identifier TEXTURE = new Identifier(Keeblarcraft.MOD_ID, "textures/gui/faction_block_menu.png");
public FactionBlockScreen(FactionBlockScreenHandler handler, PlayerInventory inventory, Text title) {
super(handler, inventory, title);
}
@Override
protected void init() {
super.init();
titleY = 1000; //begone from screen
playerInventoryTitleY = 1000; //begone from screen
}
@Override
protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) {
RenderSystem.setShader(GameRenderer::getPositionTexProgram);
RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
RenderSystem.setShaderTexture(0, TEXTURE);
this.backgroundHeight = 256;
this.backgroundWidth = 256;
int x = (width - backgroundWidth) / 2;
int y = (height - backgroundHeight) / 2;
context.drawTexture(TEXTURE, x, y, 0, 0, backgroundWidth, backgroundHeight);
}
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
renderBackground(context, mouseX, mouseY, delta);
super.render(context, mouseX, mouseY, delta);
drawMouseoverTooltip(context, mouseX, mouseY);
}
}

View File

@ -1,381 +1,381 @@
// /* /*
// * *
// * ScreenManager * ScreenManager
// * *
// * This is the screen manager for the global screen handler of `TreeHandler` type * This is the screen manager for the global screen handler of `TreeHandler` type
// * Please note: `TreeHandler` is suited for a more broad range of things; however * Please note: `TreeHandler` is suited for a more broad range of things; however
// * its initial implementation is for the skill tree. It will be renamed to a more * its initial implementation is for the skill tree. It will be renamed to a more
// * generic name so this class is more obviously re-usable after its implementation * generic name so this class is more obviously re-usable after its implementation
// * is complete AND we verify this class can be made more generic for it. Since this * is complete AND we verify this class can be made more generic for it. Since this
// * is unknown, it will remain the name it has currently. * is unknown, it will remain the name it has currently.
// * *
// * *
// */ */
// package jesse.keeblarcraft.gui; package jesse.keeblarcraft.gui;
// import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
// import java.util.ArrayList; import java.util.ArrayList;
// import java.util.HashMap; import java.util.HashMap;
// import java.util.List; import java.util.List;
// import java.util.Map.Entry; import java.util.Map.Entry;
// import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Keeblarcraft;
// import jesse.keeblarcraft.GuiMgr.TreeHandler; import jesse.keeblarcraft.GuiMgr.TreeHandler;
// import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
// import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
// import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
// import net.minecraft.client.gui.screen.ingame.HandledScreen; import net.minecraft.client.gui.screen.ingame.HandledScreen;
// import net.minecraft.entity.player.PlayerInventory; import net.minecraft.entity.player.PlayerInventory;
// import net.minecraft.text.Text; import net.minecraft.text.Text;
// // Client side renderer // Client side renderer
// public class ScreenManager extends HandledScreen<TreeHandler> { public class ScreenManager extends HandledScreen<TreeHandler> {
// private static ScreenManager static_inst; private static ScreenManager static_inst;
// @SuppressWarnings("resource") @SuppressWarnings("resource")
// private static PlayerInventory static_inventory = new PlayerInventory(null);// = MinecraftClient.getInstance().player.getInventory(); private static PlayerInventory static_inventory = new PlayerInventory(null);// = MinecraftClient.getInstance().player.getInventory();
// public static ScreenManager GetInstance() { public static ScreenManager GetInstance() {
// if (static_inst == null) { if (static_inst == null) {
// static_inst = new ScreenManager(Keeblarcraft.TREE_HANDLER.create(0, static_inventory), static_inventory, Text.of("Test")); static_inst = new ScreenManager(Keeblarcraft.TREE_HANDLER.create(0, static_inventory), static_inventory, Text.of("Test"));
// } }
// return static_inst; return static_inst;
}
private static HashMap<Integer, ArrayList<Class<? extends GenericLayerT>>> layerMap = new HashMap<Integer, ArrayList<Class<? extends GenericLayerT>>>();
private static HashMap<Integer, ArrayList<GenericLayerT>> layers = new HashMap<Integer, ArrayList<GenericLayerT>>(); // key: layer id; value: list of classes to draw
// private TreeWidget treeWidget = null;
private Screen parent;
/////////////////////////////////////////////////////////////////////////////
/// @fn ScreenManager
///
/// @arg[in] handler is the TreeHandler (ScreenHandler) object
///
/// @arg[in] inventory is the players inventory. Required by HandledScreen
/// object however is unused currently in this Screen
///
/// @arg[in] title is the title of the screen window
///
/// @brief Class constructor
/////////////////////////////////////////////////////////////////////////////
public ScreenManager(TreeHandler handler, PlayerInventory inventory, Text title) {
super(handler, inventory, title);
System.out.println("Called constructor of screen manager!");
// Initialize layers in map
// for (int i = 0; i < NUMBER_DRAW_LAYERS; i++) {
// layers.put(i, new ArrayList<Class<? extends GenericLayerT>>());
// } // }
}
// private static HashMap<Integer, ArrayList<Class<? extends GenericLayerT>>> layerMap = new HashMap<Integer, ArrayList<Class<? extends GenericLayerT>>>(); /////////////////////////////////////////////////////////////////////////////
// private static HashMap<Integer, ArrayList<GenericLayerT>> layers = new HashMap<Integer, ArrayList<GenericLayerT>>(); // key: layer id; value: list of classes to draw /// @fn AddParent
///
/// @arg[in] parent is the parent screen object
///
/// @brief Add a parent screen to the screen object. This is useful if
/// you want to return to the previous screen when this one gets
/// closed by the user
/////////////////////////////////////////////////////////////////////////////
public void AddParent(Screen parent) {
this.parent = parent;
}
// // private TreeWidget treeWidget = null; public static void AddWidget(Class<? extends GenericLayerT> widget, int drawLayer) {
// private Screen parent; if (layerMap.containsKey(drawLayer)) {
// Just append the widget to the draw layer
var layerList = layerMap.get(drawLayer);
layerList.add(widget);
} else {
// Brand new layer!
layerMap.put(drawLayer, new ArrayList<>(List.of(widget)));
}
}
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn ScreenManager /// @fn init
// /// ///
// /// @arg[in] handler is the TreeHandler (ScreenHandler) object /// @brief Initialize method; called one-time to setup class variables
// /// /////////////////////////////////////////////////////////////////////////////
// /// @arg[in] inventory is the players inventory. Required by HandledScreen @Override
// /// object however is unused currently in this Screen public void init() {
// /// // initialize screen size to the global background picture
// /// @arg[in] title is the title of the screen window this.width = MinecraftClient.getInstance().getWindow().getScaledWidth();
// /// this.height = MinecraftClient.getInstance().getWindow().getScaledHeight();
// /// @brief Class constructor
// /////////////////////////////////////////////////////////////////////////////
// public ScreenManager(TreeHandler handler, PlayerInventory inventory, Text title) {
// super(handler, inventory, title);
// System.out.println("Called constructor of screen manager!");
// // Initialize layers in map // Let's go through and initialize all the screen types now in our active memory
// // for (int i = 0; i < NUMBER_DRAW_LAYERS; i++) { for (Entry<Integer, ArrayList<Class<? extends GenericLayerT>>> layerEntry : layerMap.entrySet()) {
// // layers.put(i, new ArrayList<Class<? extends GenericLayerT>>()); var layerList = layerEntry.getValue();
// // }
// }
// ///////////////////////////////////////////////////////////////////////////// layers.put(layerEntry.getKey(), new ArrayList<>());
// /// @fn AddParent var activeLayerList = layers.get(layerEntry.getKey());
// /// for (int i = 0; i < layerList.size(); i++) {
// /// @arg[in] parent is the parent screen object try {
// /// System.out.println("Attempting to initialize widget with information: LAYER I-VAL W H: " + layerEntry.getKey() + " " + i + " " + this.width + " " + this.height);
// /// @brief Add a parent screen to the screen object. This is useful if GenericLayerT initializedWidget = layerList.get(i).getDeclaredConstructor(int.class, int.class, int.class, int.class, Text.class).newInstance(0, 0, this.width, this.height, Text.of(""));
// /// you want to return to the previous screen when this one gets activeLayerList.add(initializedWidget);
// /// closed by the user } catch (InstantiationException e) {
// ///////////////////////////////////////////////////////////////////////////// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of IntantiationException");
// public void AddParent(Screen parent) { e.printStackTrace();
// this.parent = parent; } catch (IllegalAccessException e) {
// } System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of IllegalAccessException");
e.printStackTrace();
// public static void AddWidget(Class<? extends GenericLayerT> widget, int drawLayer) { } catch (IllegalArgumentException e) {
// if (layerMap.containsKey(drawLayer)) { System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of IllegalArgumentException");
// // Just append the widget to the draw layer e.printStackTrace();
// var layerList = layerMap.get(drawLayer); } catch (InvocationTargetException e) {
// layerList.add(widget); System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of InvocationTargetException");
// } else { e.printStackTrace();
// // Brand new layer! } catch (NoSuchMethodException e) {
// layerMap.put(drawLayer, new ArrayList<>(List.of(widget))); System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of NoSuchMethodException");
// } e.printStackTrace();
// } } catch (SecurityException e) {
System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of SecurityException");
// ///////////////////////////////////////////////////////////////////////////// e.printStackTrace();
// /// @fn init }
// /// }
// /// @brief Initialize method; called one-time to setup class variables }
// /////////////////////////////////////////////////////////////////////////////
// @Override
// public void init() {
// // initialize screen size to the global background picture
// this.width = MinecraftClient.getInstance().getWindow().getScaledWidth();
// this.height = MinecraftClient.getInstance().getWindow().getScaledHeight();
// // Let's go through and initialize all the screen types now in our active memory
// for (Entry<Integer, ArrayList<Class<? extends GenericLayerT>>> layerEntry : layerMap.entrySet()) {
// var layerList = layerEntry.getValue();
// layers.put(layerEntry.getKey(), new ArrayList<>());
// var activeLayerList = layers.get(layerEntry.getKey());
// for (int i = 0; i < layerList.size(); i++) {
// try {
// System.out.println("Attempting to initialize widget with information: LAYER I-VAL W H: " + layerEntry.getKey() + " " + i + " " + this.width + " " + this.height);
// GenericLayerT initializedWidget = layerList.get(i).getDeclaredConstructor(int.class, int.class, int.class, int.class, Text.class).newInstance(0, 0, this.width, this.height, Text.of(""));
// activeLayerList.add(initializedWidget);
// } catch (InstantiationException e) {
// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of IntantiationException");
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of IllegalAccessException");
// e.printStackTrace();
// } catch (IllegalArgumentException e) {
// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of IllegalArgumentException");
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of InvocationTargetException");
// e.printStackTrace();
// } catch (NoSuchMethodException e) {
// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of NoSuchMethodException");
// e.printStackTrace();
// } catch (SecurityException e) {
// System.out.println("Could not initialize GenericLayerT class (" + layerList.get(i).getClass().toString() + ") because of SecurityException");
// e.printStackTrace();
// }
// }
// }
// // Initialize child widgets with correct screen values so they can draw themselves in the right area on the screen (duh!) // Initialize child widgets with correct screen values so they can draw themselves in the right area on the screen (duh!)
// // treeWidget = new TreeWidget(GLOBAL_SCREEN_START_X + 24, GLOBAL_SCREEN_START_Y + 24, GLOBAL_SCREEN_WIDTH - 24, GLOBAL_SCREEN_HEIGHT - 24); // treeWidget = new TreeWidget(GLOBAL_SCREEN_START_X + 24, GLOBAL_SCREEN_START_Y + 24, GLOBAL_SCREEN_WIDTH - 24, GLOBAL_SCREEN_HEIGHT - 24);
// // this.addDrawableChild(treeWidget); // this.addDrawableChild(treeWidget);
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn render /// @fn render
// /// ///
// /// @arg[in] context is the drawing context of super class /// @arg[in] context is the drawing context of super class
// /// ///
// /// @arg[in] mouseX is passed to parent class but unused here /// @arg[in] mouseX is passed to parent class but unused here
// /// ///
// /// @arg[in] mouseY is passed to parent class but unused here /// @arg[in] mouseY is passed to parent class but unused here
// /// ///
// /// @brief Render is called every frame while the screen is open /// @brief Render is called every frame while the screen is open
// /// ///
// /// @note This is a pure abstract in parent and is required /// @note This is a pure abstract in parent and is required
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public void render(DrawContext context, int mouseX, int mouseY, float delta) { public void render(DrawContext context, int mouseX, int mouseY, float delta) {
// super.render(context, mouseX, mouseY, delta); // This takes care of calling drawBackground which calls DrawMainScreen super.render(context, mouseX, mouseY, delta); // This takes care of calling drawBackground which calls DrawMainScreen
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn drawForeground /// @fn drawForeground
// /// ///
// /// @arg[in] context is the drawing context of super class /// @arg[in] context is the drawing context of super class
// /// ///
// /// @arg[in] mouseX is unused /// @arg[in] mouseX is unused
// /// ///
// /// @arg[in] mouseY is unused /// @arg[in] mouseY is unused
// /// ///
// /// @brief Draw foreground exists to draw the titles; however we /// @brief Draw foreground exists to draw the titles; however we
// /// intentionally override it so the superclass object does not /// intentionally override it so the superclass object does not
// /// draw the overlay over the background screen /// draw the overlay over the background screen
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public void drawForeground(DrawContext context, int mouseX, int mouseY) { public void drawForeground(DrawContext context, int mouseX, int mouseY) {
// // We override this function to intentionally do nothing // We override this function to intentionally do nothing
// // If in the future we want, we would draw the foreground and TITLES with this! // If in the future we want, we would draw the foreground and TITLES with this!
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn close /// @fn close
// /// ///
// /// @brief Called when the screen closes /// @brief Called when the screen closes
// /// ///
// /// @note This is a pure abstract in parent and is required /// @note This is a pure abstract in parent and is required
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public void close() { public void close() {
// this.client.setScreen(parent); // return to previous screen or null this.client.setScreen(parent); // return to previous screen or null
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn mouseDragged /// @fn mouseDragged
// /// ///
// /// @arg[in] mouseX is x-axis position of original mouse click /// @arg[in] mouseX is x-axis position of original mouse click
// /// ///
// /// @arg[in] mouseY is y-axis position of original mouse click /// @arg[in] mouseY is y-axis position of original mouse click
// /// ///
// /// @arg[in] button is the int value of button pressed for mouse dragging /// @arg[in] button is the int value of button pressed for mouse dragging
// /// ///
// /// @arg[in] deltaX is the change in the X position from the previous /// @arg[in] deltaX is the change in the X position from the previous
// /// mouse click /// mouse click
// /// ///
// /// @arg[in] deltaY is the change in the Y position from the previous /// @arg[in] deltaY is the change in the Y position from the previous
// /// mouse click /// mouse click
// /// ///
// /// @brief The drag event is called on all widgets on the screen so /// @brief The drag event is called on all widgets on the screen so
// /// long as the initial position of the drag is within the /// long as the initial position of the drag is within the
// /// bounds of the widget box itself. Widgets themselves will need /// bounds of the widget box itself. Widgets themselves will need
// /// to handle any sub-widgets since the bound check is only /// to handle any sub-widgets since the bound check is only
// /// there to verify if the event happened ANYWHERE within a /// there to verify if the event happened ANYWHERE within a
// /// widget box /// widget box
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
// super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
// // UpdateAnchorValues(); // UpdateAnchorValues();
// for (Entry<Integer, ArrayList<GenericLayerT>> layerEntry : layers.entrySet()) { for (Entry<Integer, ArrayList<GenericLayerT>> layerEntry : layers.entrySet()) {
// var layerList = layerEntry.getValue(); var layerList = layerEntry.getValue();
// for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) { for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) {
// var layer = layerList.get(layerListIterator); var layer = layerList.get(layerListIterator);
// // Check to make sure scroll is within the context of the widget then deliver information // Check to make sure scroll is within the context of the widget then deliver information
// if (InBounds(layer.startX, layer.startY, layer.endX, layer.endY, (int) mouseX, (int) mouseY)) { if (InBounds(layer.startX, layer.startY, layer.endX, layer.endY, (int) mouseX, (int) mouseY)) {
// layer.mouseDragged(mouseX, mouseY, button, deltaX, deltaY); layer.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
// } }
// } }
// } }
// return true; return true;
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn mouseScrolled /// @fn mouseScrolled
// /// ///
// /// @arg[in] mouseX is the initial X position of the cursor on a scroll /// @arg[in] mouseX is the initial X position of the cursor on a scroll
// /// ///
// /// @arg[in] mouseY is the initial Y position of the cursor on a scroll /// @arg[in] mouseY is the initial Y position of the cursor on a scroll
// /// ///
// /// @arg[in] amount is a normalized value that indicates scroll direction /// @arg[in] amount is a normalized value that indicates scroll direction
// /// ///
// /// @brief The scroll event is called on all widgets on the screen so /// @brief The scroll event is called on all widgets on the screen so
// /// long as the initial position of the scroll is within the /// long as the initial position of the scroll is within the
// /// bounds of the widget box itself. Widgets themselves will need /// bounds of the widget box itself. Widgets themselves will need
// /// to handle any sub-widgets since the bound check is only /// to handle any sub-widgets since the bound check is only
// /// there to verify if the event happened ANYWHERE within a /// there to verify if the event happened ANYWHERE within a
// /// widget box /// widget box
// /// ///
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public boolean mouseScrolled(double mouseX, double mouseY, double amount) { public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
// super.mouseScrolled(mouseX, mouseY, amount); super.mouseScrolled(mouseX, mouseY, amount);
// for (Entry<Integer, ArrayList<GenericLayerT>> layerEntry : layers.entrySet()) { for (Entry<Integer, ArrayList<GenericLayerT>> layerEntry : layers.entrySet()) {
// var layerList = layerEntry.getValue(); var layerList = layerEntry.getValue();
// for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) { for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) {
// var layer = layerList.get(layerListIterator); var layer = layerList.get(layerListIterator);
// // Check to make sure scroll is within the context of the widget then deliver information // Check to make sure scroll is within the context of the widget then deliver information
// if (InBounds(layer.startX, layer.startY, layer.endX, layer.endY, (int) mouseX, (int) mouseY)) { if (InBounds(layer.startX, layer.startY, layer.endX, layer.endY, (int) mouseX, (int) mouseY)) {
// layer.mouseScrolled(mouseX, mouseY, amount); layer.mouseScrolled(mouseX, mouseY, amount);
// } }
// } }
// } }
// return true; // The parent function defines this to be boolean; but I have no idea when I would want to return false from this return true; // The parent function defines this to be boolean; but I have no idea when I would want to return false from this
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn mouseClicked /// @fn mouseClicked
// /// ///
// /// @arg[in] mouseX is the initial X position of the mouse click event /// @arg[in] mouseX is the initial X position of the mouse click event
// /// ///
// /// @arg[in] mouseY is the initial Y position of the mouse click event /// @arg[in] mouseY is the initial Y position of the mouse click event
// /// ///
// /// @arg[in] button is the mouse click button (left/right click value) /// @arg[in] button is the mouse click button (left/right click value)
// /// ///
// /// @brief The mouse click is called on all widgets on the screen so /// @brief The mouse click is called on all widgets on the screen so
// /// long as the initial position of the click is within the /// long as the initial position of the click is within the
// /// bounds of the widget box itself. Widgets themselves will need /// bounds of the widget box itself. Widgets themselves will need
// /// to handle any sub-widgets since the bound check is only /// to handle any sub-widgets since the bound check is only
// /// there to verify if the event happened ANYWHERE within a /// there to verify if the event happened ANYWHERE within a
// /// widget box /// widget box
// /// ///
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public boolean mouseClicked(double mouseX, double mouseY, int button) { public boolean mouseClicked(double mouseX, double mouseY, int button) {
// super.mouseClicked(mouseX, mouseY, button); super.mouseClicked(mouseX, mouseY, button);
// for (Entry<Integer, ArrayList<GenericLayerT>> layerEntry : layers.entrySet()) { for (Entry<Integer, ArrayList<GenericLayerT>> layerEntry : layers.entrySet()) {
// var layerList = layerEntry.getValue(); var layerList = layerEntry.getValue();
// for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) { for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) {
// var layer = layerList.get(layerListIterator); var layer = layerList.get(layerListIterator);
// // Check to make sure scroll is within the context of the widget then deliver information // Check to make sure scroll is within the context of the widget then deliver information
// if (InBounds(layer.startX, layer.startY, layer.endX, layer.endY, (int) mouseX, (int) mouseY)) { if (InBounds(layer.startX, layer.startY, layer.endX, layer.endY, (int) mouseX, (int) mouseY)) {
// layer.mouseClicked(mouseX, mouseY, button); layer.mouseClicked(mouseX, mouseY, button);
// } }
// } }
// } }
// return true; return true;
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn DrawLayers /// @fn DrawLayers
// /// ///
// /// @arg[in] context is the global drawing context for the screen /// @arg[in] context is the global drawing context for the screen
// /// ///
// /// @arg[in] delta is passed in from background draw /// @arg[in] delta is passed in from background draw
// /// ///
// /// @brief This is the primary drawing function so that all the texture /// @brief This is the primary drawing function so that all the texture
// /// draws can be done in one place in this class. We want as /// draws can be done in one place in this class. We want as
// /// little distance as possible between redraws when possible! /// little distance as possible between redraws when possible!
// /// ///
// /// @note Currently the foreground is not drawn in the custom screen /// @note Currently the foreground is not drawn in the custom screen
// /// manager. This is because the foreground features the general /// manager. This is because the foreground features the general
// /// inventory manager that this screen handler is based on and we /// inventory manager that this screen handler is based on and we
// /// do not want to see those text pop ups. /// do not want to see those text pop ups.
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// public void DrawLayers(DrawContext context, float delta) { public void DrawLayers(DrawContext context, float delta) {
// for (Entry<Integer, ArrayList<GenericLayerT>> layerEntry : layers.entrySet()) { for (Entry<Integer, ArrayList<GenericLayerT>> layerEntry : layers.entrySet()) {
// var layerList = layerEntry.getValue(); var layerList = layerEntry.getValue();
// for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) { for (var layerListIterator = 0; layerListIterator < layerList.size(); layerListIterator++) {
// var layer = layerList.get(layerListIterator); var layer = layerList.get(layerListIterator);
// System.out.println("Drawing layer " + layerEntry.getKey() + " for class type " + layer.getClass().toString()); System.out.println("Drawing layer " + layerEntry.getKey() + " for class type " + layer.getClass().toString());
// layer.DrawLayer(context, layerEntry.getKey()); layer.DrawLayer(context, layerEntry.getKey());
// } }
// } }
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn InBounds /// @fn InBounds
// /// ///
// /// @arg[in] initX is initial position of X axis /// @arg[in] initX is initial position of X axis
// /// ///
// /// @arg[in] initY is initial position of Y axis /// @arg[in] initY is initial position of Y axis
// /// ///
// /// @arg[in] endX is the end position of X axis /// @arg[in] endX is the end position of X axis
// /// ///
// /// @arg[in] endY is the end position of Y axis /// @arg[in] endY is the end position of Y axis
// /// ///
// /// @arg[in] x is the current X value we are comparing in the X axis /// @arg[in] x is the current X value we are comparing in the X axis
// /// ///
// /// @arg[in] y is the current Y value we are comparing in the Y axis /// @arg[in] y is the current Y value we are comparing in the Y axis
// /// ///
// /// @brief Checks if an x,y coordinate position falls within the bounds /// @brief Checks if an x,y coordinate position falls within the bounds
// /// of a bounded box /// of a bounded box
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// private boolean InBounds(int initX, int initY, int endX, int endY, int x, int y) { private boolean InBounds(int initX, int initY, int endX, int endY, int x, int y) {
// return (x >= initX && x <= endX) && (y >= initY && y <= endY); return (x >= initX && x <= endX) && (y >= initY && y <= endY);
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn drawBackground /// @fn drawBackground
// /// ///
// /// @arg[in] context is the drawing context of super class /// @arg[in] context is the drawing context of super class
// /// ///
// /// @arg[in] delta is the change in background draw /// @arg[in] delta is the change in background draw
// /// ///
// /// @arg[in] mouseX is the mouse x-axis position /// @arg[in] mouseX is the mouse x-axis position
// /// ///
// /// @arg[in] mouseY is the mouse y-axis position /// @arg[in] mouseY is the mouse y-axis position
// /// ///
// /// @brief This function is an abstract parent class and must be /// @brief This function is an abstract parent class and must be
// /// implemented. This is "hijacked" and just being used as our /// implemented. This is "hijacked" and just being used as our
// /// main drawing method of all the background images. There isn't /// main drawing method of all the background images. There isn't
// /// a huge difference of drawing our stuff in background vs the /// a huge difference of drawing our stuff in background vs the
// /// foreground - except possibly foreground is drawn first. /// foreground - except possibly foreground is drawn first.
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) {
// DrawLayers(context, delta); DrawLayers(context, delta);
// } }
// } }

View File

@ -1,165 +1,165 @@
// /* /*
// * *
// * TreeWidget * TreeWidget
// * *
// * Handles the skill tree widget * Handles the skill tree widget
// * *
// * *
// */ */
// package jesse.keeblarcraft.gui.widgets; package jesse.keeblarcraft.gui.widgets;
// import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Keeblarcraft;
// import jesse.keeblarcraft.Utils.CommonStructures.Position2d; import jesse.keeblarcraft.Utils.CommonStructures.Position2d;
// import jesse.keeblarcraft.gui.GenericLayerT; import jesse.keeblarcraft.gui.GenericLayerT;
// import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
// import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder; import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
// import net.minecraft.text.Text; import net.minecraft.text.Text;
// import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
// public class TreeWidget extends GenericLayerT { public class TreeWidget extends GenericLayerT {
// private static Identifier BACKGROUND_TEXTURE = new Identifier(Keeblarcraft.MOD_ID + ":" + "textures/gui/attribute_tree_background.png"); private static Identifier BACKGROUND_TEXTURE = new Identifier(Keeblarcraft.MOD_ID + ":" + "textures/gui/attribute_tree_background.png");
// private static int maxHeight = 320; private static int maxHeight = 320;
// private static int maxLength = 640; private static int maxLength = 640;
// private int zoomScale = 1; private int zoomScale = 1;
// // private static Identifier FLIGHT_ATTRIBUTE = new Identifier(Keeblarcraft.MOD_ID + ":" + "textures/gui/attribute_flight.png"); // private static Identifier FLIGHT_ATTRIBUTE = new Identifier(Keeblarcraft.MOD_ID + ":" + "textures/gui/attribute_flight.png");
// ///TODO: Make this THE root node in the attribute tree! Rename in future ///TODO: Make this THE root node in the attribute tree! Rename in future
// // private static Identifier EXAMPLE_NODE = new Identifier(Keeblarcraft.MOD_ID + ":" + "textures/gui/attribute_tree_example_node.png"); ///TODO: Make a way to make this programmatic (Proabably extend AbstractNode to carry this var) // private static Identifier EXAMPLE_NODE = new Identifier(Keeblarcraft.MOD_ID + ":" + "textures/gui/attribute_tree_example_node.png"); ///TODO: Make a way to make this programmatic (Proabably extend AbstractNode to carry this var)
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn TreeWidget /// @fn TreeWidget
// /// ///
// /// @brief Class constructor for constructing a tree widget. This will /// @brief Class constructor for constructing a tree widget. This will
// /// be deprecated in a future version but exists for testing /// be deprecated in a future version but exists for testing
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// public TreeWidget() { public TreeWidget() {
// this(0, 0, 0, 0, Text.of("Test")); this(0, 0, 0, 0, Text.of("Test"));
// System.out.println("Calling empty tree constructor"); System.out.println("Calling empty tree constructor");
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn TreeWidget /// @fn TreeWidget
// /// ///
// /// @brief Class constructor for constructing a tree widget /// @brief Class constructor for constructing a tree widget
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// public TreeWidget(int x, int y, int width, int height, Text message) { public TreeWidget(int x, int y, int width, int height, Text message) {
// super(x, y, width, height, message); super(x, y, width, height, message);
// this.startX = x; this.startX = x;
// this.startY = y; this.startY = y;
// this.endX = x + width; this.endX = x + width;
// this.endY = y + height; this.endY = y + height;
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn renderButton /// @fn renderButton
// /// ///
// /// @param[in] context is the drawing pane /// @param[in] context is the drawing pane
// /// ///
// /// @param[in] x is the X position to draw at /// @param[in] x is the X position to draw at
// /// ///
// /// @param[in] y is the Y position to draw at /// @param[in] y is the Y position to draw at
// /// ///
// /// @param[in] delta is unused in this version /// @param[in] delta is unused in this version
// /// ///
// /// @brief Primary call to draw the GUI for this widget /// @brief Primary call to draw the GUI for this widget
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public void renderButton(DrawContext context, int x, int y, float delta) { public void renderButton(DrawContext context, int x, int y, float delta) {
// context.drawTexture(BACKGROUND_TEXTURE, x, y, 0, 0, maxLength, maxHeight, maxLength, maxHeight); context.drawTexture(BACKGROUND_TEXTURE, x, y, 0, 0, maxLength, maxHeight, maxLength, maxHeight);
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn appendClickableNarrations /// @fn appendClickableNarrations
// /// ///
// /// @param[in] builder is the narration builder. This is pure virtual in /// @param[in] builder is the narration builder. This is pure virtual in
// /// the parent but is unused in this widget currently /// the parent but is unused in this widget currently
// /// ///
// /// @brief Handles the narrator /// @brief Handles the narrator
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// protected void appendClickableNarrations(NarrationMessageBuilder builder) { protected void appendClickableNarrations(NarrationMessageBuilder builder) {
// return; return;
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn mouseClicked /// @fn mouseClicked
// /// ///
// /// @param[in] mouseX is where on the x-axis the mouse was clicked /// @param[in] mouseX is where on the x-axis the mouse was clicked
// /// ///
// /// @param[in] mouseY is where on the y-axis the mouse was clicked /// @param[in] mouseY is where on the y-axis the mouse was clicked
// /// ///
// /// @param[in] button is the button clicked with (think of a mouse...) /// @param[in] button is the button clicked with (think of a mouse...)
// /// ///
// /// @brief Handler for mouse click events /// @brief Handler for mouse click events
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public boolean mouseClicked(double mouseX, double mouseY, int button) { public boolean mouseClicked(double mouseX, double mouseY, int button) {
// return true; return true;
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn mouseDragged /// @fn mouseDragged
// /// ///
// /// @param[in] mouseX is where on the x-axis the mouse was dragged /// @param[in] mouseX is where on the x-axis the mouse was dragged
// /// ///
// /// @param[in] mouseY is where on the y-axis the mouse was dragged /// @param[in] mouseY is where on the y-axis the mouse was dragged
// /// ///
// /// @param[in] button is the button dragged with (think of a mouse...) /// @param[in] button is the button dragged with (think of a mouse...)
// /// ///
// /// @brief Handler for mouse drag events. delta's unused currently /// @brief Handler for mouse drag events. delta's unused currently
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) { public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
// boolean ret = false; boolean ret = false;
// if (this.isValidClickButton(button)) { if (this.isValidClickButton(button)) {
// // Do camera panning magic stuff here // Do camera panning magic stuff here
// ret = true; ret = true;
// } }
// return ret; return ret;
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn mouseDragged /// @fn mouseDragged
// /// ///
// /// @param[in] mouseX is where on the x-axis the mouse was dragged /// @param[in] mouseX is where on the x-axis the mouse was dragged
// /// ///
// /// @param[in] mouseY is where on the y-axis the mouse was dragged /// @param[in] mouseY is where on the y-axis the mouse was dragged
// /// ///
// /// @param[in] amount represents scroll direction. If the value is negative /// @param[in] amount represents scroll direction. If the value is negative
// /// we scale out. If positive, we scale in /// we scale out. If positive, we scale in
// /// ///
// /// @brief Handler for mouse scroll events /// @brief Handler for mouse scroll events
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public boolean mouseScrolled(double mouseX, double mouseY, double amount) { public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
// // Zooming INWARDS on scroll wheel produces 1.0 (which means zoom in) // Zooming INWARDS on scroll wheel produces 1.0 (which means zoom in)
// // Zooming BACKWARDS on scroll wheel produces -1.0 (which means zoom out) // Zooming BACKWARDS on scroll wheel produces -1.0 (which means zoom out)
// // We enforce a max scroll of 10 in either direction here // We enforce a max scroll of 10 in either direction here
// if (amount > 0 && zoomScale <= 10) { if (amount > 0 && zoomScale <= 10) {
// // Zoom in // Zoom in
// zoomScale++; zoomScale++;
// } else if (amount < 0 && zoomScale >= -10) { } else if (amount < 0 && zoomScale >= -10) {
// // Zoom out // Zoom out
// zoomScale--; zoomScale--;
// } }
// return true; return true;
// } }
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// /// @fn DrawLayer /// @fn DrawLayer
// /// ///
// /// @param[in] context is the drawing pane /// @param[in] context is the drawing pane
// /// ///
// /// @param[in] layer is the layer in which this widget is being drawn in /// @param[in] layer is the layer in which this widget is being drawn in
// /// ///
// /// @brief This calls renderButton and gives it the valid drawing /// @brief This calls renderButton and gives it the valid drawing
// /// context to use. This function is called by a ScreenManager<T> /// context to use. This function is called by a ScreenManager<T>
// ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// @Override @Override
// public void DrawLayer(DrawContext context, int layer) { public void DrawLayer(DrawContext context, int layer) {
// Position2d pos = GetScreenCenter(); Position2d pos = GetScreenCenter();
// this.renderButton(context, pos.x - (maxLength / 2), pos.y - (maxHeight / 2), 0); this.renderButton(context, pos.x - (maxLength / 2), pos.y - (maxHeight / 2), 0);
// } }
// } }

View File

@ -1,17 +0,0 @@
package jesse.keeblarcraft.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.minecraft.client.network.ClientPlayerInteractionManager;
@Mixin(ClientPlayerInteractionManager.class)
public abstract class ClientPlayerInteractionManagerMixin {
// This initial basically lets the player highlight the block at 10 blocks away. Does NOT let them break it, that is all handled in the new server mixin
// @Inject(method = "getReachDistance()F", at = @At ("HEAD"), cancellable = true)
// public void getReachDistance(CallbackInfoReturnable<Float> cir) {
// cir.setReturnValue(10.0f);
// }
}

View File

@ -1,3 +1,3 @@
// 1.20.2 2025-01-01T19:10:14.65260685 keeblarcraft/Keeblarcraft World Generation // 1.20 2024-12-05T22:38:15.935314478 keeblarcraft/Keeblarcraft World Generation
afc3340283d1101601bd4d2ca96341a58eceaf83 data/keeblarcraft/dimension_type/keeblarcraftdim_type.json afc3340283d1101601bd4d2ca96341a58eceaf83 data/keeblarcraft/dimension_type/keeblarcraftdim_type.json
4398eda2b0c28b2c754c45f5805534bf1921b243 data/keeblarcraft/worldgen/biome/test_biome.json 4398eda2b0c28b2c754c45f5805534bf1921b243 data/keeblarcraft/worldgen/biome/test_biome.json

View File

@ -10,14 +10,13 @@
package jesse.keeblarcraft.AttributeMgr; package jesse.keeblarcraft.AttributeMgr;
import java.util.HashMap; import java.util.HashMap;
import java.util.Set;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Keeblarcraft;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode; import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AttributeFlight;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AttributeMetalJacket; import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AttributeMetalJacket;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.FactionNodes.FactionBeacon;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.FactionNodes.FactionFlight;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Utils.ChatUtil;
public class AttributeMgr { public class AttributeMgr {
ConfigManager config; ConfigManager config;
@ -47,12 +46,13 @@ public class AttributeMgr {
Keeblarcraft.LOGGER.error("Attempted to assign AbstractNode class type when registering object but could not call .newInstance()! Constructs must be empty"); Keeblarcraft.LOGGER.error("Attempted to assign AbstractNode class type when registering object but could not call .newInstance()! Constructs must be empty");
e.printStackTrace(); e.printStackTrace();
} }
ChatUtil.LoggerColored("Registring attribute called", ChatUtil.CONSOLE_COLOR.CYAN, Keeblarcraft.LOGGER);
try { try {
if (attributes.containsKey(verifyNode.GetNodeTitle())) { if (attributes.containsKey(verifyNode.GetNodeTitle())) {
Keeblarcraft.LOGGER.warn("Could not register attribute with duplicate name '" + verifyNode.GetNodeTitle() + "'"); Keeblarcraft.LOGGER.warn("Could not register attribute with duplicate name '" + verifyNode.GetNodeTitle() + "'");
} else { } else {
Keeblarcraft.LOGGER.debug("REGISTERING ATTRIBUTE: " + verifyNode.GetNodeTitle()); ChatUtil.LoggerColored("REGISTERING ATTRIBUTE " + verifyNode.GetNodeTitle(), ChatUtil.CONSOLE_COLOR.YELLOW, Keeblarcraft.LOGGER);
attributes.put(verifyNode.GetNodeTitle(), classObj); attributes.put(verifyNode.GetNodeTitle(), classObj);
} }
} catch (Exception e) {} // Left empty since previous try-catch will throw error-message } catch (Exception e) {} // Left empty since previous try-catch will throw error-message
@ -70,19 +70,6 @@ public class AttributeMgr {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static String ApplyAttribute(String uuid, String attributeName) { public static String ApplyAttribute(String uuid, String attributeName) {
String msg = ""; String msg = "";
// System.out.println("ApplyAttribute debug. UUID - NAME: " + uuid + " - " + attributeName);
// Set<String> keys = attributes.keySet();
// for (String key : keys) {
// System.out.println("ATTRI: " + key);
// }
// System.out.println("ACTIVE TREES: ");
// Set<String> names = activeTrees.keySet();
// for (String name : names) {
// System.out.println("N: " + name);
// }
if (attributes.containsKey(attributeName)) { if (attributes.containsKey(attributeName)) {
AttributeTree playerTree = activeTrees.get(uuid); AttributeTree playerTree = activeTrees.get(uuid);
AbstractNode node = null; AbstractNode node = null;
@ -92,15 +79,7 @@ public class AttributeMgr {
Keeblarcraft.LOGGER.error("Could not successfully apply attribute. String of attribute name could not be successfully cast to actual java object"); Keeblarcraft.LOGGER.error("Could not successfully apply attribute. String of attribute name could not be successfully cast to actual java object");
} }
// System.out.println("Is player tree null: " + (playerTree == null ? "YES" : "NO")); if (playerTree != null && node != null) {
// System.out.println("Is player node null: " + (node == null ? "YES" : "NO"));
// if (playerTree != null) {
// System.out.println("Does player have skill: " + (playerTree.ContainsAttribute(attributeName) ? "YES" : "NO"));
// }
// Ensure player tree isn't null; node isn't null; and the player doesn't already have this attribute
if (playerTree != null && node != null && !playerTree.ContainsAttribute(attributeName)) {
/////////// ///////////
// debug testing // debug testing
String isNull = (node == null ? "NULL" : "NOT NULL"); String isNull = (node == null ? "NULL" : "NOT NULL");
@ -113,26 +92,13 @@ public class AttributeMgr {
msg = "Applied attribute '" + attributeName + "' successfully"; msg = "Applied attribute '" + attributeName + "' successfully";
} else { } else {
msg = "Player tree not found!"; msg = "Player tree not found!";
// String debug = "PlayerTree is null";
// if (playerTree != null) {
// debug = playerTree.ContainsAttribute(attributeName) ? "YES":"NO";
// }
// System.out.println("APPLY ATTRIBUTE FAIL: TREE NULL, NODE NULL, OR PLAYER ALREADY HAS THIS ATTRIBUTE (DO THEY? " + debug + ")");
} }
} else { } else {
msg = "Could not apply attribute, attribute name does not exist!"; msg = "Could not apply attribute, attribute name does not exist!";
System.out.println("Attribute does not exist!");
} }
return msg; return msg;
} }
// Deletes an attribute from the node tree
public static void DisableAttribute(String uuid, String attributeName) {
if (activeTrees.containsKey(uuid) && activeTrees.get(uuid).ContainsAttribute(attributeName)) {
activeTrees.get(uuid).DeleteNode(attributeName);
}
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn RegisterAttributes /// @fn RegisterAttributes
/// ///
@ -146,8 +112,7 @@ public class AttributeMgr {
/// TODO: Find a better way to do this more dynamically in the future /// TODO: Find a better way to do this more dynamically in the future
/// hint: make it an API for other modders to add to /// hint: make it an API for other modders to add to
RegisterAttributeClass(AttributeFlight.class);
RegisterAttributeClass(AttributeMetalJacket.class); RegisterAttributeClass(AttributeMetalJacket.class);
RegisterAttributeClass(FactionBeacon.class);
RegisterAttributeClass(FactionFlight.class);
} }
} }

View File

@ -0,0 +1,68 @@
/*
*
* AttributeFlight
*
* The flight attribute
*
*
*/
package jesse.keeblarcraft.AttributeMgr.AttributeNodes;
import java.util.HashMap;
import java.util.List;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.minecraft.block.BlockState;
import net.minecraft.util.ActionResult;
public class AttributeFlight extends AbstractNode {
Boolean registeredHitCallback = false;
public AttributeFlight() {
}
@Override
public String GetNodeTitle() {
return "attribute_low_health_flight";
}
@Override
public String GetNodeDescription() {
return "Gives player flight with low health";
}
@Override
public HashMap<String, List<String>> GetDetails() {
HashMap<String, List<String>> ret = new HashMap<String, List<String>>();
// Filling out description item stuff here
ret.put("Flight", List.of (
"Gives a player natural flight if they have less than or equal to two hearts remaining"
));
return ret;
}
@Override
public void RegisterCallbacks() {
// Register events here
if (registeredHitCallback == false) {
AttackBlockCallback.EVENT.register((player, world, hand, pos, direction) -> {
BlockState state = world.getBlockState(pos);
// Manual spectator check is necessary because AttackBlockCallbacks fire before the spectator check
if (!player.isSpectator() && player.getMainHandStack().isEmpty() && state.isToolRequired()) {
player.damage(world.getDamageSources().generic(), 1.0F);
}
return ActionResult.PASS;
});
}
registeredHitCallback = true;
}
}

View File

@ -8,8 +8,6 @@ import jesse.keeblarcraft.Armor.MetalJacketArmor;
import jesse.keeblarcraft.CustomItems.ItemManager; import jesse.keeblarcraft.CustomItems.ItemManager;
import net.minecraft.item.ArmorItem; import net.minecraft.item.ArmorItem;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
public final class AttributeMetalJacket extends AbstractNode { public final class AttributeMetalJacket extends AbstractNode {
// This is the custom armor set that players will receive if no armor is on & attribute is equipped // This is the custom armor set that players will receive if no armor is on & attribute is equipped

View File

@ -1,50 +0,0 @@
package jesse.keeblarcraft.AttributeMgr.AttributeNodes.FactionNodes;
import java.util.HashMap;
import java.util.List;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerInBaseCallback;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.ActionResult;
public class FactionBeacon extends AbstractNode {
private int beaconStrength = 1; // Increases with faction power; 1 is default
private float absorptionAmnt = 0.2f * beaconStrength;
@Override
public String GetNodeTitle() {
return "faction_beacon";
}
@Override
public String GetNodeDescription() {
return "This is a great unlockable for any faction to have and is leveled up with higher faction power. Gives beacon-like abilities + more!";
}
@Override
public HashMap<String, List<String>> GetDetails() {
HashMap<String, List<String>> ret = new HashMap<String, List<String>>();
ret.put("Faction Beacon", List.of("Grants a ton of beacon-like effects on faction members inside the radius of the faction block"));
return ret;
}
private void ApplyEffects(ServerPlayerEntity player) {
// player.setAbsorptionAmount(absorptionAmnt);
StatusEffectInstance sei = new StatusEffectInstance(StatusEffects.REGENERATION, 1000, 1, true, true, true);
player.addStatusEffect(sei);
}
@Override
public void RegisterCallbacks() {
System.out.println("REGISTER CALLBACKS FOR FACTION BEACON CALLED");
PlayerInBaseCallback.EVENT.register((player, world) -> {
// Make sure player can fly while inside the border. We don't ever want to run this more than once!
// player.sendMessage(Text.of("Applying effects"));
ApplyEffects((ServerPlayerEntity) player);
return ActionResult.SUCCESS;
});
}
}

View File

@ -1,148 +0,0 @@
package jesse.keeblarcraft.AttributeMgr.AttributeNodes.FactionNodes;
import java.util.HashMap;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerCommandFlightCallback;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerEnteredBaseCallback;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerExitedBaseCallback;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerInBaseCallback;
import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
public class FactionFlight extends AbstractNode {
private final int flightSpeed = 1;
private ServerPlayerEntity player;
private float SPEED_SCALAR = 40.0f; // The value to scale this correctly to CREATIVE flight is '20.0f' however faction flight is slower than creative intentionally
private Boolean canFly = false;
private Boolean loginInBaseToggle = false; // Covers the unique case if player logs in inside the faction block border; in which case they need flight enabled!
private Integer leaveTimerMs = 5000;
@Override
public String GetNodeTitle() {
return "faction_flight";
}
@Override
public String GetNodeDescription() {
return "This is a temporary-unlock value when you are around your factions home base block and it has flight unlocked for members!";
}
@Override
public HashMap<String, List<String>> GetDetails() {
HashMap<String, List<String>> ret = new HashMap<String, List<String>>();
ret.put("Faction Flight", List.of("Grants flight when near faction base if faction has it unlocked"));
return ret;
}
public Boolean TurnOnFlight(ServerPlayerEntity player) {
Boolean isFlying = false;
PlayerAbilities abilities = player.getAbilities();
if (canFly && !abilities.allowFlying) {
abilities.allowFlying = true;
abilities.setFlySpeed((float) (flightSpeed / SPEED_SCALAR));
isFlying = true;
player.sendAbilitiesUpdate();
}
return isFlying;
}
public Boolean TurnOffFlight(ServerPlayerEntity player) {
Boolean isFlying = false;
PlayerAbilities abilities = player.getAbilities();
if (canFly && abilities.allowFlying) {
abilities.allowFlying = false;
abilities.flying = false;
abilities.setFlySpeed(0);
isFlying = false;
player.sendAbilitiesUpdate();
}
return isFlying;
}
public void ResetPlayer(ServerPlayerEntity player) {
// Disable flight
PlayerAbilities abilities = player.getAbilities();
abilities.flying = false;
abilities.allowFlying = false;
abilities.setFlySpeed(0);
player.sendAbilitiesUpdate();
}
@Override
public void RegisterCallbacks() {
PlayerEnteredBaseCallback.EVENT.register((player, world) -> {
player.sendMessage(Text.of("Faction flight enabled"));
canFly = true;
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
// Toggle flight
TurnOnFlight(serverPlayer);
return ActionResult.PASS;
});
PlayerInBaseCallback.EVENT.register((player, world) -> {
// Make sure player can fly while inside the border. We don't ever want to run this more than once!
if (!canFly && !loginInBaseToggle) {
player.sendMessage(Text.of("Faction flight enabled"));
loginInBaseToggle = true;
canFly = true;
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
TurnOnFlight(serverPlayer);
}
return ActionResult.PASS;
});
PlayerCommandFlightCallback.EVENT.register((player, world) -> {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
Boolean isFlying = TurnOnFlight(serverPlayer);
// This is a toggle command; so first we get if the player is flying
PlayerAbilities abilities = player.getAbilities();
if (abilities.flying) {
TurnOffFlight((ServerPlayerEntity) player);
} else {
TurnOnFlight((ServerPlayerEntity) player);
}
System.out.println("abilities.flying: " + abilities.flying);
if(canFly && isFlying) {
serverPlayer.sendMessage(Text.of("Flight turned on"));
} else if (canFly && !isFlying) {
// Infers toggled off
serverPlayer.sendMessage(Text.of("Flight turned off"));
} else {
// Means player is not in fly-zone
serverPlayer.sendMessage(Text.of("You can only fly within the bounds of your faction base!"));
}
return ActionResult.PASS;
});
PlayerExitedBaseCallback.EVENT.register((player, world) -> {
Timer timer = new Timer();
canFly = false;
player.sendMessage(Text.of("You left the faction's perimeter! Flight will disable in 5 seconds..."));
timer.schedule(new TimerTask() {
@Override
public void run() {
// Cover the edge condition such that we leave the faction base (canFly = false) then
// the timer here starts and we come back into the base (canFly = true) - we want a NO-OP here
if (!canFly) {
player.sendMessage(Text.of("Faction flight disabled"));
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
ResetPlayer(serverPlayer);
}
}
}, leaveTimerMs);
return ActionResult.PASS;
});
}
}

View File

@ -17,14 +17,15 @@ import java.util.HashMap;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Keeblarcraft;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode; import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AbstractNode;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import net.minecraft.server.network.ServerPlayerEntity; import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION;
public class AttributeTree { public class AttributeTree {
PlayerTree playerAttributeTree = new PlayerTree(); PlayerTree playerAttributeTree = new PlayerTree();
ConfigManager config = new ConfigManager(); ConfigManager config = new ConfigManager();
private AbstractNode root = new RootNode(); private AbstractNode root = new RootNode();
private ServerPlayerEntity player;
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @class TreeNode /// @class TreeNode
@ -32,7 +33,7 @@ public class AttributeTree {
/// @brief This is an individual node that goes within the larger /// @brief This is an individual node that goes within the larger
/// PlayerTree class object /// PlayerTree class object
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public class TreeNode { private class TreeNode {
public TreeNode(AbstractNode node, Integer maxLevel, List<String> parents, List<String> children) { public TreeNode(AbstractNode node, Integer maxLevel, List<String> parents, List<String> children) {
thisNode = node; thisNode = node;
parentNodes = parents; parentNodes = parents;
@ -41,15 +42,15 @@ public class AttributeTree {
currentNodeLevel = 1; currentNodeLevel = 1;
} }
public AbstractNode thisNode; AbstractNode thisNode;
public Integer currentNodeLevel; Integer currentNodeLevel;
public Integer maxNodeLevel; Integer maxNodeLevel;
// Store the names of the parent and children nodes; this lets a node have any number of parents and children // Store the names of the parent and children nodes; this lets a node have any number of parents and children
// NOTE TO DEVELOPERS: Be aware! The more nodes the harrier the tree will look in the GUI!!! Always test your // NOTE TO DEVELOPERS: Be aware! The more nodes the harrier the tree will look in the GUI!!! Always test your
// code before just adding stuff willy-nilly! // code before just adding stuff willy-nilly!
public List<String> parentNodes; List<String> parentNodes;
public List<String> childrenNodes; List<String> childrenNodes;
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -60,10 +61,10 @@ public class AttributeTree {
/// stored inside the AttributeMgr class /// stored inside the AttributeMgr class
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
private class PlayerTree { private class PlayerTree {
public String uuid; String uuid;
// Key = name of AbstractNode // Key = name of AbstractNode
// Val = The attribute itself // Val = The attribute itself
public HashMap<String, TreeNode> tree = new HashMap<String, TreeNode>(); HashMap<String, TreeNode> tree = new HashMap<String, TreeNode>();
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -171,8 +172,6 @@ public class AttributeTree {
playerAttributeTree.tree.put(newNode.GetNodeTitle(), new TreeNode(newNode, maxNodeLevel, parents, children)); playerAttributeTree.tree.put(newNode.GetNodeTitle(), new TreeNode(newNode, maxNodeLevel, parents, children));
// if the new nodes level is not 0 we need to manually register the callbacks // if the new nodes level is not 0 we need to manually register the callbacks
System.out.println("Node title: " + newNode.GetNodeTitle() + " has power level " +
playerAttributeTree.tree.get(newNode.GetNodeTitle()).currentNodeLevel);
if (playerAttributeTree.tree.get(newNode.GetNodeTitle()).currentNodeLevel != 0) { if (playerAttributeTree.tree.get(newNode.GetNodeTitle()).currentNodeLevel != 0) {
System.out.println("Registering new callback for new node"); System.out.println("Registering new callback for new node");
playerAttributeTree.tree.get(newNode.GetNodeTitle()).thisNode.RegisterCallbacks(); playerAttributeTree.tree.get(newNode.GetNodeTitle()).thisNode.RegisterCallbacks();
@ -213,18 +212,6 @@ public class AttributeTree {
FlashConfig(); FlashConfig();
} }
/////////////////////////////////////////////////////////////////////////////
/// @fn public Boolean ContainsAttribute(String nodeName) {
///
/// @arg[in] nodeName is the attribute node title
///
/// @brief Returns true if this player presently has the 'nodeName'
/// attribute unlocked
/////////////////////////////////////////////////////////////////////////////
public Boolean ContainsAttribute(String nodeName) {
return playerAttributeTree.tree.containsKey(nodeName);
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn DeleteNode /// @fn DeleteNode
/// ///
@ -278,35 +265,37 @@ public class AttributeTree {
/// ///
/// @brief Constructor for class /// @brief Constructor for class
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public AttributeTree(ServerPlayerEntity p) { public AttributeTree(String uuid) {
this.player = p; // DEVELOPER NOTE:
String uuid = player.getUuidAsString(); // If you are testing this part of the code, please be reminded that anonymous testing starts a new
// player instance everytime you launch. This means the UUID CAN CHANGE when you launch the
// game! This is not an issue with proper registered accounts in production
Boolean existingFile = false; Boolean existingFile = false;
try { try {
playerAttributeTree = config.GetJsonObjectFromFile("attributes/" + uuid + ".json", PlayerTree.class); playerAttributeTree = config.GetJsonObjectFromFile("attributes/" + uuid + ".json", PlayerTree.class);
existingFile = playerAttributeTree != null; existingFile = true;
} catch (Exception e) { } catch (Exception e) {
System.out.println("Attribute tree file does not exist for this player");
// Do nothing. This means the file does not exist // Do nothing. This means the file does not exist
} }
// In the event the above code failed out, this means a new file has to be created for the player's uuid // In the event the above code failed out, this means a new file has to be created for the player's uuid
if (!existingFile) if (!existingFile)
{ {
System.out.println("Trying to create new file"); System.out.println(ChatUtil.ColoredString("Trying to create new file", CONSOLE_COLOR.BLUE));
try { try {
playerAttributeTree = new PlayerTree();
playerAttributeTree.uuid = uuid; playerAttributeTree.uuid = uuid;
FlashConfig(); FlashConfig();
} catch (Exception e) { } catch (Exception e) {
System.out.println("Could not write to file"); System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED));
} }
} else {
System.out.println(ChatUtil.ColoredString("Moving on", CONSOLE_COLOR.BLUE));
} }
// It's possible the above code will return a blank class if a file doesn't exist. This will make // It's possible the above code will return a blank class if a file doesn't exist. This will make
// a new file with this players uuid // a new file with this players uuid
if ("".equals(playerAttributeTree.uuid)) { if ("".equals(playerAttributeTree.uuid)) {
System.out.println(ChatUtil.ColoredString("Assigning new config file for this uuid. No previous existing", CONSOLE_COLOR.BLUE));
playerAttributeTree.uuid = uuid; playerAttributeTree.uuid = uuid;
} }
@ -324,7 +313,10 @@ public class AttributeTree {
/// @brief Flashes the config to the disk /// @brief Flashes the config to the disk
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public void FlashConfig() { public void FlashConfig() {
/// TODO: This is broken because of a 'java.util.Option#value it cannot write. Idk, fix soon' try {
// config.WriteToJsonFile("attributes/" + playerAttributeTree.uuid + ".json", playerAttributeTree); config.WriteToJsonFile("attributes/" + playerAttributeTree.uuid + ".json", playerAttributeTree);
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED));
}
} }
} }

View File

@ -1,9 +0,0 @@
package jesse.keeblarcraft.BankMgr;
public class BankAccountType {
public enum ACCOUNT_TYPE {
CHECKING,
SAVINGS
}
}

View File

@ -5,7 +5,8 @@ import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Map.Entry; import java.util.Map.Entry;
import jesse.keeblarcraft.BankMgr.BankAccountType.ACCOUNT_TYPE; import org.apache.logging.log4j.core.jmx.Server;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
@ -25,8 +26,7 @@ public final class BankManager {
private class PlayerBankConfig { private class PlayerBankConfig {
List<String> activeBanks = new ArrayList<String>(); // List of all banks a player has accounts in List<String> activeBanks = new ArrayList<String>(); // List of all banks a player has accounts in
String defaultSelectedBank = ""; String defaultSelectedBank;
String defaultSelectedAccount = "";
} }
// Key = player uuid // Key = player uuid
@ -44,11 +44,7 @@ public final class BankManager {
// Val = Bank routing number // Val = Bank routing number
private HashMap<String, Integer> bankNameFastMap = new HashMap<String, Integer>(); private HashMap<String, Integer> bankNameFastMap = new HashMap<String, Integer>();
public BankManager() { public BankManager() {}
if (playerConfigs == null) {
playerConfigs = new HashMap<String, PlayerBankConfig>();
}
}
// TODO: THIS NEEDS TO READ IN FROM A FILE TO STOP NUKING BANKS ON REBOOT // TODO: THIS NEEDS TO READ IN FROM A FILE TO STOP NUKING BANKS ON REBOOT
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -122,14 +118,10 @@ public final class BankManager {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public void ChangeDefaultPlayerAccount(ServerPlayerEntity player, String newDefaultAccount) { public void ChangeDefaultPlayerAccount(ServerPlayerEntity player, String newDefaultAccount) {
String bankName = AccountNumberGenerator.GetFinancialSymbolFromId(newDefaultAccount); String bankName = AccountNumberGenerator.GetFinancialSymbolFromId(newDefaultAccount);
System.out.println("ChangeDefaultPlayerAccount: Received bankName " + bankName);
// Verify bank exists first
System.out.println(bankNameFastMap); System.out.println(bankNameFastMap);
for(Entry<String, Integer> entry : bankNameFastMap.entrySet()) { // Verify bank exists first
System.out.println("KEY: " + entry.getKey());
}
if (bankNameFastMap.containsKey(bankName)) { if (bankNameFastMap.containsKey(bankName)) {
Integer routNum = bankNameFastMap.get(bankName); Integer routNum = bankNameFastMap.get(bankName);
IndividualBank bank = banks.get(routNum); IndividualBank bank = banks.get(routNum);
@ -137,29 +129,10 @@ public final class BankManager {
// Verify this person has access to this account // Verify this person has access to this account
if(bank.IsAccountHolder(newDefaultAccount, player.getUuidAsString())) { if(bank.IsAccountHolder(newDefaultAccount, player.getUuidAsString())) {
// Finally update config to this account since checks pass // Finally update config to this account since checks pass
playerConfigs.get(player.getUuidAsString()).defaultSelectedAccount = newDefaultAccount; playerConfigs.get(player.getUuidAsString()).defaultSelectedBank = newDefaultAccount;
} }
} else { } else {
player.sendMessage(Text.of("Could not change default selected account. Bank does not exist!")); player.sendMessage(Text.of("Could not change default selected bank. Bank does not exist!"));
}
}
// This guarentees a player config exists; and so can be called from many areas. Does not erase pre-existing config
public boolean EnsurePlayerConfigExists(String uuid) {
if (!playerConfigs.containsKey(uuid)) {
playerConfigs.put(uuid, new PlayerBankConfig());
}
return true;
}
// Allows the player to select a bank
public void ChangeDefaultSelectedBank(ServerPlayerEntity player, String bankName) {
if (bankNameFastMap.containsKey(bankName) && EnsurePlayerConfigExists(player.getUuidAsString())) {
playerConfigs.get(player.getUuidAsString()).defaultSelectedBank = bankName;
player.sendMessage(Text.of("You have successfully selected the following financial institution: " + bankName));
player.sendMessage(Text.of("Please be aware the context of commands following this will likely be done under this financial institution"));
} else {
player.sendMessage(Text.of("That bank does not exist."));
} }
} }
@ -225,9 +198,9 @@ public final class BankManager {
/// ///
/// @brief Initiate a funds transfer between accounts or banks /// @brief Initiate a funds transfer between accounts or banks
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public void InitiateBankFundsTransfer(ServerPlayerEntity fromPlayer, String toAccount, Integer amount, String reason) { public void InitiateBankFundsTransfer(ServerPlayerEntity fromPlayer, String toAccount, Integer amount) {
// Get player default selection // Get player default selection
String fromAccount = playerConfigs.get(fromPlayer.getUuidAsString()).defaultSelectedAccount; String fromAccount = playerConfigs.get(fromPlayer.getUuidAsString()).defaultSelectedBank;
String fromAccountSymbol = AccountNumberGenerator.GetFinancialSymbolFromId(fromAccount); String fromAccountSymbol = AccountNumberGenerator.GetFinancialSymbolFromId(fromAccount);
String toAccountSymbol = AccountNumberGenerator.GetFinancialSymbolFromId(toAccount); String toAccountSymbol = AccountNumberGenerator.GetFinancialSymbolFromId(toAccount);
@ -273,21 +246,12 @@ public final class BankManager {
String account = ""; String account = "";
if (playerConfigs.containsKey(playerUuid)) { if (playerConfigs.containsKey(playerUuid)) {
account = playerConfigs.get(playerUuid).defaultSelectedAccount; account = playerConfigs.get(playerUuid).defaultSelectedBank;
} }
return account; return account;
} }
public String GetPlayerSelectedBank(String playerUuid) {
String bank = "";
if (playerConfigs.containsKey(playerUuid)) {
bank = playerConfigs.get(playerUuid).defaultSelectedBank;
}
return bank;
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn InitiateBankAccountCreation /// @fn InitiateBankAccountCreation
/// ///
@ -299,18 +263,40 @@ public final class BankManager {
/// ///
/// @brief Initiates a bank account creation with a bank /// @brief Initiates a bank account creation with a bank
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public void InitiateBankAccountCreation(String bankIdentifier, ServerPlayerEntity player, ACCOUNT_TYPE accountType) { public void InitiateBankAccountCreation(String bankIdentifier, ServerPlayerEntity player, String accountType) {
Boolean success = false; Boolean success = false;
IndividualBank bank = GetBankByName(bankIdentifier); System.out.println("initiating bank creation");
boolean defaultServerBank = bankIdentifier == null || bankIdentifier == "";
System.out.println("value of bankIdentifier is " + defaultServerBank);
if (bank != null) { System.out.println("The player name is " + player.getDisplayName().getString());
success = bank.CreateAccount(player.getUuidAsString(), player.getEntityName(), accountType);
// DEBUG
System.out.println("BANK NAME: " + banks.get(KEEBLARCRAFT_SERVER_BANK_ID).GetBankName());
System.out.println("BANK BALANCE: " + banks.get(KEEBLARCRAFT_SERVER_BANK_ID).GetBankBalance());
// DEBUG END
// Create an account via the server-owned bank account
if (defaultServerBank) {
success = banks.get(KEEBLARCRAFT_SERVER_BANK_ID).CreateAccount(player.getUuidAsString(), player.getDisplayName().getString(), accountType);
} else {
System.out.println("Creating bank on non-server owned bank");
// Create an account via a specified bank identifier
Integer routingNumber = Integer.parseInt(bankIdentifier);
if (banks.containsKey(routingNumber)) {
banks.get(routingNumber).CreateAccount(player.getUuidAsString(), player.getDisplayName().getString(), accountType);
} else {
player.sendMessage(Text.of("That bank does not exist"));
}
} }
if (success) { if (success) {
player.sendMessage(Text.of("The banking operation was successful and your banking information has been updated")); player.sendMessage(Text.of("The banking operation was successful and your banking information has been updated"));
} else { } else {
player.sendMessage(Text.of("The banking operating FAILED. Make sure you selected this bank before creating it!")); player.sendMessage(Text.of("The banking operating FAILED. You may need to visit the bank for more information!"));
} }
} }
} }

View File

@ -2,8 +2,6 @@ package jesse.keeblarcraft.BankMgr;
import java.util.List; import java.util.List;
import jesse.keeblarcraft.BankMgr.BankAccountType.ACCOUNT_TYPE;
// Contains the information of an individuals player's bank account. // 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 // TODO: Add ability to store NBT data of items in the future so we can store not just money but items too
// like a safety deposit box // like a safety deposit box
@ -18,14 +16,14 @@ public class IndividualAccount {
private Integer accountBalance; private Integer accountBalance;
private Boolean allowNegativeBalance; private Boolean allowNegativeBalance;
private Boolean accountLocked; private Boolean accountLocked;
private ACCOUNT_TYPE accountType; private Integer accountType; // TODO: Replace with enum in future. Valid is "checking" and "savings" right now
public IndividualAccount() {} public IndividualAccount() {}
public IndividualAccount(String accountNumber, Integer routingNumber, List<String> holders, public IndividualAccount(String accountNumber, Integer routingNumber, List<String> holders,
List<String> accountHolderUuids, Boolean allowNegativeBalance, Integer initialBalance, List<String> accountHolderUuids, Boolean allowNegativeBalance, Integer initialBalance,
String alias, ACCOUNT_TYPE accountType, String bankLetterIdentifier) { String alias, Integer accountType, String bankLetterIdentifier) {
System.out.println("Called to create new IndividualAccount with following values: " + accountNumber + " " + routingNumber + " " + holders + " " + System.out.println("Called to create new IndividualAccount with following values: " + accountNumber + " " + routingNumber + " " + holders + " " +
accountHolderUuids + " " + allowNegativeBalance + " " + initialBalance + " " + alias + " " + accountType); accountHolderUuids + " " + allowNegativeBalance + " " + initialBalance + " " + alias + " " + accountType);

View File

@ -11,22 +11,23 @@ import static java.util.Map.entry;
import java.io.File; import java.io.File;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.BankMgr.BankAccountType.ACCOUNT_TYPE; import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION;
// Contains the information of an individual bank // Contains the information of an individual bank
// //
// The bank will keep track of all accounts within its facilities. In addition to accounts, the 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. // maintains its own identifier which is unique and other misc things.
public class IndividualBank { public class IndividualBank {
private Map<ACCOUNT_TYPE, Integer> ACCOUNT_TYPES = Map.ofEntries( private Map<String, Integer> ACCOUNT_TYPES = Map.ofEntries(
entry(ACCOUNT_TYPE.CHECKING, 0), entry("checking", 0),
entry(ACCOUNT_TYPE.SAVINGS, 1) entry("savings", 1)
); );
private ConfigManager config = new ConfigManager(); private ConfigManager config = new ConfigManager();
private Integer routingNumber; // this is the banks unique identifier private Integer routingNumber; // this is the banks unique identifier
private Integer numberOfAccounts = 0; // Total number of accounts the bank has. This includes only active accounts inside accountsList. private Integer numberOfAccounts; // Total number of accounts the bank has. This includes only active accounts inside accountsList.
private Integer maxBankAccounts = 100_000_000; // Making this simple for myself any one type of account has 8 random numbers genereated so 10^8 possible accounts private Integer maxBankAccounts = 100_000_000; // Making this simple for myself any one type of account has 8 random numbers genereated so 10^8 possible accounts
private String bankFourLetterIdentifier; private String bankFourLetterIdentifier;
private String registeredBankName; private String registeredBankName;
@ -35,13 +36,13 @@ public class IndividualBank {
// Think FDIC but from the servers account (keeblarcraft insurance corporation) // Think FDIC but from the servers account (keeblarcraft insurance corporation)
// KBIC will ensure an amount of money based on its trustworthiness to a bank and the number of holders it has. // KBIC will ensure an amount of money based on its trustworthiness to a bank and the number of holders it has.
private Integer kbicInsuredAmount = 0; private Integer kbicInsuredAmount;
private Boolean kbicInsured = false; private Boolean kbicInsured;
// bankMoney is the total amount of money the bank possesses itself. The bank itself is personally responsible // 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. // 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 // A bank can have a sum of money that is less than the total amount of money of all its account holders
private Integer bankMoney = 0; private Integer bankMoney;
// Key = ACCOUNT NUMBER // Key = ACCOUNT NUMBER
// Value = ACCOUNT // Value = ACCOUNT
@ -88,7 +89,7 @@ public class IndividualBank {
// TODO: REPLACE WITH SQL SERVER. DIRTY ITERATE OVER ALL FILES IN DIRECTORY TO LOAD STRUCTURE // TODO: REPLACE WITH SQL SERVER. DIRTY ITERATE OVER ALL FILES IN DIRECTORY TO LOAD STRUCTURE
File dir = new File(accountsListDir); File dir = new File(accountsListDir);
File[] allFiles = dir.listFiles(); File[] allFiles = dir.listFiles();
if (accounts != null && allFiles != null) { if (allFiles != null) {
for (File file : allFiles ) { for (File file : allFiles ) {
// First grab file identifier as KEY // First grab file identifier as KEY
String accountIdentifier = file.getName(); String accountIdentifier = file.getName();
@ -106,6 +107,7 @@ public class IndividualBank {
if (!existingFile) if (!existingFile)
{ {
System.out.println(ChatUtil.ColoredString("Trying to create new file", CONSOLE_COLOR.BLUE));
try { try {
// We assume the bank dir is created by server. Create this banks dir // We assume the bank dir is created by server. Create this banks dir
// config.CreateDirectory("bank/" + routingNumber); // config.CreateDirectory("bank/" + routingNumber);
@ -115,15 +117,16 @@ public class IndividualBank {
// Flash initial account configuration file for this bank // Flash initial account configuration file for this bank
FlashConfig("accounts"); FlashConfig("accounts");
} catch (Exception e) { } catch (Exception e) {
Keeblarcraft.LOGGER.error("Could not write to file in IndividualBank"); System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED));
} }
} else {
System.out.println(ChatUtil.ColoredString("Moving on", CONSOLE_COLOR.BLUE));
} }
// A modified config reader is needed here for when each IndividualAccount is read in - the name is taken from that and is attached to the // A modified config reader is needed here for when each IndividualAccount is read in - the name is taken from that and is attached to the
// 'accountsListFromName' structure. This makes it no worse than O(n) to fill these two structures in. // 'accountsListFromName' structure. This makes it no worse than O(n) to fill these two structures in.
// NOTE: This is an *EXPENSIVE* operation! Future us might need to update this. Also note a method is needed for everytime a player opens a new account // NOTE: This is an *EXPENSIVE* operation! Future us might need to update this. Also note a method is needed for everytime a player opens a new account
// or gets put on one to update the map every time // or gets put on one to update the map every time
if (accounts != null) {
for (Entry<String, IndividualAccount> account : accounts.accountsList.entrySet()) { for (Entry<String, IndividualAccount> account : accounts.accountsList.entrySet()) {
// We must loop over the string of holders for each account as well to make the flattened accountsListFromName map // We must loop over the string of holders for each account as well to make the flattened accountsListFromName map
List<String> accountHolders = account.getValue().GetAccountHolders(); List<String> accountHolders = account.getValue().GetAccountHolders();
@ -140,10 +143,6 @@ public class IndividualBank {
} }
} }
numberOfAccounts = accounts.accountsList.size(); numberOfAccounts = accounts.accountsList.size();
} else {
accounts = new Accounts();
numberOfAccounts = 0;
}
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -165,9 +164,12 @@ public class IndividualBank {
/// @return List of all bank accounts. List will be EMPTY if no accounts /// @return List of all bank accounts. List will be EMPTY if no accounts
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public List<IndividualAccount> GetAccountsOfUser(String uuid) { public List<IndividualAccount> GetAccountsOfUser(String uuid) {
System.out.println("UUID passed in: " + uuid);
List<IndividualAccount> accountsFromUser = new ArrayList<IndividualAccount>(); List<IndividualAccount> accountsFromUser = new ArrayList<IndividualAccount>();
List<String> listOfAccounts = accounts.accountsListFromName.get(uuid); 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) { if (listOfAccounts != null && listOfAccounts.size() > 0) {
for (int i = 0; i < listOfAccounts.size(); i++) { for (int i = 0; i < listOfAccounts.size(); i++) {
accountsFromUser.add(accounts.accountsList.get(listOfAccounts.get(i))); accountsFromUser.add(accounts.accountsList.get(listOfAccounts.get(i)));
@ -368,14 +370,17 @@ public class IndividualBank {
/// ///
/// @return True if account can be created, false if it fails /// @return True if account can be created, false if it fails
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public Boolean CreateAccount(String holderUuid, String holderName, ACCOUNT_TYPE accountType) { public Boolean CreateAccount(String holderUuid, String holderName, String accountTypeStr) {
Boolean success = false; Boolean success = false;
if (accounts.accountsList.size() <= maxBankAccounts) { System.out.println("Attempting to create new bank account given args UUID / NAME / TYPE : " + holderUuid + " " + holderName + " " + accountTypeStr);
System.out.println("accounts size is " + accounts.accountsList.size());
System.out.println("account string is { " + accountTypeStr + " }. Does this account type exist in this bank? => " + ACCOUNT_TYPES.containsKey(accountTypeStr.toLowerCase()));
if (accounts.accountsList.size() <= maxBankAccounts && ACCOUNT_TYPES.containsKey(accountTypeStr.toLowerCase())) {
// Verify this isn't a blacklisted user // Verify this isn't a blacklisted user
System.out.println("Is user bank locked? " + lockedUsers.contains(holderName)); System.out.println("Is user bank locked? " + lockedUsers.contains(holderName));
if (!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. Integer maxAttempts = 15; // Reasonably a unique bank account should pop up within 1000 generations. If not, the user may try again.
String accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountType), holderName); 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("Account generator came back with bank account id { " + accountId + " }");
System.out.println("4 letter bank: " + AccountNumberGenerator.GetFinancialSymbolFromId(accountId)); System.out.println("4 letter bank: " + AccountNumberGenerator.GetFinancialSymbolFromId(accountId));
@ -386,7 +391,7 @@ public class IndividualBank {
// TODO: Fix in future with a method that will guarentee a one-time necessary number generator. Statistically speaking; this will be okay for the // TODO: Fix in future with a method that will guarentee a one-time necessary number generator. Statistically speaking; this will be okay for the
// entire life time of the server. BUT, you never know! // entire life time of the server. BUT, you never know!
while (maxAttempts != 0 && !accounts.accountsList.containsKey(AccountNumberGenerator.GetAccountNumberFromId(accountId))) { while (maxAttempts != 0 && !accounts.accountsList.containsKey(AccountNumberGenerator.GetAccountNumberFromId(accountId))) {
accountId = AccountNumberGenerator.GenerateNewAccountNumber(bankFourLetterIdentifier, routingNumber, ACCOUNT_TYPES.get(accountType), holderName); 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("Account generator came back with bank account id { " + accountId + " }");
maxAttempts--; maxAttempts--;
} }
@ -397,7 +402,7 @@ public class IndividualBank {
if (!accounts.accountsList.containsKey(actualAccountNumber)) { if (!accounts.accountsList.containsKey(actualAccountNumber)) {
IndividualAccount newAccount = new IndividualAccount(actualAccountNumber, this.routingNumber, List.of(holderName), IndividualAccount newAccount = new IndividualAccount(actualAccountNumber, this.routingNumber, List.of(holderName),
List.of(holderUuid), false, 0, List.of(holderUuid), false, 0,
"", accountType, bankFourLetterIdentifier); "", ACCOUNT_TYPES.get(accountTypeStr), bankFourLetterIdentifier);
System.out.println("Updating accounts list for this bank"); System.out.println("Updating accounts list for this bank");
UpdateBankAccounts(holderName, holderUuid, actualAccountNumber, newAccount); UpdateBankAccounts(holderName, holderUuid, actualAccountNumber, newAccount);
success = true; success = true;
@ -559,7 +564,12 @@ public class IndividualBank {
} }
// Re-flash file // Re-flash file
try {
config.WriteToJsonFile(dirName + "/" + accountNum + ".json", singleAccount.getValue()); config.WriteToJsonFile(dirName + "/" + accountNum + ".json", singleAccount.getValue());
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println("Failed to flash configuration file properly. Printing stack trace");
e.printStackTrace();
}
} }
} }
} }

View File

@ -4,13 +4,11 @@ package jesse.keeblarcraft.BankMgr;
public class TransactionMetadata { public class TransactionMetadata {
enum TRANSACTION_TYPE { enum TRANSACTION_TYPE {
DEBIT, DEBIT,
CREDIT, CREDIT
WITHDRAWAL,
DEPOSIT
} }
public String fromParty; // Account ID public String fromParty; // Account ID
public String toParty; // Account ID or party (like ATM/self,etc) public String toParty; // Account ID
public Integer amount; public Integer amount;
public String transactionId; public String transactionId;
public TRANSACTION_TYPE transactionType; public TRANSACTION_TYPE transactionType;

View File

@ -1,43 +0,0 @@
package jesse.keeblarcraft.ChatStuff;
public class ChatFormatting {
// These are for Minecraft chat box
public static String COLOR_START = "§";
public static String COLOR_END = "§f";
public static 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
/////////////////////////////////////////////////////////////////////////////
public static 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;
}
}

View File

@ -1,68 +0,0 @@
package jesse.keeblarcraft.ChatStuff;
import java.util.ArrayList;
import java.util.List;
import jesse.keeblarcraft.ChatStuff.ChatFormatting.COLOR_CODE;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
// Create a "chat menu" which is just a menu in chat with pages that a user can click to display
// the next page.
public class ChatMenu {
private List<Text> msgList = new ArrayList<>();
private Text header;
private Text leftArrow;
private Text rightArrow;
private int pageLimit = 5; // Messages per page in this menu
private int pageCount = 1; // Calculated at runtime
private ChatMsg formatter = new ChatMsg();
public ChatMenu() {
// Initialize default header and arrows
header = Text.of("[----- HELP MENU -----]");
header = formatter.ColorMsg(header, COLOR_CODE.GOLD);
leftArrow = Text.of("<<");
leftArrow = formatter.ColorMsg(leftArrow, COLOR_CODE.GOLD);
rightArrow = Text.of(">>");
rightArrow = formatter.ColorMsg(rightArrow, COLOR_CODE.GOLD);
}
public void SetHeader(Text header) {
this.header = header;
}
public void SetLeftArrow(Text leftArrow) {
this.leftArrow = leftArrow;
}
public void SetRightArrow(Text rightArrow) {
this.rightArrow = rightArrow;
}
public void AddMsg(Text newMsg) {
msgList.add(newMsg);
}
public void AddMsg(String newMsg) {
AddMsg(Text.of(newMsg));
}
public void ClearList() {
msgList.clear();
pageCount = 1;
}
public void SetPageLimit(int limit) {
if (limit >= 1) {
pageLimit = limit;
}
}
public void SendMsg(ServerPlayerEntity target) {
// Calculate number of pages
pageCount = (int) Math.ceil(msgList.size() / (double) pageLimit);
}
}

View File

@ -75,7 +75,10 @@ public class AttributeCommands {
public int ApplyAttribute(ServerPlayerEntity targetPlayer, String attributeName, CommandContext<ServerCommandSource> context) { public int ApplyAttribute(ServerPlayerEntity targetPlayer, String attributeName, CommandContext<ServerCommandSource> context) {
int ret = -1; int ret = -1;
System.out.println("Applying attribute");
if (context.getSource().isExecutedByPlayer()) { if (context.getSource().isExecutedByPlayer()) {
System.out.println("Executed by player");
String result = AttributeMgr.ApplyAttribute(targetPlayer.getUuidAsString(), attributeName); String result = AttributeMgr.ApplyAttribute(targetPlayer.getUuidAsString(), attributeName);
Keeblarcraft.LOGGER.info("[ApplyAttribute] -> " + result); Keeblarcraft.LOGGER.info("[ApplyAttribute] -> " + result);
context.getSource().getPlayer().sendMessage(Text.of(result)); context.getSource().getPlayer().sendMessage(Text.of(result));

View File

@ -1,24 +1,20 @@
package jesse.keeblarcraft.Commands; package jesse.keeblarcraft.Commands;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import static java.util.Map.entry; import static java.util.Map.entry;
import jesse.keeblarcraft.BankMgr.BankAccountType;
import jesse.keeblarcraft.BankMgr.BankManager; import jesse.keeblarcraft.BankMgr.BankManager;
import jesse.keeblarcraft.BankMgr.IndividualAccount; import jesse.keeblarcraft.BankMgr.IndividualAccount;
import jesse.keeblarcraft.BankMgr.IndividualBank; import jesse.keeblarcraft.BankMgr.IndividualBank;
import jesse.keeblarcraft.BankMgr.BankAccountType.ACCOUNT_TYPE;
import jesse.keeblarcraft.ChatStuff.ChatFormatting.COLOR_CODE;
import jesse.keeblarcraft.ChatStuff.ChatMsg;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Utils.HelpBuilder;
import jesse.keeblarcraft.Utils.HelpBuilder.COLOR_CODE;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
@ -56,7 +52,7 @@ public class BankCommands {
private static String HELPCMD_ADMIN_ACCOUNTS_TRANSACTIONS = "admin-accounts-transactions"; private static String HELPCMD_ADMIN_ACCOUNTS_TRANSACTIONS = "admin-accounts-transactions";
private static String HELPCMD_ADMIN_ACCOUNTS_LOCK = "admin-accounts-lock"; private static String HELPCMD_ADMIN_ACCOUNTS_LOCK = "admin-accounts-lock";
ChatMsg msgFormatter = new ChatMsg(); HelpBuilder msgFormatter = new HelpBuilder();
private static Map<String, String> HELP_COMMANDS = Map.ofEntries( private static Map<String, String> HELP_COMMANDS = Map.ofEntries(
entry entry
@ -200,206 +196,148 @@ public class BankCommands {
/// @brief Registers all bank commands on the server /// @brief Registers all bank commands on the server
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public void RegisterCommands() { public void RegisterCommands() {
// Bank help
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
// This is basically a small re-created SQL language but for bank commands. I recommend asking me for the drawn
// image to better understand what this is accomplishing if it is confusing. Essentially it is easy though, as it
// is just /bank ACTION-WORD [arguments...] [optionals]
var bankRoot = CommandManager.literal("bank").build(); var bankRoot = CommandManager.literal("bank").build();
var help = CommandManager.literal("help").build();
var helpTarget = CommandManager.argument("target", StringArgumentType.greedyString()) // Removing "argList" and just running the entire list as an argList from actionWord makes `/bank help` possible
.executes(context -> HelpCommand(context.getSource().getPlayer(), StringArgumentType.getString(context, "target"))) var argList = CommandManager.argument("ARG_LIST", StringArgumentType.greedyString())
.executes(context -> ParseBankCommand
(
context,
StringArgumentType.getString(context, "ARG_LIST"))
)
.build(); .build();
var info = CommandManager.literal("info")
.executes(context -> ListBankInfo(context.getSource().getPlayer()))
.build();
bankRoot.addChild(info);
var create = CommandManager.literal("create").build();
var createAccount = CommandManager.literal("account").build();
var checking = CommandManager.literal("checking")
.executes(context -> CreateAccount(context.getSource().getPlayer(), ACCOUNT_TYPE.CHECKING))
.build();
var savings = CommandManager.literal("savings")
.executes(context -> CreateAccount(context.getSource().getPlayer(), ACCOUNT_TYPE.SAVINGS))
.build();
bankRoot.addChild(create);
create.addChild(createAccount);
createAccount.addChild(checking);
createAccount.addChild(savings);
var wireCmd = CommandManager.literal("wire").build();
var accountNum = CommandManager.argument("account", StringArgumentType.string()).build();
var wireAmount = CommandManager.argument("amount", IntegerArgumentType.integer()).build();
var wireReason = CommandManager.argument("reason", StringArgumentType.greedyString())
.executes(context -> WireCommand(
context.getSource().getPlayer(),
IntegerArgumentType.getInteger(context, "amount"),
StringArgumentType.getString(context, "account"),
StringArgumentType.getString(context, "reason")
))
.build();
bankRoot.addChild(wireCmd);
wireCmd.addChild(accountNum);
accountNum.addChild(wireAmount);
wireAmount.addChild(wireReason);
var list = CommandManager.literal("list")
.executes(context -> ListAllBanks(context.getSource().getPlayer()))
.build();
bankRoot.addChild(list);
var selectBankAccount = CommandManager.literal("select-default-account").build();
var selectBankAccountName = CommandManager.argument("global-account-id", StringArgumentType.string())
.executes(context -> SelectDefaultAccount(context.getSource().getPlayer(), StringArgumentType.getString(context, "global-account-id")))
.build();
bankRoot.addChild(selectBankAccount);
selectBankAccount.addChild(selectBankAccountName);
var selectBank = CommandManager.literal("select-bank").build();
var selectBankName = CommandManager.argument("global_bank_name", StringArgumentType.string())
.executes(context -> SelectBank(context.getSource().getPlayer(), StringArgumentType.getString(context, "global_bank_name")))
.build();
bankRoot.addChild(selectBank);
selectBank.addChild(selectBankName);
var close = CommandManager.literal("close").build();
var closeAccountId = CommandManager.argument("account", StringArgumentType.string())
.executes(context -> CloseCommand(context.getSource().getPlayer(), StringArgumentType.getString(context, "account")))
.build();
bankRoot.addChild(close);
close.addChild(closeAccountId);
var moveCmd = CommandManager.literal("move").build();
var moveAmount = CommandManager.argument("move_amount", IntegerArgumentType.integer()).build();
var fromAccount = CommandManager.argument("from_account", StringArgumentType.string()).build();
var toAccount = CommandManager.argument("to_account", StringArgumentType.string())
.executes(context -> MoveCommand(
context.getSource().getPlayer(),
IntegerArgumentType.getInteger(context, "move_amount"),
StringArgumentType.getString(context, "from_account"),
StringArgumentType.getString(context, "to_account")
))
.build();
bankRoot.addChild(moveCmd);
moveCmd.addChild(moveAmount);
moveAmount.addChild(fromAccount);
fromAccount.addChild(toAccount);
var admin = CommandManager.literal("admin").build();
// var accounts = CommandManager.literal("accounts").build();
var subtractMoney = CommandManager.literal("sub-money").build();
var subtractAmount = CommandManager.argument("sub_amount", IntegerArgumentType.integer()).build();
var subtractAccount = CommandManager.argument("sub_account", StringArgumentType.string()).build();
var subtractReason = CommandManager.argument("sub_reason", StringArgumentType.greedyString())
.executes(context -> AdminSubtractMoney(
context.getSource().getPlayer(),
IntegerArgumentType.getInteger(context, "sub_amount"),
StringArgumentType.getString(context, "sub_account"),
StringArgumentType.getString(context, "sub_reason")
))
.build();
var addMoney = CommandManager.literal("add-money").build();
var addAmount = CommandManager.argument("add_amount", IntegerArgumentType.integer()).build();
var addAccount = CommandManager.argument("add_account", StringArgumentType.string()).build();
var addReason = CommandManager.argument("add_reason", StringArgumentType.greedyString())
.executes(context -> AdminAddMoney(
context.getSource().getPlayer(),
IntegerArgumentType.getInteger(context, "add_amount"),
StringArgumentType.getString(context, "add_account"),
StringArgumentType.getString(context, "add_reason")
))
.build();
var setMoney = CommandManager.literal("set-bal").build();
var setAmnt = CommandManager.argument("set_amount", IntegerArgumentType.integer()).build();
var setAccount = CommandManager.argument("set_account", StringArgumentType.string()).build();
var setReason = CommandManager.argument("set_reason", StringArgumentType.greedyString())
.executes(context -> AdminSetMoney(
context.getSource().getPlayer(),
IntegerArgumentType.getInteger(context, "set_amount"),
StringArgumentType.getString(context, "set_account"),
StringArgumentType.getString(context, "set_reason")
))
.build();
var getBal = CommandManager.literal("get-bal").build();
var getBalTgt = CommandManager.argument("get_bal_target", StringArgumentType.string()).build();
var createBank = CommandManager.literal("create-bank").build();
var createBankName = CommandManager.argument("create_bank_name", StringArgumentType.string()).build();
var closeBank = CommandManager.literal("close-bank").build();
var closeBankName = CommandManager.argument("close_bank_name", StringArgumentType.string()).build();
var setServerBal = CommandManager.literal("set-server-bal").build();
var setServerBalAmnt = CommandManager.argument("set_server_bal_amount", StringArgumentType.string()).build();
var setServerAllowance = CommandManager.literal("set-server-allowance").build();
var setServerAllowanceAmount = CommandManager.argument("set_server_allowance", IntegerArgumentType.integer()).build();
bankRoot.addChild(admin);
admin.addChild(subtractMoney);
subtractMoney.addChild(subtractAmount);
subtractAmount.addChild(subtractAccount);
subtractAccount.addChild(subtractReason);
admin.addChild(addMoney);
addMoney.addChild(addAmount);
addAmount.addChild(addAccount);
addAccount.addChild(addReason);
admin.addChild(setMoney);
setMoney.addChild(setAmnt);
setAmnt.addChild(setAccount);
setAccount.addChild(setReason);
admin.addChild(getBal);
getBal.addChild(getBalTgt);
admin.addChild(createBank);
createBank.addChild(createBankName);
admin.addChild(closeBank);
admin.addChild(closeBankName);
admin.addChild(setServerBal);
setServerBal.addChild(setServerBalAmnt);
admin.addChild(setServerAllowance);
setServerAllowance.addChild(setServerAllowanceAmount);
// Building the argument tree here // Building the argument tree here
dispatcher.getRoot().addChild(bankRoot); dispatcher.getRoot().addChild(bankRoot);
bankRoot.addChild(help); bankRoot.addChild(argList);
help.addChild(helpTarget);
}); });
} }
public int SelectBank(ServerPlayerEntity player, String bank) { /////////////////////////////////////////////////////////////////////////////
System.out.println("Select bank called"); /// @fn RemoveFillerWords
BankManager.GetInstance().ChangeDefaultSelectedBank(player, bank); ///
/// @brief Takes in a list of arguments with the intention to remove
/// all words found in the filler list. This helps with dynamic
/// typing
///
/// @return List of arguments without filler words
/////////////////////////////////////////////////////////////////////////////
public List<String> RemoveFillerWords(List<String> argList) {
int index = 0;
for (String str : argList) {
if (FILLER_WORDS.contains(str)) {
argList.remove(index);
}
// Also make every word lower case
str = str.toLowerCase();
index++;
}
return argList;
}
/////////////////////////////////////////////////////////////////////////////
/// @fn ParseBankCommand
///
/// @brief Parses the global bank command
/////////////////////////////////////////////////////////////////////////////
public int ParseBankCommand(CommandContext<ServerCommandSource> context, String unformattedArgList) {
List<String> formattedArgList = List.of(unformattedArgList.split("\\s+")); // REGEX is matching 1+ whitespace characters
System.out.println("After formatting the arg list, the size of arg list is size { " + formattedArgList.size() + " }");
formattedArgList = RemoveFillerWords(formattedArgList);
String actionWord = formattedArgList.get(0);
System.out.println("The action word for this operation is " + actionWord.toUpperCase());
System.out.println("Parsing bank command on action word { " + actionWord + " } with arg list { " + formattedArgList + " }");
switch(actionWord)
{
case "create":
System.out.println("Calling create command...");
CreateCommand(context.getSource().getPlayer(), formattedArgList.subList(1, formattedArgList.size()));
break;
case "close":
CloseCommand(context.getSource().getPlayer(), formattedArgList);
break;
case "select":
SelectCommand(context.getSource().getPlayer(), formattedArgList.subList(1, formattedArgList.size()));
break;
case "wire":
WireCommand(context.getSource().getPlayer(), formattedArgList.subList(1, formattedArgList.size()));
break;
case "balance":
BalanceCommand(context.getSource().getPlayer(), formattedArgList);
break;
case "help":
HelpCommand(context.getSource().getPlayer(), formattedArgList);
break;
case "move":
MoveCommand(context.getSource().getPlayer(), formattedArgList);
break;
case "alias":
AliasCommand(context.getSource().getPlayer(), formattedArgList);
break;
case "report":
ReportCommand(context.getSource().getPlayer(), formattedArgList);
break;
case "examples":
HelpCommand(context.getSource().getPlayer(), List.of(HELPCMD_EXAMPLES));
break;
case "syntax":
HelpCommand(context.getSource().getPlayer(), List.of(HELPCMD_SYNTAX));
break;
case "list":
ListAllBanks(context.getSource().getPlayer(), formattedArgList);
break;
case "account":
case "accounts":
ManageAccounts(context.getSource().getPlayer(), formattedArgList.subList(1, formattedArgList.size()));
break;
case "admin":
AdminCommand(context.getSource().getPlayer(), formattedArgList.subList(1, formattedArgList.size()));
break;
default:
if (context.getSource().isExecutedByPlayer()) {
context.getSource().getPlayer().sendMessage(Text.of("You have entered an improperly formatted message. Please reference the bank manual if you are confused how to form a command!"));
}
break;
}
return 0; return 0;
} }
/////////////////////////////////////////////////////////////////////////////
/// @fn ParseToInteger
///
/// @param[in] player is the player to send message to on failure
///
/// @param[in] possibleInt is string to be parsed
///
/// @param[in] helpCmd is help command to send player on failure to parse
///
/// @brief Helper is designed to parse a string to a number (helpful in
/// banking) and upon a failure of parse send a designated help
/// message for that command (this system is non-trivial to use)
///
/// @return The parsed integer if successful parse. If false, the server
/// should catch and a help command is sent
/////////////////////////////////////////////////////////////////////////////
public Integer ParseToInteger(ServerPlayerEntity player, String possibleInt, String helpCmd) {
Integer amount = 0;
try {
amount = Integer.parseInt(possibleInt);
} catch (NumberFormatException exception) {
HelpCommand(player, List.of(helpCmd));
}
System.out.println("ParseToInteger was called. The input was " + possibleInt + " and the parsed int is " + amount);
return amount;
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn IsOperator /// @fn IsOperator
/// ///
@ -417,19 +355,166 @@ public class BankCommands {
} }
} }
public int AdminSubtractMoney(ServerPlayerEntity player, Integer amount, String account, String reason) { // Possible code paths ({}=required, []=optionals, ()=explanation):
AdminBalanceChange(player, account, amount, "subtract", reason); // REQUIRED (path) = {SetBal|AddMoney|SubMoney} {LONG_ID|BANK_ID} {amount} (Depending on context, changes balance somehow from an account ID or bank)
return 0; // REQUIRED (path) = {GetBal} {LONG_ID:BANK_ID} (Gets the balance of a bank account or bank)
// REQUIRED (path) = {accounts} {list} {PLAYER_NAME} (Returns summarized account information on a player)
// REQUIRED (path) = {accounts} {move} {LONG_ID} to {BANK_ID} (Will move account to diff bank. May generate new account ID)
// REQUIRED (path) = {accounts} {force-close} {LOND_ID} (Forces an account to be closed. Money is returned to server bank account)
// REQUIRED (path) = {accounts} {add} to {PLAYER_NAME} [BANK_ID] (Adds an account to a player to server by default. Specify other for other)
// REQUIRED (path) = {accounts} {transactions} from {LONG_ID} (Gets transaction report from an account by ID)
// REQUIRED (path) = {accounts} {lock} {LONG_ID:USER} (Locks a specific bank account OR all bank accounts owned by $USER)
// REQUIRED (path) = {create-bank} {BANK_ID} (Create a new bank. Default is owned by server)
// REQUIRED (path) = {close-bank} {BANK_ID} (Closing a bank forces a close on all accounts. Banks money is returned to server bank)
// REQUIRED (path) = {lock-bank} {BANK_ID} (Freezes all activities through a bank)
// REQUIRED (path) = {unlock} {BANK_ID:ACCOUNT_ID:USER} (will unlock a bank, account, or all of a users accounts)
// REQUIRED (path) = {wire} {amount} from {ACCOUNT_ID} to {ACCOUNT_ID} (Forces a wire from one account to another. Overrides overdraft setting since it's administrative)
// REQUIRED (path) = {get-server-allowance} (Returns the rate of which the server adds money to itself magically & how much)
// REQUIRED (path) = {set-server-allowance} {amount} {interval} (Sets the magic allowance rate of server & period in which it does it to add money magically to server bank)
/////////////////////////////////////////////////////////////////////////////
/// @fn AdminCommand
///
/// @param[in] sourcePlayer is player running command
///
/// @param[in] argList is the argument list to be parsed
///
/// @brief Code paths should be read in above comment. Primary admin list
/// of commands that are possible to run
/////////////////////////////////////////////////////////////////////////////
public void AdminCommand(ServerPlayerEntity sourcePlayer, List<String> argList) {
// The player must be opped & the size must be at LEAST 2 (1 keyword + extra for sublist)
String pName = sourcePlayer.getDisplayName().toString();
System.out.println("Is player admin? " + (IsOperator(sourcePlayer) ? "YES" : "NO"));
if (IsOperator(sourcePlayer) && argList.size() >= 1) {
String arg = argList.get(0);
List<String> remainingArgs = argList.subList(1, argList.size());
switch (arg) {
case "account":
case "accounts":
break;
case "submoney":
case "subtract-money":
case "subtractmoney":
case "sub-money":
// Require account identifier + balance
if (remainingArgs.size() >= 2) {
String accountId = remainingArgs.get(0);
Integer amount = ParseToInteger(sourcePlayer, remainingArgs.get(1), HELPCMD_ADMIN_BALANCE_CHANGE);
String optionalReason = "";
if (remainingArgs.size() >= 3) {
optionalReason = remainingArgs.get(2);
} }
public int AdminAddMoney(ServerPlayerEntity player, Integer amount, String account, String reason) { AdminBalanceChange(sourcePlayer, accountId, amount, "subtract", optionalReason);
AdminBalanceChange(player, account, amount, "add", reason); } else {
return 0; HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_BALANCE_CHANGE));
}
break;
case "addmoney":
case "add-money":
// Require account identifier + balance
if (remainingArgs.size() >= 2) {
String accountId = remainingArgs.get(0);
Integer amount = ParseToInteger(sourcePlayer, remainingArgs.get(1), HELPCMD_ADMIN_BALANCE_CHANGE);
String optionalReason = "";
if (remainingArgs.size() >= 3) {
optionalReason = remainingArgs.get(2);
} }
public int AdminSetMoney(ServerPlayerEntity player, Integer amount, String account, String reason) { AdminBalanceChange(sourcePlayer, accountId, amount, "add", optionalReason);
AdminBalanceChange(player, account, amount, "set", reason); } else {
return 0; HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_BALANCE_CHANGE));
}
break;
case "setbal":
case "set-bal":
case "setbalance":
case "set-balance":
// Require account identifier + balance
if (remainingArgs.size() >= 2) {
String accountId = remainingArgs.get(0);
Integer amount = ParseToInteger(sourcePlayer, remainingArgs.get(1), HELPCMD_ADMIN_BALANCE_CHANGE);
String optionalReason = "";
if (remainingArgs.size() >= 3) {
optionalReason = remainingArgs.get(2);
}
System.out.println("Running set-balance with amount " + amount);
if (amount != 0) {
AdminBalanceChange(sourcePlayer, accountId, amount, "set", optionalReason);
} else {
HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_BALANCE_CHANGE));
}
} else {
HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_BALANCE_CHANGE));
}
break;
case "getbal":
case "get-bal":
case "getbalance":
case "get-balance":
// Require account identifier
if (remainingArgs.size() >= 1) {
} else {
HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_BALANCE_GET));
}
break;
case "createbank":
case "create-bank":
if (remainingArgs.size() >= 1) {
} else {
HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_CREATE_BANK));
}
break;
case "closebank":
case "close-bank":
if (remainingArgs.size() >= 1) {
} else {
HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_CLOSE_BANK));
}
break;
case "forcewire":
case "force-wire":
case "wiremoney":
case "wire-money":
case "wire":
if (remainingArgs.size() >= 3) {
} else {
HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_FORCE_WIRE));
}
break;
case "lock-bank":
case "lockbank":
if (remainingArgs.size() >= 1) {
} else {
HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_LOCK_BANK));
}
break;
case "get-server-allowance":
case "getserverallowance":
sourcePlayer.sendMessage(Text.of(GetServerAllowance()));
break;
case "setserverallowance":
case "set-server-allowance":
if (remainingArgs.size() >= 1) {
} else {
HelpCommand(sourcePlayer, List.of(HELPCMD_SET_SERVER_ALLOWANCE));
}
break;
default:
HelpCommand(sourcePlayer, List.of(HELPCMD_ADMIN_COMMANDS_LIST));
break;
}
} else {
sourcePlayer.sendMessage(Text.of("Only admins can use this command!"));
}
} }
public String GetServerAllowance() { public String GetServerAllowance() {
@ -453,6 +538,7 @@ public class BankCommands {
/// amount /// amount
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public void AdminBalanceChange(ServerPlayerEntity player, String accountId, Integer amount, String type, String optionalReason) { public void AdminBalanceChange(ServerPlayerEntity player, String accountId, Integer amount, String type, String optionalReason) {
System.out.println("AdminChangeFunds on account " + accountId);
BankManager.GetInstance().AdminChangeFunds(player, accountId, amount, type, optionalReason); BankManager.GetInstance().AdminChangeFunds(player, accountId, amount, type, optionalReason);
} }
@ -496,9 +582,15 @@ public class BankCommands {
/// ///
/// @brief Change the balance of a designated account /// @brief Change the balance of a designated account
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public int ListBankInfo(ServerPlayerEntity sourcePlayer) { public void ManageAccounts(ServerPlayerEntity sourcePlayer, List<String> argList) {
String bankName = BankManager.GetInstance().GetPlayerSelectedBank(sourcePlayer.getUuidAsString()); System.out.println("Manage accounts arg list is { " + argList + " }");
if (argList.size() > 0) {
// TODO: For now we assume they reference the bank name and not routing #
String bankName = argList.get(0).toUpperCase();
IndividualBank bank = BankManager.GetInstance().GetBankByName(bankName); IndividualBank bank = BankManager.GetInstance().GetBankByName(bankName);
System.out.println("Test print on memory");
Boolean isNull = bank == null;
System.out.println("isNull: " + isNull);
if (bank != null) { if (bank != null) {
System.out.println("Grabbing user account information"); System.out.println("Grabbing user account information");
@ -526,13 +618,13 @@ public class BankCommands {
} else { } else {
sourcePlayer.sendMessage(Text.of(msgFormatter.ColorMsg("That bank does not exist", COLOR_CODE.RED))); sourcePlayer.sendMessage(Text.of(msgFormatter.ColorMsg("That bank does not exist", COLOR_CODE.RED)));
} }
return 0; } else {
sourcePlayer.sendMessage(Text.of("Unrecognized move command. Please use \"/bank help ACCOUNTS\" for more information."));
}
} }
// TODO: make prettier public void ListAllBanks(ServerPlayerEntity sourcePlayer, List<String> argList) {
public int ListAllBanks(ServerPlayerEntity sourcePlayer) {
sourcePlayer.sendMessage(Text.of("Here is a list of available banks on the server: " + BankManager.GetInstance().GetAllBankNames())); sourcePlayer.sendMessage(Text.of("Here is a list of available banks on the server: " + BankManager.GetInstance().GetAllBankNames()));
return 0;
} }
// Possible code paths: // Possible code paths:
@ -548,8 +640,39 @@ public class BankCommands {
/// ///
/// @brief Command to move account. Read above comment for code paths /// @brief Command to move account. Read above comment for code paths
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public int MoveCommand(ServerPlayerEntity sourcePlayer, Integer amount, String fromAccount, String toAccount) { public void MoveCommand(ServerPlayerEntity sourcePlayer, List<String> argList) {
return 0; if (argList.size() >= 2) {
String possibleExternalIdentifier = argList.get(1);
boolean isExternalTransfer = false;
/*
* CALL TO BANKMGR TO VERIFY IF ABOVE IS VALID BANK ID. IF NOT; THIS IS INTERNAL TRANSFER
*/
if (isExternalTransfer) {
// External move to another bank or faction
String targetMoveAccount = argList.get(0);
String destBankId = argList.get(1);
/*
* CALL TO BANKMGR TO MOVE ACCOUNTS HERE
*/
} else {
// Internal transfer to this players accounts within system
String optionalFromAccount = ""; /* CALL TO BANKMGR TO GET DEFAULT SELECTED ACCOUNT FOR `FROM` FIELD */
if (argList.size() == 3) {
optionalFromAccount = argList.get(1);
}
String transferAmount = argList.get(0);
String destinationTransfer = argList.get(2);
/*
* BANK MGR CALL HERE
*/
}
} else {
sourcePlayer.sendMessage(Text.of("Unrecognized move command. Please use \"/bank help MOVE\" for more information."));
}
} }
// Posible code paths: // Posible code paths:
@ -590,14 +713,14 @@ public class BankCommands {
/// @brief Shorthand function call-through to CreateCommand for generating /// @brief Shorthand function call-through to CreateCommand for generating
/// an account(s) report. /// an account(s) report.
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// public void ReportCommand(ServerPlayerEntity sourcePlayer, List<String> argList) { public void ReportCommand(ServerPlayerEntity sourcePlayer, List<String> argList) {
// if (argList.size() > 0) { if (argList.size() > 0) {
// argList.add(0, "report"); // Since we lose 'report' when we pass it as an alias/passthrough; we just shim it into the first spot argList.add(0, "report"); // Since we lose 'report' when we pass it as an alias/passthrough; we just shim it into the first spot
// CreateCommand(sourcePlayer, argList); CreateCommand(sourcePlayer, argList);
// } else { } else {
// sourcePlayer.sendMessage(Text.of("Unrecognized report command. Please run \"/bank help REPORT\" for more information.")); sourcePlayer.sendMessage(Text.of("Unrecognized report command. Please run \"/bank help REPORT\" for more information."));
// } }
// } }
// Possible code paths: // Possible code paths:
// REQUIRED = {} // REQUIRED = {}
@ -623,29 +746,88 @@ public class BankCommands {
return 0; return 0;
} }
// Create command - valid arg list types:
// /... CREATE {CA/checking/savings/checking-account/savings-account/report}
/////////////////////////////////////////////////////////////////////////////
/// @fn CreateCommand
///
/// @param[in] player is player who ran command
///
/// @param[in] argList is the argument list to be parsed
///
/// @brief Create a bank account or create report on account
/////////////////////////////////////////////////////////////////////////////
public int CreateCommand(ServerPlayerEntity sourcePlayer, List<String> argList) {
System.out.println("Attempting account creation given arg list { " + argList + " }.");
System.out.println("argList size is " + argList.size());
if (argList.size() > 0) {
String action = argList.get(0).toLowerCase();
System.out.println("action word is " + action);
switch (action) {
// Checking & Savings are handled in the same function so we can just "alias" all of these to the same call!
case "ca":
case "checking":
case "checking-account":
case "sa":
case "savings":
case "savings-account":
System.out.println("Creating account. Removing index 0 in argList. New argList is { " + argList + " }");
CreateAccount(sourcePlayer, argList);
break;
case "rep":
case "report":
GenerateAccountReport(sourcePlayer, argList);
break;
default:
// Unrecognized creation type
}
} else {
sourcePlayer.sendMessage(Text.of("Unrecognized create command formed on bank. Please run \"/bank help CREATE\" for more information"));
}
return 0;
}
// Possible code paths: // Possible code paths:
// REQUIRED = {ACCOUNT ID|ALIAS} // REQUIRED = {ACCOUNT ID|ALIAS}
// OPTIONAL = [] // OPTIONAL = []
public int CloseCommand(ServerPlayerEntity sourcePlayer, String account) { public int CloseCommand(ServerPlayerEntity sourcePlayer, List<String> argList) {
// if (argList.size() > 0) { if (argList.size() > 0) {
// String accountToClose = argList.get(0); String accountToClose = argList.get(0);
// /* /*
// * CALL TO BANKMGR TO DO STUFF * CALL TO BANKMGR TO DO STUFF
// */ */
// } else { } else {
// sourcePlayer.sendMessage(Text.of("Unrecognized close command. Please see \"/bank help CLOSE\" for more information.")); sourcePlayer.sendMessage(Text.of("Unrecognized close command. Please see \"/bank help CLOSE\" for more information."));
// } }
return 0; return 0;
} }
// Possible code paths: // Possible code paths:
// required = {account id | alias} // required = {account id | alias}
// optional = [default|secondary|backup] // optional = [default|secondary|backup]
public int SelectDefaultAccount(ServerPlayerEntity sourcePlayer, String account) { public int SelectCommand(ServerPlayerEntity sourcePlayer, List<String> argList) {
BankManager.GetInstance().ChangeDefaultPlayerAccount(sourcePlayer, account); if (argList.size() > 0) {
String requiredArg = argList.get(0);
// If the optional args exist; fetch them
String optionalArg = "";
if (argList.size() == 2) {
optionalArg = argList.get(1);
}
BankManager.GetInstance().ChangeDefaultPlayerAccount(sourcePlayer, requiredArg);
} else {
sourcePlayer.sendMessage(Text.of("Unrecognized select command. Please run /bank help select for more information."));
}
return 0; return 0;
} }
// Possible code paths:
// REQUIRED = {AMOUNT} {ACCOUNT_ID} [optional]
// OPTIONAL = [reason]
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn WireCommand /// @fn WireCommand
/// ///
@ -655,8 +837,22 @@ public class BankCommands {
/// ///
/// @brief Create wire on bank account /// @brief Create wire on bank account
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public int WireCommand(ServerPlayerEntity sourcePlayer, Integer amount, String destAccount, String reason) { public int WireCommand(ServerPlayerEntity sourcePlayer, List<String> argList) {
BankManager.GetInstance().InitiateBankFundsTransfer(sourcePlayer, destAccount, amount, reason); System.out.println("WireCommand called with arg size " + argList.size());
if (argList.size() >= 2) {
Integer amountToWire = ParseToInteger(sourcePlayer, argList.get(0), HELPCMD_WIRE);
String destAccount = argList.get(1);
String optionalReason = "";
if (argList.size() >= 3) {
optionalReason = argList.get(3);
}
System.out.println("optional reason: " + optionalReason);
BankManager.GetInstance().InitiateBankFundsTransfer(sourcePlayer, destAccount, amountToWire);
} else {
sourcePlayer.sendMessage(Text.of("Unrecognized wire command. Please run /bank help wire for more information."));
}
return 0; return 0;
} }
@ -673,10 +869,8 @@ public class BankCommands {
/// @brief Builds a dynamic help list to the player to see all command /// @brief Builds a dynamic help list to the player to see all command
/// options on the server /// options on the server
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public int HelpCommand(ServerPlayerEntity sourcePlayer, String helpCommandList) { public int HelpCommand(ServerPlayerEntity sourcePlayer, List<String> helpCommand) {
System.out.println("Running help command"); System.out.println("Running help command");
List<String> helpCommand = new ArrayList<String>(Arrays.asList(helpCommandList.split(" ")));
if (helpCommand.size() == 0) { if (helpCommand.size() == 0) {
// General help command // General help command
for (Entry<String, String> helpCmd : HELP_COMMANDS.entrySet()) { for (Entry<String, String> helpCmd : HELP_COMMANDS.entrySet()) {
@ -723,14 +917,23 @@ public class BankCommands {
/// ///
/// @brief Creates a bank account /// @brief Creates a bank account
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public int CreateAccount(ServerPlayerEntity player, ACCOUNT_TYPE accountType) { public void CreateAccount(ServerPlayerEntity player, List<String> accountArgs) {
String bank = BankManager.GetInstance().GetPlayerSelectedBank(player.getUuidAsString()); System.out.println("Attempting to create checking account with arg list { " + accountArgs + " }");
System.out.println("Received bank: " + bank); if (accountArgs.size() > 0) {
String accountType = accountArgs.get(0);
String accountAlias = "NO_ALIAS";
if (bank != "") { // Set the optional account alias for ease-of-reference
BankManager.GetInstance().InitiateBankAccountCreation(bank, player, accountType); if (accountArgs.size() >= 2) {
accountAlias = accountArgs.get(1).toLowerCase();
}
System.out.println("ACCOUNT CREATION REQUESTED WITH TYPE " + accountType + " AND ALIAS " + accountAlias);
// FIXME: This is just a patch at the moment to let players make bank accounts in server bank
BankManager.GetInstance().InitiateBankAccountCreation(null, player, accountType);
} else {
player.sendMessage(Text.of("Unrecognized create account command. Please run /bank help create for more information"));
} }
return 0;
} }
// Possible code paths for /bank create report // Possible code paths for /bank create report

View File

@ -8,8 +8,8 @@
package jesse.keeblarcraft.Commands; package jesse.keeblarcraft.Commands;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.ChatStuff.ChatMsg; import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
public class CustomCommandManager { public class CustomCommandManager {
// Intentionally empty constructor since at object definition time it may not be possible to register commands // Intentionally empty constructor since at object definition time it may not be possible to register commands
@ -24,16 +24,14 @@ public class CustomCommandManager {
AttributeCommands attributeCommands = new AttributeCommands(); AttributeCommands attributeCommands = new AttributeCommands();
FactionCommands factionCommands = new FactionCommands(); FactionCommands factionCommands = new FactionCommands();
MiscCommands miscCommands = new MiscCommands(); MiscCommands miscCommands = new MiscCommands();
MailCommands mailCommands = new MailCommands();
// REGISTER COMMANDS BELOW // REGISTER COMMANDS BELOW
Keeblarcraft.LOGGER.info("Registering mod commands"); System.out.println(ChatUtil.ColoredString("REGISTERING CUSTOM COMMAND EXTENSIONS BELOW", CONSOLE_COLOR.BLUE));
shortcuts.RegisterShortcutCommands(); shortcuts.RegisterShortcutCommands();
noteCommands.RegisterNoteCommands(); noteCommands.RegisterNoteCommands();
bankCommands.RegisterCommands(); bankCommands.RegisterCommands();
attributeCommands.RegisterCommands(); attributeCommands.RegisterCommands();
factionCommands.RegisterFactionCommands(); factionCommands.RegisterFactionCommands();
miscCommands.RegisterCommands(); miscCommands.RegisterCommands();
mailCommands.RegisterMailCommands();
} }
} }

View File

@ -2,19 +2,15 @@ package jesse.keeblarcraft.Commands;
import java.util.List; import java.util.List;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import jesse.keeblarcraft.FactionMgr.FactionManager; import jesse.keeblarcraft.FactionMgr.FactionManager;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerCommandFlightCallback;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.command.argument.EntityArgumentType;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
public class FactionCommands { public class FactionCommands {
@ -31,13 +27,6 @@ public class FactionCommands {
var disbandFaction = CommandManager.literal("disband").build(); var disbandFaction = CommandManager.literal("disband").build();
var promote = CommandManager.literal("promote").build(); var promote = CommandManager.literal("promote").build();
var demote = CommandManager.literal("demote").build(); var demote = CommandManager.literal("demote").build();
var kick = CommandManager.literal("kick").build();
var info = CommandManager.literal("info")
.executes(context -> GetFactionInformation(context.getSource().getPlayer()))
.build();
var invite = CommandManager.literal("invite").build();
var fly = CommandManager.literal("fly")
.executes(context -> ForwardFlightCallback(context)).build();
// The below nodes are duplicates but are necessary to make the execute path jump correctly // The below nodes are duplicates but are necessary to make the execute path jump correctly
var createFactionName = CommandManager.argument("faction_name", StringArgumentType.greedyString()) var createFactionName = CommandManager.argument("faction_name", StringArgumentType.greedyString())
@ -56,22 +45,10 @@ public class FactionCommands {
) )
).build(); ).build();
var promoteName = CommandManager.argument("target_name", EntityArgumentType.player())
.executes(context -> PromotePlayerInFaction(context, EntityArgumentType.getPlayer(context, "target_name")))
.build();
var demoteName = CommandManager.argument("target_name", EntityArgumentType.player())
.executes(context -> DemotePlayerInFaction(context, EntityArgumentType.getPlayer(context, "target_name")))
.build();
var kickName = CommandManager.argument("target_name", EntityArgumentType.player())
.executes(context -> KickPlayerFromFaction(context, EntityArgumentType.getPlayer(context, "target_name")))
.build();
var inviteName = CommandManager.argument("target_name", EntityArgumentType.player())
.executes(context -> InvitePlayerToFaction(context, EntityArgumentType.getPlayer(context, "target_name")))
.build();
var leaveFaction = CommandManager.literal("leave").executes(context -> LeaveFaction(context) var leaveFaction = CommandManager.literal("leave").executes(context -> LeaveFaction(context)
).build(); ).build();
var listAll = CommandManager.literal("list") var listAll = CommandManager.literal("list")
.executes(context -> ListAllFactions(context.getSource().getPlayer())).build(); .executes(context -> ListAllFactions(context.getSource().getPlayer())).build();
@ -84,60 +61,10 @@ public class FactionCommands {
factionNode.addChild(createFaction); factionNode.addChild(createFaction);
factionNode.addChild(disbandFaction); factionNode.addChild(disbandFaction);
factionNode.addChild(leaveFaction); factionNode.addChild(leaveFaction);
factionNode.addChild(promote);
factionNode.addChild(demote);
factionNode.addChild(kick);
factionNode.addChild(info);
factionNode.addChild(invite);
factionNode.addChild(fly);
promote.addChild(promoteName);
demote.addChild(demoteName);
kick.addChild(kickName);
invite.addChild(inviteName);
createFaction.addChild(createFactionName); createFaction.addChild(createFactionName);
disbandFaction.addChild(disbandFactionName); disbandFaction.addChild(disbandFactionName);
}); });
// I'll refactor the above one later! LOL
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
var factionNode = CommandManager.literal("faction").build();
var powerNode = CommandManager.literal("power")
.executes(context -> GetFactionPower(context.getSource().getPlayer()))
.build();
var setNode = CommandManager.literal("set").build();
var factionNameNode = CommandManager.argument("faction_name", StringArgumentType.string()).build();
var powerAmountNode = CommandManager.argument("power_amount", IntegerArgumentType.integer())
.executes(context -> SetFactionPower(context.getSource().getPlayer(), StringArgumentType.getString(context, "faction_name"), IntegerArgumentType.getInteger(context, "power_amount")))
.build();
dispatcher.getRoot().addChild(factionNode);
factionNode.addChild(powerNode);
powerNode.addChild(setNode);
setNode.addChild(factionNameNode);
setNode.addChild(powerAmountNode);
});
}
private int ForwardFlightCallback(CommandContext<ServerCommandSource> context) {
if (context.getSource().isExecutedByPlayer()) {
ActionResult result = PlayerCommandFlightCallback.EVENT.invoker().interact(context.getSource().getPlayer(), context.getSource().getWorld());
}
return 0;
}
public int SetFactionPower(ServerPlayerEntity caller, String faction, Integer amount) {
FactionManager.GetInstance().SetFactionPower(caller, faction, amount);
return 0;
}
public int GetFactionPower(ServerPlayerEntity player) {
FactionManager.GetInstance().GetFactionPower(player);
return 0;
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -182,9 +109,10 @@ public class FactionCommands {
return retValue; return retValue;
} }
private int InvitePlayerToFaction(CommandContext<ServerCommandSource> context, ServerPlayerEntity player) { private int AddPlayerToFaction() {
FactionManager.GetInstance().InvitePlayerToFaction(context.getSource().getPlayer(), player.getUuidAsString(), player.getEntityName()); int retValue = -1;
return 0;
return retValue;
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -202,26 +130,22 @@ public class FactionCommands {
return 0; return 0;
} }
private int GetFactionInformation(ServerPlayerEntity player) { private int KickPlayerFromFaction() {
return 0;
}
private int KickPlayerFromFaction(CommandContext<ServerCommandSource> context, ServerPlayerEntity player) {
int retValue = -1; int retValue = -1;
return retValue; return retValue;
} }
private int PromotePlayerInFaction(CommandContext<ServerCommandSource> context, ServerPlayerEntity player) { private int PromotePlayerInFaction() {
ServerPlayerEntity caller = context.getSource().getPlayer(); int retValue = -1;
FactionManager.GetInstance().PromotePlayer(caller, player.getUuidAsString(), player.getEntityName());
return 0; return retValue;
} }
private int DemotePlayerInFaction(CommandContext<ServerCommandSource> context, ServerPlayerEntity player) { private int DemotePlayerInFaction() {
ServerPlayerEntity caller = context.getSource().getPlayer(); int retValue = -1;
FactionManager.GetInstance().DemotePlayer(caller, player.getUuidAsString(), player.getEntityName());
return 0; return retValue;
} }
private int SetPlayerRoleInFaction() { private int SetPlayerRoleInFaction() {

View File

@ -1,61 +0,0 @@
package jesse.keeblarcraft.Commands;
import com.mojang.brigadier.arguments.StringArgumentType;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.network.ServerPlayerEntity;
public class MailCommands {
public void RegisterMailCommands() {
// Mail send <player> msg...
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
var mailRoot = CommandManager.literal("mail").build();
var sendNode = CommandManager.literal("send").build();
var playerName = CommandManager.argument("target_name", StringArgumentType.string()).build();
var message = CommandManager.argument("mail_msg", StringArgumentType.greedyString())
.executes(context -> SendMail(context.getSource().getPlayer(), StringArgumentType.getString(context, "target_name"), StringArgumentType.getString(context, "mail_msg")))
.build();
dispatcher.getRoot().addChild(mailRoot);
mailRoot.addChild(sendNode);
sendNode.addChild(playerName);
playerName.addChild(message);
});
// Mail read
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
var mailRoot = CommandManager.literal("mail").build();
var readNode = CommandManager.literal("read")
.executes(context -> ReadMail(context.getSource().getPlayer()))
.build();
dispatcher.getRoot().addChild(mailRoot);
mailRoot.addChild(readNode);
});
// Mail clear
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
var mailRoot = CommandManager.literal("mail").build();
var clearNode = CommandManager.literal("clear")
.executes(context -> ClearMail(context.getSource().getPlayer()))
.build();
dispatcher.getRoot().addChild(mailRoot);
mailRoot.addChild(clearNode);
});
}
private int SendMail(ServerPlayerEntity source, String targetName, String mail) {
return 0;
}
private int ReadMail(ServerPlayerEntity player) {
return 0;
}
private int ClearMail(ServerPlayerEntity player) {
return 0;
}
}

View File

@ -1,16 +1,35 @@
package jesse.keeblarcraft.Commands; package jesse.keeblarcraft.Commands;
import org.apache.logging.log4j.core.jmx.Server;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import jesse.keeblarcraft.Keeblarcraft;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.ConfigMgr.GeneralConfig; import jesse.keeblarcraft.ConfigMgr.GeneralConfig;
import jesse.keeblarcraft.EventMgr.DimensionLoadingEvent;
import jesse.keeblarcraft.Utils.DirectionalVec; import jesse.keeblarcraft.Utils.DirectionalVec;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; 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.command.CommandManager;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ServerWorld;
import net.minecraft.text.Text; 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.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraft.world.dimension.DimensionType;
public class MiscCommands { public class MiscCommands {
ConfigManager config = new ConfigManager(); ConfigManager config = new ConfigManager();
@ -56,17 +75,6 @@ public class MiscCommands {
dispatcher.getRoot().addChild(warp); dispatcher.getRoot().addChild(warp);
warp.addChild(warpLoc); warp.addChild(warpLoc);
}); });
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
var warp = CommandManager.literal("nick").build();
var warpLoc = CommandManager.argument("CUSTOM_NICKNAME", StringArgumentType.string())
.executes(context -> SetNickname(context.getSource().getPlayer(), StringArgumentType.getString(context, "CUSTOM_NICKNAME"))).build();
dispatcher.getRoot().addChild(warp);
warp.addChild(warpLoc);
});
} }
public int Warp(ServerPlayerEntity player, String location) { public int Warp(ServerPlayerEntity player, String location) {
@ -124,12 +132,6 @@ public class MiscCommands {
return 0; return 0;
} }
public int SetNickname(ServerPlayerEntity player, String name) {
player.setCustomName(Text.of(name));
player.setCustomNameVisible(true);
return 0;
}
public int GetEnderchestOfPlayer(ServerPlayerEntity cmdInitiator, ServerPlayerEntity targetPlayer) { public int GetEnderchestOfPlayer(ServerPlayerEntity cmdInitiator, ServerPlayerEntity targetPlayer) {
// if (cmdInitiator.hasPermissionLevel(4)) { // if (cmdInitiator.hasPermissionLevel(4)) {

View File

@ -6,12 +6,13 @@ import com.mojang.brigadier.context.CommandContext;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.JsonClassObjects.PlayerNote; import jesse.keeblarcraft.JsonClassObjects.PlayerNote;
import jesse.keeblarcraft.ChatStuff.ChatMsg; import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_CREATE_EXCEPTION;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
public class NoteCommands { public class NoteCommands {
/// Class Variables /// Class Variables
@ -20,8 +21,27 @@ public class NoteCommands {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn NoteCommands /// @fn NoteCommands
///
/// @brief This classes non-trivial constructor. Ensures creation
// of notes directory exists before commands can be ran
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public NoteCommands() {} public NoteCommands() {
// Check if directory exists
// if (notesConfig.DoesDirectoryExist(NOTES_GLOBAL_DIRECTORY) == false) {
// // Attempt to create the directory
// try {
// if (notesConfig.CreateDirectory(NOTES_GLOBAL_DIRECTORY) == true) {
// System.out.println(ChatUtil.ColoredString("Created notes directory successfully!", CONSOLE_COLOR.BLUE)); //TODO: Success!
// } 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
// }
// } catch (DIRECTORY_CREATE_EXCEPTION e) {
// System.out.println(ChatUtil.ColoredString("Directory creation failed", CONSOLE_COLOR.RED));
// }
// } else {
// System.out.println(ChatUtil.ColoredString("Notes directory already exists. Skipping creation...", CONSOLE_COLOR.BLUE)); //TODO: Success!
// }
}
//TODO: Rework note commands upon story mode release //TODO: Rework note commands upon story mode release
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -31,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));
// });
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -117,11 +137,11 @@ public class NoteCommands {
// Note mgmt // Note mgmt
PlayerNote note = new PlayerNote(player.getUuidAsString()); PlayerNote note = new PlayerNote(player.getUuidAsString());
note.AddNote(value, 1, 1, 1, 1); note.AddNote(value, 1, 1, 1, 1);
player.sendMessage(Text.of("New note logged to entry! View notes any time with /notegui")); ChatUtil.SendPlayerMsg(player, "New note logged to entry! View notes any time with /notegui");
ret = 0; ret = 0;
} else { } else {
System.out.println("Only a player can execute this command!"); System.out.println(ChatUtil.ColoredString("Only a player can execute this command!", CONSOLE_COLOR.RED));
} }
return ret; return ret;
@ -146,7 +166,7 @@ public class NoteCommands {
ServerPlayerEntity player = context.getSource().getPlayer(); ServerPlayerEntity player = context.getSource().getPlayer();
PlayerNote note = new PlayerNote(player.getUuidAsString()); PlayerNote note = new PlayerNote(player.getUuidAsString());
player.sendMessage(Text.of("Deleted note entry. View notes any time with /notegui")); ChatUtil.SendPlayerMsg(player, "Deleted note entry. View notes any time with /notegui");
ret = 0; ret = 0;
note.DeleteNote(value); note.DeleteNote(value);
@ -186,8 +206,7 @@ public class NoteCommands {
note.ModifyNote(value, newNote, epochTime, storyChapter, storyPart); note.ModifyNote(value, newNote, epochTime, storyChapter, storyPart);
player.sendMessage(Text.of("Modified note entry. View notes any time with /notegui")); ChatUtil.SendPlayerMsg(player, "Modified note entry. View notes any time with /notegui");
ret = 0; ret = 0;
} }
@ -213,7 +232,7 @@ public class NoteCommands {
PlayerNote note = new PlayerNote(player.getUuidAsString()); PlayerNote note = new PlayerNote(player.getUuidAsString());
note.PurgeAllNotes(); note.PurgeAllNotes();
player.sendMessage(Text.of("Purged all notes. View notes any time with /notegui")); ChatUtil.SendPlayerMsg(player, "Purged all notes. View notes any time with /notegui");
ret = 0; ret = 0;
} else { } else {
@ -240,10 +259,11 @@ public class NoteCommands {
ServerPlayerEntity player = context.getSource().getPlayer(); ServerPlayerEntity player = context.getSource().getPlayer();
PlayerNote notes = new PlayerNote(player.getUuidAsString()); PlayerNote notes = new PlayerNote(player.getUuidAsString());
ChatUtil.SendPlayerMsg(player, "Listing all notes...");
for (int i = 0; i <= notes.GetNotebookSize(); i++) { for (int i = 0; i <= notes.GetNotebookSize(); i++) {
String individualNote = notes.GetNoteString(i); String individualNote = notes.GetNoteString(i);
if (individualNote != "") { if (individualNote != "") {
player.sendMessage(Text.of("Note " + i + ": " + individualNote)); ChatUtil.SendPlayerMsg(player, "Note " + i + ": " + individualNote);
} }
} }

View File

@ -1,18 +0,0 @@
package jesse.keeblarcraft.Commands;
import com.mojang.brigadier.arguments.StringArgumentType;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.server.command.CommandManager;
public class ShopCommands {
public void RegisterShopCommands() {
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
var shopCmd = CommandManager.literal("shop").build();
var shopCreate = CommandManager.literal("create").build();
dispatcher.getRoot().addChild(shopCmd);
});
}
}

View File

@ -13,10 +13,9 @@ package jesse.keeblarcraft.Commands;
import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.Utils.PlayerChecks; import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.minecraft.command.argument.EntityArgumentType;
import net.minecraft.entity.player.PlayerAbilities; import net.minecraft.entity.player.PlayerAbilities;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
@ -25,6 +24,8 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class ShortcutCommands { public class ShortcutCommands {
float DEFAULT_FLIGHT_SPEED = 0.05f; // Minecraft operates on a 0.0 -> 1.0 scale; with each .01 making a difference in speed. 0.05 is creative flight speed
float SPEED_SCALAR = 20.0f; // For clamping speed down to half of its max output (So 0.5 will be max speed on a system that goes up in 0.05'ths) float SPEED_SCALAR = 20.0f; // For clamping speed down to half of its max output (So 0.5 will be max speed on a system that goes up in 0.05'ths)
public void RegisterShortcutCommands() public void RegisterShortcutCommands()
@ -38,31 +39,31 @@ public class ShortcutCommands {
// Fly command // Fly command
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
var flightNode = CommandManager.literal("fly").executes(context -> FlightSpeedShortcut(null, context)).build(); dispatcher.register(CommandManager.literal("fly")
.executes(context -> { FlightShortcut(context);
var flightSpeed = CommandManager.argument("value", IntegerArgumentType.integer()) return 0;
.executes(context -> FlightSpeedShortcut(IntegerArgumentType.getInteger(context, "value"), context)).build(); }));
dispatcher.getRoot().addChild(flightNode);
flightNode.addChild(flightSpeed);
}); });
// Fly command with speed
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
var healNode = CommandManager.literal("heal").executes(context -> HealShortcut(context, null)).build(); dispatcher.register(CommandManager.literal("fly")
var targetPlayer = CommandManager.argument("targetPlayer", EntityArgumentType.player()) .then(CommandManager.argument("value", IntegerArgumentType.integer())
.executes(context -> HealShortcut(context, EntityArgumentType.getPlayer(context, "targetPlayer"))).build(); .executes(context -> FlightSpeedShortcut(IntegerArgumentType.getInteger(context, "value"), context))));
dispatcher.getRoot().addChild(healNode);
healNode.addChild(targetPlayer);
}); });
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { ///TODO: Read TODO on function
var feedNode = CommandManager.literal("feed").executes(context -> FeedShortcut(context, null)).build(); // CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
var targetPlayer = CommandManager.argument("targetPlayer", EntityArgumentType.player()) // dispatcher.register(CommandManager.literal("walk")
.executes(context -> FeedShortcut(context, EntityArgumentType.getPlayer(context, "targetPlayer"))).build(); // .then(CommandManager.argument("value", IntegerArgumentType.integer())
// .executes(context -> WalkSpeedShortcut(IntegerArgumentType.getInteger(context, "value"), context))));
// });
dispatcher.getRoot().addChild(feedNode); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
feedNode.addChild(targetPlayer); dispatcher.register(CommandManager.literal("heal")
.executes(context -> { HealShortcut(context);
return 0;
}));
}); });
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
@ -110,79 +111,118 @@ public class ShortcutCommands {
retValue = -1; retValue = -1;
break; break;
} }
} }
else { else {
player.sendMessage(Text.literal("\033[31m You do not have permissions to run this command! \033[0m")); player.sendMessage(Text.literal("\033[31m You do not have permissions to run this command! \033[0m"));
} }
} }
else { else {
Keeblarcraft.LOGGER.info("This command cannot be executed by a non-player entity!"); System.out.println(ChatUtil.ColoredString("This command cannot be executed by a non-player entity!", CONSOLE_COLOR.RED));
} }
return retValue; return retValue;
} }
private int FlightSpeedShortcut(Integer value, CommandContext<ServerCommandSource> context) { private int FlightShortcut(CommandContext<ServerCommandSource> context) {
if (PlayerChecks.HasPermission(context)) { int retValue = -1;
if (context.getSource().isExecutedByPlayer()) {
ServerPlayerEntity player = context.getSource().getPlayer(); ServerPlayerEntity player = context.getSource().getPlayer();
PlayerAbilities abilities = player.getAbilities();
// Disable flight if (player.hasPermissionLevel(4)) {
if (abilities.flying && value == null) { PlayerAbilities abilities = player.getAbilities();
abilities.flying = false; abilities.flying = !abilities.flying; // Toggle flying
abilities.allowFlying = false; abilities.setFlySpeed(DEFAULT_FLIGHT_SPEED); // It seems flight speed is on a 0-1 scale
abilities.setFlySpeed(0);
player.sendMessage(Text.of("Disabled flight"));
player.sendAbilitiesUpdate(); player.sendAbilitiesUpdate();
} else if (!abilities.flying && value == null) { ChatUtil.SendPlayerMsg(player, "You can now fly! Flight speed is " + abilities.getFlySpeed());
value = 1; } else {
player.sendMessage(Text.literal("You do not have permission for this command"));
}
} }
// Enable flight return retValue;
if (value != null && value >= 1 && value <= 10) { }
private int FlightSpeedShortcut(int value, CommandContext<ServerCommandSource> context) {
int retValue = -1;
if (context.getSource().isExecutedByPlayer()) {
ServerPlayerEntity player = context.getSource().getPlayer();
if (player.hasPermissionLevel(4)) {
PlayerAbilities abilities = player.getAbilities();
if (value >= 1 && value <= 10) {
abilities.allowFlying = true; abilities.allowFlying = true;
abilities.setFlySpeed((float) (value / SPEED_SCALAR)); // Dividing by 20f yields max clamp value of 0.5 since MC does 0.0-> 1.0 flight. 0.1 flight is too fast! abilities.setFlySpeed((float) (value / SPEED_SCALAR)); // Dividing by 20f yields max clamp value of 0.5 since MC does 0.0-> 1.0 flight. 0.1 flight is too fast!
player.sendAbilitiesUpdate(); player.sendAbilitiesUpdate();
player.sendMessage(Text.of("Flight speed set to " + value)); ChatUtil.SendPlayerMsg(player, "Flight speed set to " + (value));
} else if (value != null) { } else {
player.sendMessage(Text.literal("Only values from 1-10 are accepted")); player.sendMessage(Text.literal("Only values from 1-10 are accepted"));
} }
}
return 0;
}
private int FeedShortcut(CommandContext<ServerCommandSource> context, ServerPlayerEntity target) {
if (PlayerChecks.HasPermission(context)) {
// if target is null, feed ourselves
if (target == null) {
ServerPlayerEntity player = context.getSource().getPlayer();
player.getHungerManager().setExhaustion(0.0f);
player.getHungerManager().setFoodLevel(20); // 20 is hardcoded inside class
player.getHungerManager().setSaturationLevel(10.0f); // 5 is set in constructor, but let's try 10!
player.sendMessage(Text.of("You were just super fed!"));
} else { } else {
target.getHungerManager().setExhaustion(0.0f); player.sendMessage(Text.literal("You do not have permission for this command"));
target.getHungerManager().setFoodLevel(20); // 20 is hardcoded inside class
target.getHungerManager().setSaturationLevel(10.0f); // 5 is set in constructor, but let's try 10!
target.sendMessage(Text.of("You were just super fed!"));
} }
} }
return 0;
}
private int HealShortcut(CommandContext<ServerCommandSource> context, ServerPlayerEntity target) { return retValue;
}
///TODO: There is a bug with walk speed that causes the players speed to behave weirdly despite the value. It's either a crawl or mach 10
///TODO: It's possible that the player may need to die first to reset speed; and reloading in the debugger does not count as resetting values. This
///TODO: code may actually work; but I just did not die first in between testing speed changes.
// private int WalkSpeedShortcut(int value, CommandContext<ServerCommandSource> context) {
// int retValue = -1;
// if (context.getSource().isExecutedByPlayer()) {
// ServerPlayerEntity player = context.getSource().getPlayer();
// if (player.hasPermissionLevel(4)) {
// PlayerAbilities abilities = player.getAbilities();
// if (value >= 1 && value <= 10) {
// abilities.setWalkSpeed((float) 1.0f);
// player.sendAbilitiesUpdate();
// ChatUtil.SendPlayerMsg(player, "Set walk speed to " + (value));
// } else {
// player.sendMessage(Text.literal("Only values from 1-10 are accepted"));
// }
// } else {
// player.sendMessage(Text.literal("You do not have permission for this command"));
// }
// }
// return retValue;
// }
// TODO: Add when we can find where in the API to fill players hunger level
// private int FeedShortcut(CommandContext<ServerCommandSource> context) {
// int retValue = -1;
// if (context.getSource().isExecutedByPlayer()) {
// ServerPlayerEntity player = context.getSource().getPlayer();
// if (player.hasPermissionLevel(4)) {
// } else {
// player.sendMessage(Text.literal("You do not have permission for this command"));
// }
// }
// return retValue;
// }
private int HealShortcut(CommandContext<ServerCommandSource> context) {
int retValue = -1; int retValue = -1;
if (PlayerChecks.HasPermission(context)) { if (context.getSource().isExecutedByPlayer()) {
// If no player specified; then heal ourself full HP ServerPlayerEntity player = context.getSource().getPlayer();
if (target == null) {
context.getSource().getPlayer().setHealth(context.getSource().getPlayer().getMaxHealth()); if (player.hasPermissionLevel(4)) {
context.getSource().getPlayer().sendMessage(Text.of("Healed!")); player.setHealth(player.getMaxHealth());
ChatUtil.SendPlayerMsg(player, "Healed!");
} else { } else {
target.setHealth(target.getMaxHealth()); player.sendMessage(Text.literal("You do not have permission for this command"));
target.sendMessage(Text.of("You were just healed!"));
context.getSource().getPlayer().sendMessage(Text.of("You healed " + target.getEntityName()));
} }
} }
return retValue; return retValue;
} }

View File

@ -15,7 +15,6 @@ import java.io.FileWriter;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Paths;
import com.google.common.base.Charsets; import com.google.common.base.Charsets;
import com.google.common.io.Files; import com.google.common.io.Files;
@ -31,110 +30,65 @@ import org.apache.commons.io.FileUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.Utils.CustomExceptions.*;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtIo;
import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtList;
public class ConfigManager { public class ConfigManager {
// Pedantic empty constructor
private static final String GLOBAL_CONFIG = "config/keeblarcraft/";
// Pedantic empty constructor
public ConfigManager() {} public ConfigManager() {}
// Get a File reference to a file that is created on disk // CreateFile
private File GetFile(String confFile) { //
File file = null; // Returns true if file is created, will return false if file cannot be created (returns true if already exists)
System.out.println("Get file called for " + GLOBAL_CONFIG + confFile); public Boolean CreateFile(String fileName) throws FILE_CREATE_EXCEPTION {
Boolean ret = false;
File file = new File(fileName);
// Check 1: Does the file already exist?
ret = file.exists();
System.out.println(ChatUtil.ColoredString("Does file exist? ", CONSOLE_COLOR.BLUE) + (ret ? ChatUtil.ColoredString("YES", CONSOLE_COLOR.YELLOW) : ChatUtil.ColoredString("NO", CONSOLE_COLOR.YELLOW)));
// Check 2: If the file does not exist, attempt to create it
if (ret == false) {
try { try {
System.out.println("GetFile Cur Dir: " + Paths.get("").toAbsolutePath().toString()); ret = file.createNewFile();
file = new File(GLOBAL_CONFIG + confFile); } catch (IOException e) {
} catch (Exception e) {} // The file could not be created
return file; throw new FILE_CREATE_EXCEPTION();
}
// Returns the parent path to a given input.
// Ex: /home/Downloads/file.txt will return /home/Downloads/
// Ex: /home/Downloads will return /home/
// Ex: / will return /
private String GetPathOfFile(String file) {
String pathToFile = "";
if (file != null) {
for (int i = file.length() - 1; i >= 0; i--) {
if (file.charAt(i) != File.separatorChar) {
continue;
}
else {
// Trim and break
pathToFile = file.substring(0, i);
break;
}
}
}
System.out.println("PathOfFile: " + pathToFile);
return pathToFile;
}
// Creates a directory and all necessary parent directories listed in dirname (under global config area)
public Boolean CreateDirectory(String dirName) {
Boolean success = false;
File directory = GetFile(dirName);
try {
if (directory != null) {
if (!directory.exists())
{
success = directory.mkdirs();
} else if (directory.isDirectory()) {
success = true;
} else {
System.out.println("Directory " + dirName + " is an already existing file!");
}
}
} catch (Exception e) {
System.out.println("Failed to create directory with name " + dirName);
e.printStackTrace();
}
return success;
}
// Create a file on the disk
public Boolean CreateFile(String fileName) {
Boolean success = false;
File file = GetFile(fileName);
String parentDir = GetPathOfFile(fileName);
// CreateDirectory will verify that the parent directories exist & at least the parent directory is in fact a directory
if (file != null && !file.exists() && CreateDirectory(parentDir)) {
try {
success = file.createNewFile();
} catch (Exception e) {
System.out.println("Failed to create file " + fileName);
e.printStackTrace();
} }
} else { } else {
System.out.println("CreateFile failed to finish. File may have been null (empty string input, unlikely), or parent directories could not be created/have overlapped name"); ret = true; // This might be a hot fix, but technically the file already exists so would this be true or false? --?this statement is wild?
success = false; System.out.println(ChatUtil.ColoredString("File (name: ", CONSOLE_COLOR.BLUE) + ChatUtil.ColoredString(fileName, CONSOLE_COLOR.YELLOW) + ChatUtil.ColoredString(" was determined to already exist. Exiting out", CONSOLE_COLOR.BLUE));
} }
return success; return ret;
} }
public Boolean DeleteFile(String fileName) { // DeleteFile
Boolean success = false; //
File file = GetFile(fileName); // Returns true if file is deleted, false if could not be deleted or does not exist
public Boolean DeleteFile(String fileName) throws FILE_DELETE_EXCEPTION {
Boolean ret = false;
File file = new File(fileName);
success = !file.exists(); // Step 1: Does file exist?
ret = file.exists();
if (!success) { // Step 2: If file exists, attempt to delete
if (ret == true) {
try { try {
success = file.delete(); ret = file.delete();
} catch (Exception e) { } catch (SecurityException e) {
System.out.println("Failed to delete file " + fileName); throw new FILE_DELETE_EXCEPTION();
e.printStackTrace();
} }
} else {
System.out.println(ChatUtil.ColoredString("cannot delete file ", CONSOLE_COLOR.RED) + ChatUtil.ColoredString(fileName, CONSOLE_COLOR.YELLOW) + ChatUtil.ColoredString(" because file does not exist", CONSOLE_COLOR.BLUE));
} }
return success; return ret;
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -149,9 +103,9 @@ public class ConfigManager {
/// @brief Writes NbtList data to disk /// @brief Writes NbtList data to disk
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public void WriteNbtListToFile(String fileName, String key, NbtList data) { public void WriteNbtListToFile(String fileName, String key, NbtList data) {
// fileName = "config/keeblarcraft/" + fileName; fileName = "config/keeblarcraft/" + fileName;
File file = GetFile(fileName); File file = new File(fileName);
if (!file.exists()) { if (!file.exists()) {
file.getParentFile().mkdirs(); file.getParentFile().mkdirs();
} }
@ -180,9 +134,9 @@ public class ConfigManager {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public HashMap<String, NbtList> ReadAllNbtListFromDirectory(String dir, int listType) { public HashMap<String, NbtList> ReadAllNbtListFromDirectory(String dir, int listType) {
HashMap<String, NbtList> list = new HashMap<String, NbtList>(); HashMap<String, NbtList> list = new HashMap<String, NbtList>();
// dir = "config/keeblarcraft/" + dir; dir = "config/keeblarcraft/" + dir;
File directory = GetFile(dir); File directory = new File(dir);
File[] files = directory.listFiles(); File[] files = directory.listFiles();
@ -236,7 +190,7 @@ public class ConfigManager {
FileWriter file; FileWriter file;
try { try {
file = new FileWriter(GetFile(fileName)); file = new FileWriter(fileName);
switch(mode) { switch(mode) {
case "w": case "w":
file.write(data); file.write(data);
@ -247,14 +201,13 @@ public class ConfigManager {
ret = true; ret = true;
break; break;
default: default:
Keeblarcraft.LOGGER.debug("Invalid mode to WriteToFile!!"); System.out.println(ChatUtil.ColoredString("Invalid mode to WriteToFile!", CONSOLE_COLOR.RED));
break; break;
} }
file.close(); file.close();
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); System.out.println(ChatUtil.ColoredString("Could not open file ", CONSOLE_COLOR.RED) + ChatUtil.ColoredString(fileName, CONSOLE_COLOR.YELLOW) + ChatUtil.ColoredString(" to write to it! Possibly permission issue?", CONSOLE_COLOR.RED));
Keeblarcraft.LOGGER.error("Could not open file " + fileName + " to write to it! Possible permissions issue??");
} }
return ret; return ret;
@ -270,16 +223,17 @@ public class ConfigManager {
// top-level key. // top-level key.
// //
// 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) { 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(GetFile(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) {
Keeblarcraft.LOGGER.error("Could not successfully write to json file ["+fileName+"]"); System.out.println(ChatUtil.ColoredString("Could not successfully write to json file [" + fileName + "]", CONSOLE_COLOR.RED));
e.printStackTrace(); throw new FILE_WRITE_EXCEPTION();
} }
} }
@ -289,32 +243,80 @@ 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
try { try {
File file = GetFile(fileName); File file = new File(fileName);
ret = FileUtils.readFileToString(file, "UTF-8"); ret = FileUtils.readFileToString(file, "UTF-8");
} catch (Exception e) { } catch (NullPointerException e) {
e.printStackTrace(); System.out.println(ChatUtil.ColoredString("nullptr exception", CONSOLE_COLOR.RED));
System.out.println("Caught an exception in retrieving JSON Object from file " + fileName); throw new JsonSyntaxException("");
// throw new JsonSyntaxException(""); } catch (FileNotFoundException e) {
System.out.println(ChatUtil.ColoredString("file not found", CONSOLE_COLOR.RED));
throw new JsonSyntaxException("");
} catch (java.nio.charset.UnsupportedCharsetException e) {
System.out.println(ChatUtil.ColoredString("charset issue", CONSOLE_COLOR.RED));
throw new JsonSyntaxException("");
} catch (IOException e) {
System.out.println(ChatUtil.ColoredString("io exception", CONSOLE_COLOR.RED));
throw new JsonSyntaxException("");
} }
return gson.fromJson(ret, classToConvertTo); return gson.fromJson(ret, classToConvertTo);
} }
public Boolean DoesFileExist(String fileName) { public Boolean DoesFileExist(String fileName) {
return GetFile(fileName) != null; return new File(fileName).exists(); // untested
} }
public Boolean DoesDirectoryExist(String dirName) { public Boolean DoesDirectoryExist(String dirName) {
File file = GetFile(dirName); return new File(dirName).isDirectory(); // untested
return file != null && file.isDirectory();
} }
public Boolean DeleteDirectory(String dirName) { public Boolean CreateDirectory(String dirName) throws DIRECTORY_CREATE_EXCEPTION {
return DeleteFile(dirName); Boolean ret = false;
File dir = new File(dirName);
System.out.println("Attempting to create dir with name " + dirName);
try {
if ( ! dir.exists()) {
ret = dir.mkdirs();
}
} catch (Exception e) {
System.out.println(ChatUtil.ColoredString("Failed to make directory with name: ", CONSOLE_COLOR.RED) + ChatUtil.ColoredString(dirName, CONSOLE_COLOR.YELLOW));
ret = true; /// TODO: Hack to make Setup fn be fine with prev-created files! Make Setup more robust!
throw new DIRECTORY_CREATE_EXCEPTION();
}
return ret;
}
public Boolean DeleteDirectory(String dirName) throws DIRECTORY_DELETE_EXCEPTION {
Boolean ret = false;
File dir = new File(dirName);
try {
ret = dir.delete();
System.out.println(ChatUtil.ColoredString("Deleted directory ", CONSOLE_COLOR.GREEN) + ChatUtil.ColoredString(dirName, CONSOLE_COLOR.YELLOW));
} catch (Exception e) {
System.out.println(ChatUtil.ColoredString("Failed to delete directory: ", CONSOLE_COLOR.RED) + ChatUtil.ColoredString(dirName, CONSOLE_COLOR.YELLOW));
throw new DIRECTORY_DELETE_EXCEPTION();
}
return ret;
}
// AddToKey
//
// Adds new text to a key if found inside the config
public String AddToKey(String key, String newInfo) {
String ret = "";
return ret;
} }
// GetFile // GetFile
@ -322,11 +324,11 @@ public class ConfigManager {
// Returns a file as an arraylist of all the lines in the file. Generally only used for testing // Returns a file as an arraylist of all the lines in the file. Generally only used for testing
// //
// NOTE: Returns UTF-8 Encoding of file // NOTE: Returns UTF-8 Encoding of file
public List<String> GetFileLines(String fileName) { public List<String> GetFile(String fileName) {
List<String> ret = new ArrayList<String>(); List<String> ret = new ArrayList<String>();
try { try {
return Files.readLines(GetFile(fileName), Charsets.UTF_8); return Files.readLines(new File(fileName), Charsets.UTF_8);
} catch (IOException e) { } catch (IOException e) {
ret.clear(); ret.clear();
} }

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import jesse.keeblarcraft.Utils.DirectionalVec; import jesse.keeblarcraft.Utils.DirectionalVec;
import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION;
public class GeneralConfig { public class GeneralConfig {
private static GeneralConfig static_inst; private static GeneralConfig static_inst;
@ -44,6 +45,7 @@ public class GeneralConfig {
try { try {
config = cfgMgr.GetJsonObjectFromFile("general.json", ImplementedConfig.class); config = cfgMgr.GetJsonObjectFromFile("general.json", ImplementedConfig.class);
System.out.println("Read in config. Random value: " + config.global_spawn.x);
existingFile = true; existingFile = true;
} catch(Exception e) { } catch(Exception e) {
System.out.println("FAILED TO READ IN GENERALCONFIG"); System.out.println("FAILED TO READ IN GENERALCONFIG");
@ -85,27 +87,6 @@ public class GeneralConfig {
FlashConfig(); FlashConfig();
} }
/////////////////////////////////////////////////////////////////////////////
/// @fn GetSQLPassword
///
/// @brief Returns the SQL password set in the text config
/////////////////////////////////////////////////////////////////////////////
public String GetSQLPassword() {
return config.sqlPassword;
}
public String GetSQLUsername() {
return config.sqlUsername;
}
public String GetSQLAddress() {
return config.sqlAddress;
}
public String GetSQLDatabase() {
return config.sqlDatabaseName;
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn IsNewPlayer /// @fn IsNewPlayer
/// ///
@ -117,7 +98,6 @@ public class GeneralConfig {
/// @return True if player is new, false if not /// @return True if player is new, false if not
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public Boolean IsNewPlayer(String uuid) { public Boolean IsNewPlayer(String uuid) {
System.out.println("Is config null? " + (config == null ? "YES" : "NO"));
System.out.println("IsNewPlayer called. List has: " + config.playerList); System.out.println("IsNewPlayer called. List has: " + config.playerList);
Boolean isNew = !config.playerList.contains(uuid); Boolean isNew = !config.playerList.contains(uuid);
@ -145,10 +125,6 @@ public class GeneralConfig {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
private class ImplementedConfig { private class ImplementedConfig {
public String MOTD = "Welcome to the server! Have fun!"; public String MOTD = "Welcome to the server! Have fun!";
public String sqlAddress = "localhost";
public String sqlDatabaseName = "keeblarcraft";
public String sqlUsername = "SQL_USERNAME";
public String sqlPassword = "SQL_PASSWORD";
// This is lazy, but this will fill with every unique UUID that has joined the server. This is how I am checking // 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 // to see if a player has just joined the server for a first time or not
@ -163,6 +139,10 @@ public class GeneralConfig {
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
private void FlashConfig() { private void FlashConfig() {
System.out.println("Attempting to write generalconfig to file. Is null? " + (config == null ? "YES" : "NO")); System.out.println("Attempting to write generalconfig to file. Is null? " + (config == null ? "YES" : "NO"));
try {
cfgMgr.WriteToJsonFile("general.json", config); cfgMgr.WriteToJsonFile("general.json", config);
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println("Caught FileWriteException from general config writing. uh oh!");
}
} }
} }

View File

@ -1,184 +0,0 @@
package jesse.keeblarcraft.ConfigMgr;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import jesse.keeblarcraft.ConfigMgr.SQLTypeSupport.VALID_SQL_TYPE;
import jesse.keeblarcraft.Utils.CommonStructures.Pair;
public class SQLConfig {
private static SQLConfig static_inst;
private String dbName;
private String dbUser;
private String dbPass;
private String dbAddr;
private Boolean connected = false;
private Connection conn = null; // Actual connection object
private enum SQL_RUN_TYPE {
GENERAL,
QUERY,
UPDATE
}
// Direct return object in relation to the SQL_RUN_TYPE of the SQL command that was used. Only one will
// be filled out properly for what you run - the other values will be null and not cleared!
private class SQLRunReturn {
Boolean generalRet;
ResultSet queryReturn;
Integer updateReturn;
}
public static SQLConfig GetInstance() {
if (static_inst == null) {
static_inst = new SQLConfig();
}
return static_inst;
}
public SQLConfig() {
connected = false;
try {
// According to some random online tutorial; this loads the driver!
Class.forName("com.mysql.cj.jdbc.Driver");
connected = true;
} catch (Exception e) {
System.out.println("Could not find the proper SQL JDBC Drivers. Cannot connect to SQL Config");
e.printStackTrace();
}
if (connected) {
try {
dbName = GeneralConfig.GetInstance().GetSQLDatabase();
dbUser = GeneralConfig.GetInstance().GetSQLUsername();
dbPass = GeneralConfig.GetInstance().GetSQLPassword();
dbAddr = "jdbc:mysql://" + GeneralConfig.GetInstance().GetSQLAddress() + "/" + dbName;
conn = DriverManager.getConnection(dbAddr, dbUser, dbPass);
} catch (SQLException e) {}
}
}
private SQLRunReturn RunCommand(String sqlCommand, SQL_RUN_TYPE type) {
SQLRunReturn sqlData = new SQLRunReturn();
// If conn is null; we may need to reconnect before running the command
if (conn == null) {
Connect();
}
if (conn != null) {
try {
Statement statement = conn.createStatement();
switch(type) {
case GENERAL:
sqlData.generalRet = statement.execute(sqlCommand);
break;
case QUERY:
sqlData.queryReturn = statement.executeQuery(sqlCommand);
break;
case UPDATE:
sqlData.updateReturn = statement.executeUpdate(sqlCommand);
break;
}
} catch (SQLException e) {
System.out.println(e.getSQLState());
}
}
return sqlData;
}
// Re-attempt the connection
public Boolean Connect() {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {}
}
Boolean success = false;
try {
conn = DriverManager.getConnection(dbAddr, dbUser, dbPass);
success = true;
} catch (Exception e) {}
return success;
}
public Boolean IsConnected() {
return conn != null && this.connected;
}
// The case is converted to upper case automatically to be case insensitive
public Boolean DoesTableExist(String name) {
boolean tableExists = false;
if (conn != null) {
try (ResultSet rs = conn.getMetaData().getTables(null, null, name, null)) {
while (rs.next()) {
String tName = rs.getString("TABLE_NAME");
if (tName != null && tName.equals(name)) {
tableExists = true;
break;
}
}
} catch (SQLException e) {}
}
return tableExists;
}
public Boolean MakeNonNullable(String table, String columnName) {
return false;
}
public Integer AddPrimaryKey(String tableName, String primaryKeyColumn) {
SQLRunReturn success = new SQLRunReturn();
if (DoesTableExist(tableName)) {
String sqlCmd = "ALTER TABLE " + tableName + " ADD PRIMARY KEY (" + primaryKeyColumn + ");";
success = RunCommand(sqlCmd, SQL_RUN_TYPE.UPDATE);
}
return success.updateReturn;
}
public Integer AddForeignKey(String primaryTableName, String primaryColumnName, String foreignTableName, String foreignKeyColumn) {
SQLRunReturn success = new SQLRunReturn();
Boolean primaryTableExists = DoesTableExist(primaryTableName);
Boolean foreignTableExists = DoesTableExist(foreignTableName);
if (primaryTableExists && foreignTableExists) {
String sqlCmd = "ALTER TABLE " + primaryTableName + " ADD FOREIGN KEY (" + primaryColumnName + ") REFERENCES " + foreignTableName + " (" + foreignKeyColumn + ")";
success = RunCommand(sqlCmd, SQL_RUN_TYPE.UPDATE);
}
return success.updateReturn;
}
// Might fix heap pollution decay in future with enum types or something. For now we assume the user isn't horrifically stupid and will give a SQL-able type
public Boolean CreateTable(String tableName, Pair<String, VALID_SQL_TYPE>... columnPairs) {
Boolean success = false;
if (conn != null && !DoesTableExist(tableName.toUpperCase())) {
String sqlCommand = "CREATE TABLE " + tableName.toUpperCase() + "(";
for (Pair<String, VALID_SQL_TYPE> colPair : columnPairs) {
sqlCommand = sqlCommand + " " + colPair.GetKey() + " " + SQLTypeSupport.GetSqlStrForType(colPair.GetValue()) + ",";
}
// Strip the leading comma and append the ending ');' on the SQL statement
sqlCommand = sqlCommand.substring(0, sqlCommand.length() - 1) + ");";
SQLRunReturn rs = RunCommand(sqlCommand, SQL_RUN_TYPE.GENERAL);
try {
while (rs.queryReturn.next()) {
}
} catch (Exception e) {}
}
return success;
}
}

View File

@ -1,51 +0,0 @@
package jesse.keeblarcraft.ConfigMgr;
import jesse.keeblarcraft.ConfigMgr.SQLTypeSupport.VALID_SQL_TYPE;
import jesse.keeblarcraft.Utils.CommonStructures.Pair;
public class SQLInitServer {
// Initial run-time checks to make sure tables are all setup in advanced
public void Initialize() {
SetupTables();
}
@SuppressWarnings("unchecked")
private void SetupTables() {
// TABLE NAMES
String accountsTable = "ACCOUNTS";
String banksTable = "BANKS";
String customerTable = "CUSTOMER";
String transactionTable = "TRANSACTION";
// Create the ACCOUNTS table
Pair<String, VALID_SQL_TYPE> accountsGlobalId = new Pair<>("global_account_id", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> userUuid = new Pair<>("address", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> accountType = new Pair<>("account_type", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> balance = new Pair<>("balance", VALID_SQL_TYPE.BIGINT);
Pair<String, VALID_SQL_TYPE> openDate = new Pair<>("open_date", VALID_SQL_TYPE.VARCHAR);
SQLConfig.GetInstance().CreateTable(accountsTable, accountsGlobalId, userUuid, accountType, balance, openDate);
// Create the CUSTOMER table
Pair<String, VALID_SQL_TYPE> playerUuid = new Pair<>("player_uuid", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> playerName = new Pair<>("player_entity_name", VALID_SQL_TYPE.VARCHAR);
SQLConfig.GetInstance().CreateTable(customerTable, playerUuid, playerName);
// Create the BANKS table
Pair<String, VALID_SQL_TYPE> bankRouting = new Pair<>("routing", VALID_SQL_TYPE.BIGINT);
Pair<String, VALID_SQL_TYPE> bankName = new Pair<>("bank_name", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> bankSymbol = new Pair<>("bank_symbol", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> bankDateOpened = new Pair<>("date_opened", VALID_SQL_TYPE.VARCHAR);
SQLConfig.GetInstance().CreateTable(banksTable, bankRouting, bankName, bankSymbol, bankDateOpened);
// Create the TRANSACTION table
Pair<String, VALID_SQL_TYPE> transactionId = new Pair<>("transaction_id", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> transactionDate = new Pair<>("transaction_date", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> transactionType = new Pair<>("transaction_type", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> transactionAmount = new Pair<>("amount", VALID_SQL_TYPE.BIGINT);
Pair<String, VALID_SQL_TYPE> transactionFromAccount = new Pair<>("account_id", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> transactionDescription = new Pair<>("description", VALID_SQL_TYPE.TEXT);
Pair<String, VALID_SQL_TYPE> transactionDestination = new Pair<>("destination", VALID_SQL_TYPE.VARCHAR);
SQLConfig.GetInstance().CreateTable(transactionTable, transactionId, transactionDate, transactionType, transactionAmount,
transactionFromAccount, transactionDescription, transactionDestination);
}
}

View File

@ -1,27 +0,0 @@
package jesse.keeblarcraft.ConfigMgr;
public class SQLTypeSupport {
public enum VALID_SQL_TYPE {
VARCHAR,
BIGINT,
INT,
TEXT
}
// Produces the word that SQL would expect for the given datatype. In general it's usually just the word itself but in cases
// like 'varchar' you usually specify a size too. For now it defaults 255 but this can be expanded in the future
public static String GetSqlStrForType(VALID_SQL_TYPE type) {
switch(type) {
case VARCHAR:
return "VARCHAR(255)";
case BIGINT:
return "BIGINT";
case INT:
return "INT";
case TEXT:
return "TEXT";
}
return null; // This should never get hit
}
}

View File

@ -1,38 +0,0 @@
package jesse.keeblarcraft.ConfigMgr;
import jesse.keeblarcraft.ConfigMgr.SQLTypeSupport.VALID_SQL_TYPE;
import jesse.keeblarcraft.Utils.CommonStructures.Pair;
// Random commands to run to test the SQL class
public class SQLUnitTest {
public void RunTests() {
CreateTableTest();
ForeignKeyTest();
}
public void CreateTableTest() {
String tableName = "test_table";
Pair<String, VALID_SQL_TYPE> pairOne = new Pair<>("name", VALID_SQL_TYPE.VARCHAR);
Pair<String, VALID_SQL_TYPE> pairTwo = new Pair<>("address", VALID_SQL_TYPE.BIGINT);
Pair<String, VALID_SQL_TYPE> pairThree = new Pair<>("email", VALID_SQL_TYPE.TEXT);
SQLConfig.GetInstance().CreateTable(tableName, pairOne, pairTwo, pairThree);
}
public void DoesTableExistTest() {
String tableName = "test_table";
Boolean temp = SQLConfig.GetInstance().DoesTableExist(tableName.toUpperCase());
System.out.println("[SQL-UnitTest]: Does the table " + tableName + " exist? " + (temp ? "YES":"NO"));
}
public void ForeignKeyTest() {
String primTableName = "test_table";
String primColName = "name";
String foreTableName = "accounts";
String foreColName = "global_account_id";
Integer ret = SQLConfig.GetInstance().AddForeignKey(primTableName, primColName, foreTableName, foreColName);
System.out.println("[SQL-UnitTest]: Update foreign key test. Got return result number: " + ret);
}
}

View File

@ -1,27 +0,0 @@
package jesse.keeblarcraft.CustomBlocks.BlockEntities;
import jesse.keeblarcraft.Keeblarcraft;
import jesse.keeblarcraft.CustomBlocks.BlockManager;
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
// EVENTUALLY THIS CLASS WILL GET COLLAPSED UNDER @ref BlockManager.java
// However; I don't have the time to figure out how to do this dynamically this second (I'm lazy and doing this
// all in one sitting)
public class BlockEntityRegistration {
// PLEASE STICK A COMMENT ABOVE EACH REGISTRATION FOR LATER REFERENCE
// FactionBlockEntity
public static final BlockEntityType<FactionBlockEntity> FACTION_BLOCK_ENTITY =
Registry.register(Registries.BLOCK_ENTITY_TYPE, new Identifier(Keeblarcraft.MOD_ID, "faction_block_entity"),
FabricBlockEntityTypeBuilder.create(FactionBlockEntity::new, BlockManager.GetBlock("faction_base_block")).build());
public static void RegisterBlockEntities() {
Keeblarcraft.LOGGER.info("Registering block entities for " + Keeblarcraft.MOD_ID);
}
}

View File

@ -1,177 +0,0 @@
package jesse.keeblarcraft.CustomBlocks.BlockEntities;
import java.util.ArrayList;
import jesse.keeblarcraft.AttributeMgr.AttributeMgr;
import jesse.keeblarcraft.AttributeMgr.AttributeTree;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerEnteredBaseCallback;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerExitedBaseCallback;
import jesse.keeblarcraft.FactionMgr.Callbacks.PlayerInBaseCallback;
import jesse.keeblarcraft.GuiMgr.FactionBlockScreenHandler;
import jesse.keeblarcraft.world.ImplementedInventory;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
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.network.PacketByteBuf;
import net.minecraft.screen.PropertyDelegate;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.collection.DefaultedList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class FactionBlockEntity extends BlockEntity implements ExtendedScreenHandlerFactory, ImplementedInventory {
private final DefaultedList<ItemStack> inventory = DefaultedList.ofSize(7, ItemStack.EMPTY);
private static final int DEFENSE_SLOT_ONE = 0;
private static final int DEFENSE_SLOT_TWO = 1;
private static final int OFFENSE_SLOT_ONE = 2;
private static final int OFFENSE_SLOT_TWO = 3;
private static int factionPower = 0;
Boolean stopMobSpawn = true;
Boolean hasBuildFlight = true;
Boolean hasSuperBeacon = true;
private ArrayList<String> playersInRadius = new ArrayList<>();
protected final PropertyDelegate propertyDelegate;
public FactionBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntityRegistration.FACTION_BLOCK_ENTITY, pos, state);
this.propertyDelegate = new PropertyDelegate() {
@Override
public int get(int index) {
// The only value we need to get/delegate is faction power
return switch(index) {
default -> factionPower;
};
}
@Override
public void set(int index, int value) {
switch(index) {
default -> factionPower = value;
};
}
@Override
public int size() {
// We are only sync'ing 1 integer - faction power
return 1;
}
};
}
@Override
public Text getDisplayName() {
return Text.literal("Faction Home Base Station"); // Replace with proper en_us format later
}
@Override
public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) {
return new FactionBlockScreenHandler(syncId, playerInventory, this, this.propertyDelegate);
}
@Override
public void readNbt(NbtCompound nbt) {
super.readNbt(nbt);
Inventories.readNbt(nbt, inventory);
factionPower = nbt.getInt("faction_block_entity.power");
}
@Override
public void writeNbt(NbtCompound nbt) {
super.writeNbt(nbt);
// Write the inventory of the block
Inventories.writeNbt(nbt, inventory);
nbt.putInt("faction_block_entity.power", factionPower);
}
@Override
public DefaultedList<ItemStack> getItems() {
return inventory;
}
@Override
public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) {
// Send position of this block entity from server->client->server etc
buf.writeBlockPos(this.pos);
}
private Boolean IsPlayerInBounds(PlayerEntity player, BlockPos pos) {
Boolean isNearBlock = false;
// Will check in range - assumes same world! 50 is a temporary value at the moment
Boolean xBounds = player.getX() <= pos.getX() + 50 && player.getX() >= pos.getX() - 50;
Boolean yBounds = player.getY() <= pos.getY() + 50 && player.getY() >= pos.getY() - 50;
Boolean zBounds = player.getZ() <= pos.getZ() + 50 && player.getZ() >= pos.getZ() - 50;
if (xBounds && yBounds && zBounds) {
isNearBlock = true;
}
return isNearBlock;
}
// Tick method is called 20 times a second
public void tick(World world, BlockPos pos, BlockState state) {
// For reasons unknown to me and only to Kaupenjoe (youtube video) - we never want to call this on a client.
if (world.isClient()) {
return;
}
// TODO: Optimize this block so that when it is placed the placers UUID is related to a faction and only pull from a list of those players not the entire server
for (PlayerEntity player : world.getPlayers()) {
Boolean isPlayerInFactionRadius = IsPlayerInBounds(player, pos);
if (isPlayerInFactionRadius) {
// Run individual faction modules for players here
// First time entry callback check
if (!playersInRadius.contains(player.getUuidAsString())) {
playersInRadius.add(player.getUuidAsString());
ActionResult result = PlayerEnteredBaseCallback.EVENT.invoker().interact(player, world);
}
// Invoke the flight attribute on this player
if (hasBuildFlight) {
AttributeMgr.ApplyAttribute(player.getUuidAsString(), "faction_flight");
ActionResult result = PlayerInBaseCallback.EVENT.invoker().interact(player, world);
}
if (hasSuperBeacon) {
AttributeMgr.ApplyAttribute(player.getUuidAsString(), "faction_beacon");
// ActionResult result = PlayerInBaseCallback.EVENT.invoker().interact(player, world);
}
} else if (!isPlayerInFactionRadius && playersInRadius.contains(player.getUuidAsString())) {
playersInRadius.remove(player.getUuidAsString());
ActionResult result = PlayerExitedBaseCallback.EVENT.invoker().interact(player, world);
}
}
// if (stopMobSpawn) {
// // Temporary for now
// // Sphere center point is going to be X,Y,Z
// Integer X = pos.getX();
// Integer y = pos.getY();
// Integer z = pos.getZ();
// Integer radius = 10;
// }
// if (hasBuildFlight) {
// for (PlayerEntity player : world.getPlayers()) {
// if (IsPlayerInBounds(player, pos)) {
// // Notify the attribute tree to enable this attribute!
// }
// }
// world.getBlockEntity(pos.east());
// }
}
}

View File

@ -1,7 +1,7 @@
package jesse.keeblarcraft.CustomBlocks; package jesse.keeblarcraft.CustomBlocks;
import jesse.keeblarcraft.CustomBlocks.Blocks.FactionBaseBlock;
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings; import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.ExperienceDroppingBlock; import net.minecraft.block.ExperienceDroppingBlock;
@ -20,6 +20,5 @@ public class BlockList {
BlockManager.RegisterBlock("example_block_ore", new Block(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).sounds(BlockSoundGroup.AMETHYST_BLOCK).requiresTool().breakInstantly())); BlockManager.RegisterBlock("example_block_ore", new Block(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).sounds(BlockSoundGroup.AMETHYST_BLOCK).requiresTool().breakInstantly()));
BlockManager.RegisterBlock("example_block", new ExperienceDroppingBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).sounds(BlockSoundGroup.ANCIENT_DEBRIS).requiresTool(), UniformIntProvider.create(4, 20))); BlockManager.RegisterBlock("example_block", new ExperienceDroppingBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).sounds(BlockSoundGroup.ANCIENT_DEBRIS).requiresTool(), UniformIntProvider.create(4, 20)));
BlockManager.RegisterBlock("example_statue", new Block(FabricBlockSettings.copyOf(Blocks.BELL))); BlockManager.RegisterBlock("example_statue", new Block(FabricBlockSettings.copyOf(Blocks.BELL)));
BlockManager.RegisterBlock("faction_base_block", new FactionBaseBlock(FabricBlockSettings.copyOf(Blocks.IRON_BLOCK).nonOpaque()));
} }
} }

View File

@ -1,76 +0,0 @@
package jesse.keeblarcraft.CustomBlocks.Blocks;
import jesse.keeblarcraft.CustomBlocks.BlockEntities.BlockEntityRegistration;
import jesse.keeblarcraft.CustomBlocks.BlockEntities.FactionBlockEntity;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.BlockEntityTicker;
import net.minecraft.block.entity.BlockEntityType;
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.ItemScatterer;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.World;
public class FactionBaseBlock extends BlockWithEntity implements BlockEntityProvider {
// public static final VoxelShape SHAPE = Block.createCuboidShape(0, 0, 0, 16, 12, 16);
public FactionBaseBlock(Settings settings) {
super(settings);
}
// @Override
// protected VoxelShape getOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context) {
// return SHAPE;
// }
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}
@Override
public BlockEntity createBlockEntity(BlockPos pos, BlockState state) {
return new FactionBlockEntity(pos, state);
}
// If block is destroyed; drop inventory
@Override
public void onStateReplaced(BlockState state, World world, BlockPos pos, BlockState newState, boolean moved) {
if (state.getBlock() != newState.getBlock()) {
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity != null && blockEntity instanceof FactionBlockEntity) {
ItemScatterer.spawn(world, pos, (FactionBlockEntity) blockEntity);
world.updateComparators(pos, this);
}
super.onStateReplaced(state, world, pos, newState, moved);
}
}
// Open the inventory
// Calls ScreenHandler inside createMenu of entity class
@Override
public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) {
// Server side handling is different than that of client side handling; we MUST check if we are on a server first because then we must
// request information about this block entity from the server
System.out.println("onUse of faction base block called");
if (!world.isClient()) {
NamedScreenHandlerFactory screenHandlerFactory = (FactionBlockEntity) world.getBlockEntity(pos);
if (screenHandlerFactory != null) {
player.openHandledScreen(screenHandlerFactory);
}
}
return ActionResult.SUCCESS;
}
@Override
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
return validateTicker(type, BlockEntityRegistration.FACTION_BLOCK_ENTITY,
(world1, pos, state1, blockEntity) -> blockEntity.tick(world1, pos, state1));
}
}

View File

@ -65,4 +65,5 @@ public class ItemManager {
// Item exampleItem = new Item(new FabricItemSettings()); // Item exampleItem = new Item(new FabricItemSettings());
// RegisterItem("metaljacket_helmet", exampleItem); // RegisterItem("metaljacket_helmet", exampleItem);
} }
} }

View File

@ -4,7 +4,8 @@ import java.util.HashMap;
import java.util.Map.Entry; import java.util.Map.Entry;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.ChatStuff.ChatMsg; import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.world.dimension.ModDimensions; import jesse.keeblarcraft.world.dimension.ModDimensions;
import net.minecraft.nbt.NbtElement; import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtList;
@ -120,7 +121,7 @@ public class DimensionLoadingEvent {
} }
} }
} catch (Exception e) { } catch (Exception e) {
System.out.println("Could not flash dimension loading configuration file"); System.out.println(ChatUtil.ColoredString("Could not flash dimension loading configuration file", CONSOLE_COLOR.RED));
} }
} }
} }

View File

@ -1,10 +1,7 @@
package jesse.keeblarcraft.EventMgr; package jesse.keeblarcraft.EventMgr;
import java.util.HashMap;
import jesse.keeblarcraft.AttributeMgr.AttributeMgr; import jesse.keeblarcraft.AttributeMgr.AttributeMgr;
import jesse.keeblarcraft.AttributeMgr.AttributeTree; import jesse.keeblarcraft.AttributeMgr.AttributeTree;
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.ConfigMgr.GeneralConfig; import jesse.keeblarcraft.ConfigMgr.GeneralConfig;
import jesse.keeblarcraft.Utils.DirectionalVec; import jesse.keeblarcraft.Utils.DirectionalVec;
import net.fabricmc.fabric.api.networking.v1.PacketSender; import net.fabricmc.fabric.api.networking.v1.PacketSender;
@ -16,13 +13,6 @@ import net.minecraft.text.Text;
public class PlayerJoinListener { public class PlayerJoinListener {
private static PlayerJoinListener static_inst; private static PlayerJoinListener static_inst;
ConfigManager config = new ConfigManager();
String CACHED_PLAYER_LOGIN_CONFIG = "misc/cached_uuids.json";
private class CachedUUIDConfig {
HashMap<String, String> cached_uuids = new HashMap<String, String>();
}
CachedUUIDConfig cachedPlayerConfig;
// Get the static instance for this class // Get the static instance for this class
public static PlayerJoinListener GetInstance() { public static PlayerJoinListener GetInstance() {
@ -32,28 +22,6 @@ public class PlayerJoinListener {
return static_inst; return static_inst;
} }
public PlayerJoinListener() {
Boolean existingFile = false;
cachedPlayerConfig = new CachedUUIDConfig();
try {
cachedPlayerConfig = config.GetJsonObjectFromFile(CACHED_PLAYER_LOGIN_CONFIG, CachedUUIDConfig.class);
existingFile = cachedPlayerConfig != null;
} catch (Exception e) {
// intentionally empty
}
if (!existingFile) {
try {
cachedPlayerConfig = new CachedUUIDConfig();
config.CreateFile(CACHED_PLAYER_LOGIN_CONFIG);
FlashCachedConfig();
} catch (Exception e) {
System.out.println("Failed to parse or create cached uuid file");
}
}
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn HandleServerJoinEvent /// @fn HandleServerJoinEvent
/// ///
@ -70,13 +38,12 @@ public class PlayerJoinListener {
// Handle skill tree map instance // Handle skill tree map instance
if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == false) { if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == false) {
AttributeMgr.activeTrees.put(player.getUuidAsString(), new AttributeTree(player)); AttributeMgr.activeTrees.put(player.getUuidAsString(), new AttributeTree(player.getUuidAsString()));
} }
// Handle first time joining events (world spawn teleport, MOTD, etc) // Handle first time joining events (world spawn teleport, MOTD, etc)
System.out.println("Running first time login stuff"); System.out.println("Running first time login stuff");
IsFirstTimeLogin(player, server); IsFirstTimeLogin(player, server);
CachePlayersUuid(player.getUuidAsString(), player.getEntityName());
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -107,29 +74,4 @@ public class PlayerJoinListener {
} }
} }
} }
public String TryGetPlayerUuidByName(String name) {
String uuid = "";
if (cachedPlayerConfig != null && cachedPlayerConfig.cached_uuids.containsKey(name)) {
uuid = cachedPlayerConfig.cached_uuids.get(name);
}
return uuid;
}
private void CachePlayersUuid(String uuid, String entityName) {
if (cachedPlayerConfig.cached_uuids.containsKey(entityName)) {
return;
} else {
cachedPlayerConfig.cached_uuids.put(entityName, uuid);
FlashCachedConfig();
}
}
private void FlashCachedConfig() {
try {
config.WriteToJsonFile(CACHED_PLAYER_LOGIN_CONFIG, cachedPlayerConfig);
} catch (Exception e) {
System.out.println("Encountered exception in writing cached uuid file!");
}
}
} }

View File

@ -1,24 +0,0 @@
package jesse.keeblarcraft.FactionMgr.Callbacks;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.world.World;
public interface PlayerCommandFlightCallback {
Event<PlayerCommandFlightCallback> EVENT = EventFactory.createArrayBacked(PlayerCommandFlightCallback.class,
(listeners) -> (player, world) -> {
for (PlayerCommandFlightCallback listener : listeners) {
ActionResult result = listener.interact(player, world);
if (result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult interact(PlayerEntity player, World world);
}

View File

@ -1,24 +0,0 @@
package jesse.keeblarcraft.FactionMgr.Callbacks;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.world.World;
public interface PlayerEnteredBaseCallback {
Event<PlayerEnteredBaseCallback> EVENT = EventFactory.createArrayBacked(PlayerEnteredBaseCallback.class,
(listeners) -> (player, world) -> {
for (PlayerEnteredBaseCallback listener : listeners) {
ActionResult result = listener.interact(player, world);
if (result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult interact(PlayerEntity player, World world);
}

View File

@ -1,24 +0,0 @@
package jesse.keeblarcraft.FactionMgr.Callbacks;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.world.World;
public interface PlayerExitedBaseCallback {
Event<PlayerExitedBaseCallback> EVENT = EventFactory.createArrayBacked(PlayerExitedBaseCallback.class,
(listeners) -> (player, world) -> {
for (PlayerExitedBaseCallback listener : listeners) {
ActionResult result = listener.interact(player, world);
if (result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult interact(PlayerEntity player, World world);
}

View File

@ -1,24 +0,0 @@
package jesse.keeblarcraft.FactionMgr.Callbacks;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.ActionResult;
import net.minecraft.world.World;
public interface PlayerInBaseCallback {
Event<PlayerInBaseCallback> EVENT = EventFactory.createArrayBacked(PlayerInBaseCallback.class,
(listeners) -> (player, world) -> {
for (PlayerInBaseCallback listener : listeners) {
ActionResult result = listener.interact(player, world);
if (result != ActionResult.PASS) {
return result;
}
}
return ActionResult.PASS;
});
ActionResult interact(PlayerEntity player, World world);
}

View File

@ -91,26 +91,6 @@ public class FactionConfig {
return success; return success;
} }
// It is assumed that the person calling this function has verified that the person
// can in fact set faction power. This is generally just an admin command
public Boolean SetPower(String factionName, Integer amount) {
Boolean success = false;
if (IsValid(factionName)) {
allFactions.get(factionName).factionPower = amount;
success = true;
}
return success;
}
// The user should verify the faction exists prior to calling this. 0 is default
// return if faction does not exist (or the faction actually has a balance of 0)
public Integer GetPower(String factionName) {
Integer amount = 0;
if (IsValid(factionName)) {
amount = allFactions.get(factionName).factionPower;
}
return amount;
}
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// @fn DeleteFaction /// @fn DeleteFaction
@ -522,6 +502,7 @@ public class FactionConfig {
System.out.println("ListOfFactions - map size: " + allFactions.size()); System.out.println("ListOfFactions - map size: " + allFactions.size());
for (Entry<String, WriteableFaction> entry : allFactions.entrySet()) { for (Entry<String, WriteableFaction> entry : allFactions.entrySet()) {
System.out.println("Adding fac " + entry.getKey() + " to fac");
facs.add(entry.getKey()); facs.add(entry.getKey());
} }

View File

@ -12,15 +12,14 @@ package jesse.keeblarcraft.FactionMgr;
import java.util.List; import java.util.List;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.MailSystem.MailMgr; import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.ChatStuff.ChatMsg;
import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION; import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class FactionManager { public class FactionManager {
private static String FACTION_CFG_FILE = "factions/factions.json"; private static String FACTION_CFG_FILE = "config/keeblarcraft/factions/factions.json";
ConfigManager config = new ConfigManager(); ConfigManager config = new ConfigManager();
private static FactionManager static_inst; private static FactionManager static_inst;
@ -63,7 +62,7 @@ public class FactionManager {
config.CreateDirectory(FACTION_CFG_FILE); config.CreateDirectory(FACTION_CFG_FILE);
FlashConfig(); FlashConfig();
} catch (Exception e) { } catch (Exception e) {
Keeblarcraft.LOGGER.error("Could not write to file"); System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED));
} }
} }
@ -92,9 +91,8 @@ public class FactionManager {
String playerFac = factionConfig.factions.FindFactionOfPlayer(player.getUuidAsString()); String playerFac = factionConfig.factions.FindFactionOfPlayer(player.getUuidAsString());
if (playerFac != "") { if (playerFac != "") {
success = factionConfig.factions.LeaveFaction(playerFac, player.getUuidAsString(), player.getEntityName()); success = factionConfig.factions.LeaveFaction(playerFac, player.getUuidAsString(), player.getDisplayName().toString());
player.sendMessage(Text.of("[Factions]: You left your faction!")); player.sendMessage(Text.of("[Factions]: You left your faction!"));
FlashConfig();
} else { } else {
player.sendMessage(Text.of("[Factions]: You are not in a faction!")); player.sendMessage(Text.of("[Factions]: You are not in a faction!"));
} }
@ -118,11 +116,7 @@ public class FactionManager {
String facOfPlayer = factionConfig.factions.FindFactionOfPlayer(creator.getUuidAsString()); String facOfPlayer = factionConfig.factions.FindFactionOfPlayer(creator.getUuidAsString());
if (facOfPlayer == "") { if (facOfPlayer == "") {
creator.sendMessage(Text.of("Your display name: " + creator.getDisplayName().toString())); success = factionConfig.factions.CreateFaction(factionName, creator.getUuidAsString(), creator.getDisplayName().toString());
creator.sendMessage(Text.of("Your name: " + creator.getName()));
creator.sendMessage(Text.of("Your custom name: " + creator.getCustomName()));
creator.sendMessage(Text.of("Your entity name: " + creator.getEntityName()));
success = factionConfig.factions.CreateFaction(factionName, creator.getUuidAsString(), creator.getEntityName());
if (!success) { if (!success) {
creator.sendMessage(Text.of("[Factions]: Could not create faction - faction already exists.")); creator.sendMessage(Text.of("[Factions]: Could not create faction - faction already exists."));
@ -186,45 +180,6 @@ public class FactionManager {
return factionConfig.factions.FindFactionOfPlayer(playerUuid); return factionConfig.factions.FindFactionOfPlayer(playerUuid);
} }
public Boolean InvitePlayerToFaction(ServerPlayerEntity caller, String inviteeUuid, String inviteeDisplayName) {
String playerFaction = factionConfig.factions.FindFactionOfPlayer(caller.getUuidAsString());
Boolean success = false;
if (!playerFaction.equals("")) {
success = factionConfig.factions.InvitePlayerToFaction(playerFaction, caller.getUuidAsString(), inviteeUuid);
} else {
caller.sendMessage(Text.of("You aren't in a faction!"));
}
if (success) {
String mailMsg = "You receive a faction invite from " + caller.getEntityName() + "! You can join with /faction join " + playerFaction;
MailMgr.GetInstance().SendMail(inviteeUuid, mailMsg);
}
return success;
}
public Boolean SetFactionPower(ServerPlayerEntity caller, String factionName, Integer amount) {
Boolean success = false;
if (caller.hasPermissionLevel(4)) {
factionConfig.factions.SetPower(factionName, amount);
} else {
caller.sendMessage(Text.of("You do not have permission to use this command"));
}
return success;
}
public Integer GetFactionPower(ServerPlayerEntity caller) {
Integer amount = 0;
String playerFaction = factionConfig.factions.FindFactionOfPlayer(caller.getUuidAsString());
if (!playerFaction.equals("")) {
amount = factionConfig.factions.GetPower(playerFaction);
caller.sendMessage(Text.of("[" + playerFaction + " - POWER]: " + Integer.toString(amount)));
}
return amount;
}
public Boolean PromotePlayer(ServerPlayerEntity caller, String promoteeUuid, String promoteeDisplayName) { public Boolean PromotePlayer(ServerPlayerEntity caller, String promoteeUuid, String promoteeDisplayName) {
Boolean success = factionConfig.factions.PromotePlayer(GetFactionOfPlayer(caller.getUuidAsString()), caller.getUuidAsString(), promoteeUuid, promoteeDisplayName); Boolean success = factionConfig.factions.PromotePlayer(GetFactionOfPlayer(caller.getUuidAsString()), caller.getUuidAsString(), promoteeUuid, promoteeDisplayName);
@ -268,6 +223,10 @@ public class FactionManager {
/// @brief Update the faction configuration file on disk /// @brief Update the faction configuration file on disk
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public void FlashConfig() { public void FlashConfig() {
try {
config.WriteToJsonFile(FACTION_CFG_FILE, factionConfig); config.WriteToJsonFile(FACTION_CFG_FILE, factionConfig);
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println("config writing of faction file failed. oh well!");
}
} }
} }

View File

@ -1,110 +0,0 @@
package jesse.keeblarcraft.GuiMgr;
import jesse.keeblarcraft.CustomBlocks.BlockEntities.FactionBlockEntity;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.screen.ArrayPropertyDelegate;
import net.minecraft.screen.PropertyDelegate;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.screen.slot.Slot;
public class FactionBlockScreenHandler extends ScreenHandler {
private final Inventory inventory;
private final PropertyDelegate propertyDelegate;
public final FactionBlockEntity blockEntity;
public int factionPower = 0;
public FactionBlockScreenHandler(int syncId, PlayerInventory inventory, PacketByteBuf buf) {
this(syncId, inventory, inventory.player.getWorld().getBlockEntity(buf.readBlockPos()), new ArrayPropertyDelegate(7));
}
public FactionBlockScreenHandler(int syncId, PlayerInventory playerInventory, BlockEntity blockEntity, PropertyDelegate arrayPropertyDelegate) {
super(ScreenHandlerRegistration.FACTION_BLOCK_SCREEN_HANDLER, syncId);
checkSize((Inventory) blockEntity, 7);
this.inventory = (Inventory) blockEntity;
inventory.onOpen(playerInventory.player);
this.propertyDelegate = arrayPropertyDelegate;
this.blockEntity = (FactionBlockEntity) blockEntity;
// Need a better way of storing these coordinates...
this.addSlot(new Slot(inventory, 0, 20, 11)); // top row
this.addSlot(new Slot(inventory, 1, 20, 39));
this.addSlot(new Slot(inventory, 2, 49, 11));
this.addSlot(new Slot(inventory, 3, 49, 39));
this.addSlot(new Slot(inventory, 4, 78, 11));
this.addSlot(new Slot(inventory, 5, 78, 39));
this.addSlot(new Slot(inventory, 6, 128, 26));
addPlayerInventory(playerInventory);
addPlayerHotbar(playerInventory);
// Need to reference Kaupendim tutorial again; but we could theoretically just add the player inventory
// right here so that they can drag items in and whatnot (I assume). I am unsure if I am taking that
// direction with this block RIGHT NOW - so for now I am NOT doing that
// Remainder stuff
addProperties(arrayPropertyDelegate);
}
public Integer GetFactionPower() {
factionPower = this.propertyDelegate.get(0);
return factionPower;
}
// This is just for SHIFT+CLICK moving
@Override
public ItemStack quickMove(PlayerEntity player, int invSlot) {
ItemStack newStack = ItemStack.EMPTY;
Slot slot = this.slots.get(invSlot);
if (slot != null && slot.hasStack()) {
ItemStack originalStack = slot.getStack();
newStack = originalStack.copy();
// TODO: This is from the YT video and it looks atrocious. Refactor this later
if ( (invSlot < this.inventory.size() && !this.insertItem(originalStack, this.inventory.size(), this.slots.size(), true) ) ||
(!this.insertItem(originalStack, 0, this.inventory.size(), false))) {
return ItemStack.EMPTY;
}
if (originalStack.isEmpty()) {
slot.setStack(ItemStack.EMPTY);
} else {
slot.markDirty();;
}
}
return newStack;
}
// From Kaupenjoe video
private void addPlayerInventory(PlayerInventory playerInventory) {
for (int i = 0; i < 3; ++i) { // Rows
for (int l = 0; l < 9; ++l) { // Columns
// The fancy math (expanded from kaupen video for clarity for me for later) seems to just specify a few things
int index = l + i * 9 + 9; // l = col, i*9 = the row to be on (scaling by 9 bc slots are 1-(9*3) in amount), +9 = where on that row to be!
int x = 8 + l * 18; // Texture draw position on image
int y = 84 + i * 18; // Texture draw position on image
this.addSlot(new Slot(playerInventory, index, x, y));
}
}
}
// From Kaupenjoe video
private void addPlayerHotbar(PlayerInventory playerInventory) {
for (int i = 0; i < 9; ++i) {
int index = i; // Index of hotbar (only 9 slots long in vanilla)
int x = 8 + i * 18; // Texture draw position
int y = 142; // Texture draw position
this.addSlot(new Slot(playerInventory, index, x, y));
}
}
@Override
public boolean canUse(PlayerEntity player) {
return this.inventory.canPlayerUse(player);
}
}

View File

@ -1,18 +0,0 @@
package jesse.keeblarcraft.GuiMgr;
import jesse.keeblarcraft.Keeblarcraft;
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.screen.ScreenHandlerType;
import net.minecraft.util.Identifier;
public class ScreenHandlerRegistration {
public static final ScreenHandlerType<FactionBlockScreenHandler> FACTION_BLOCK_SCREEN_HANDLER =
Registry.register(Registries.SCREEN_HANDLER, new Identifier(Keeblarcraft.MOD_ID, "faction_block"),
new ExtendedScreenHandlerType<>(FactionBlockScreenHandler::new));
public static void registerScreenHandlers() {
Keeblarcraft.LOGGER.info("Registering screen handlers for " + Keeblarcraft.MOD_ID);
}
}

View File

@ -11,8 +11,9 @@ import java.util.HashMap;
import java.util.Map.Entry; import java.util.Map.Entry;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.ChatStuff.ChatMsg; import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION;
public class PlayerNote { public class PlayerNote {
/// Class variables /// Class variables
@ -85,18 +86,21 @@ public class PlayerNote {
// In the event the above code failed out, this means a new file has to be created for the player's uuid // In the event the above code failed out, this means a new file has to be created for the player's uuid
if (!existingFile) if (!existingFile)
{ {
System.out.println(ChatUtil.ColoredString("Trying to create new file", CONSOLE_COLOR.BLUE));
try { try {
thisNote.uuid = uuid; thisNote.uuid = uuid;
FlashConfig(); FlashConfig();
} catch (Exception e) { } catch (Exception e) {
Keeblarcraft.LOGGER.warn("Could not write to the player notes file"); System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED));
} }
} else {
System.out.println(ChatUtil.ColoredString("Moving on", CONSOLE_COLOR.BLUE));
} }
// It's possible the above code will return a blank class if a file doesn't exist. This will make // It's possible the above code will return a blank class if a file doesn't exist. This will make
// a new file with this players uuid // a new file with this players uuid
if ("".equals(thisNote.uuid)) { if ("".equals(thisNote.uuid)) {
System.out.println("Assigning new config file for this uuid. No previous existing"); System.out.println(ChatUtil.ColoredString("Assigning new config file for this uuid. No previous existing", CONSOLE_COLOR.BLUE));
thisNote.uuid = uuid; thisNote.uuid = uuid;
} }
} }
@ -226,6 +230,10 @@ public class PlayerNote {
/// @brief Writes to the configuration file /// @brief Writes to the configuration file
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public void FlashConfig() { public void FlashConfig() {
try {
config.WriteToJsonFile("notes/" + thisNote.uuid + ".json", thisNote); config.WriteToJsonFile("notes/" + thisNote.uuid + ".json", thisNote);
} catch (FILE_WRITE_EXCEPTION e) {
System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED));
}
} }
} }

View File

@ -13,36 +13,45 @@ 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.entity.event.v1.ServerEntityWorldChangeEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerEntityEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; 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.kyrptonaught.customportalapi.api.CustomPortalBuilder;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.entity.mob.HostileEntity; 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.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;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jesse.keeblarcraft.AttributeMgr.AttributeMgr; import jesse.keeblarcraft.AttributeMgr.AttributeMgr;
import jesse.keeblarcraft.AttributeMgr.AttributeTree;
import jesse.keeblarcraft.BankMgr.BankManager; import jesse.keeblarcraft.BankMgr.BankManager;
import jesse.keeblarcraft.Commands.CustomCommandManager; import jesse.keeblarcraft.Commands.CustomCommandManager;
import jesse.keeblarcraft.ConfigMgr.SQLUnitTest;
import jesse.keeblarcraft.CustomBlocks.BlockList; import jesse.keeblarcraft.CustomBlocks.BlockList;
import jesse.keeblarcraft.CustomBlocks.BlockEntities.BlockEntityRegistration; // 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.EventMgr.DimensionLoadingEvent; import jesse.keeblarcraft.EventMgr.DimensionLoadingEvent;
import jesse.keeblarcraft.EventMgr.PlayerJoinListener; import jesse.keeblarcraft.EventMgr.PlayerJoinListener;
import jesse.keeblarcraft.EventMgr.ServerTickListener; import jesse.keeblarcraft.EventMgr.ServerTickListener;
import jesse.keeblarcraft.GuiMgr.ScreenHandlerRegistration;
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;
import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.Utils.Setup; import jesse.keeblarcraft.Utils.Setup;
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
public class Keeblarcraft implements ModInitializer { public class Keeblarcraft implements ModInitializer {
public static String MOD_ID = "keeblarcraft"; public static String MOD_ID = "keeblarcraft";
@ -65,14 +74,28 @@ public class Keeblarcraft implements ModInitializer {
@Override @Override
public void onInitialize() { public void onInitialize() {
// This code runs as soon as Minecraft is in a mod-load-ready state.
// However, some things (like resources) may still be uninitialized.
// Proceed with mild caution.
ChatUtil.LoggerColored("Hello Fabric world!", CONSOLE_COLOR.CYAN, LOGGER);
if (setup != null) { if (setup != null) {
try { try {
// Run setup. If setup fails; it throws SETUP_FAILED_EXCEPTION // Run setup. If setup fails; it throws SETUP_FAILED_EXCEPTION
LOGGER.info("Running setup"); LOGGER.info("\033[34m Running setup stage \033[0m");
setup.RunSetup(); setup.RunSetup();
/// TODO: Move callbacks somewhere else // This is a very special case where this must be in this classes' initializer
// method
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
// var player = handler.player;
// 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) {
// AttributeMgr.activeTrees.put(player.getUuidAsString(), new AttributeTree(player.getUuidAsString()));
// }
System.out.println("ServerPlayConnectionEvents.JOIN called"); System.out.println("ServerPlayConnectionEvents.JOIN called");
PlayerJoinListener.GetInstance().HandleServerJoinEvent(handler, sender, server); PlayerJoinListener.GetInstance().HandleServerJoinEvent(handler, sender, server);
}); });
@ -97,16 +120,6 @@ public class Keeblarcraft implements ModInitializer {
DimensionLoadingEvent.GetInstance().SaveInventories(); DimensionLoadingEvent.GetInstance().SaveInventories();
}); });
ServerEntityEvents.ENTITY_LOAD.register((entity, world) -> {
// System.out.println("ENTITY LOAD EVENT INFORMATION");
// System.out.println("Name: " + entity.getEntityName());
// System.out.println("World: " + world.asString());
// System.out.println("COORDS: " + entity.getX() + " " + entity.getY() + " " + entity.getZ());
// System.out.println("TYPE: " + entity.getType());
// System.out.println("SPAWN GROUP: " + entity.getType().getSpawnGroup().asString());
// System.out.println("Is hostile? " + (entity instanceof HostileEntity ? "YES":"NO"));
});
// Initialize our ticks!! // Initialize our ticks!!
ServerTickListener.InitializeServerTicks(); ServerTickListener.InitializeServerTicks();
@ -120,10 +133,6 @@ public class Keeblarcraft implements ModInitializer {
// Register the banking system // Register the banking system
BankManager.GetInstance().InitializeBanks(); BankManager.GetInstance().InitializeBanks();
System.out.println("Attempting SQL Registration call");
SQLUnitTest sqlTests = new SQLUnitTest();
sqlTests.RunTests();
/// THE BELOW ITEMS MUST BE DONE LAST IN THE STEPS /// THE BELOW ITEMS MUST BE DONE LAST IN THE STEPS
// Register items // Register items
@ -131,7 +140,6 @@ public class Keeblarcraft implements ModInitializer {
// Register blocks // Register blocks
BlockList.RegisterBlocks(); BlockList.RegisterBlocks();
BlockEntityRegistration.RegisterBlockEntities();
// World generation // World generation
@ -144,17 +152,14 @@ public class Keeblarcraft implements ModInitializer {
.tintColor(234, 183, 8) .tintColor(234, 183, 8)
.registerPortal(); .registerPortal();
// Screen handlers
ScreenHandlerRegistration.registerScreenHandlers();
} catch (SETUP_FAILED_EXCEPTION e) { } catch (SETUP_FAILED_EXCEPTION e) {
Keeblarcraft.LOGGER.error("ERROR. Setup failed to initialize environment. Mod likely does not have read/write permissions inside area. Mod will now close out."); 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));
e.printStackTrace(); e.printStackTrace();
} }
} else { } else {
// Program exit. Dual definition of setup somehow happened! // Program exit. Dual definition of setup somehow happened!
Keeblarcraft.LOGGER.error("Dual definition of singleton attempted! Out of order initialization? How did this even happen?"); System.out.println(ChatUtil.ColoredString("Dual definition of singleton attempted! Out of order initialization? How did this even happen?", CONSOLE_COLOR.RED));
} }
} }
} }

View File

@ -1,81 +0,0 @@
package jesse.keeblarcraft.MailSystem;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
public class MailMgr {
ConfigManager config = new ConfigManager();
MailConfigClass mailConfig;
String CONFIG_FILE = "mail/player_mail.json";
private static MailMgr static_inst;
public static MailMgr GetInstance() {
if (static_inst == null) {
static_inst = new MailMgr();
}
return static_inst;
}
private class MailConfigClass {
private HashMap<String, ArrayList<String>> mailList = new HashMap<String, ArrayList<String>>();
}
public MailMgr() {
System.out.println("Mail manager called");
Boolean existingFile = false;
try {
mailConfig = config.GetJsonObjectFromFile(CONFIG_FILE, MailConfigClass.class);
existingFile = true;
} catch (Exception e) {
System.out.println("Mail config could not correctly parse json file or it did not exist");
}
if (!existingFile) {
try {
config.CreateFile(CONFIG_FILE);
} catch (Exception e) {
System.out.println("Failed to correctly make or parse mail config file");
}
}
}
public void SendMail(String playerUuid, String mail) {
if (mailConfig != null) {
if (mailConfig.mailList.containsKey(playerUuid)) {
mailConfig.mailList.get(playerUuid).add(mail);
} else {
mailConfig.mailList.put(playerUuid, new ArrayList<>(Arrays.asList(mail)));
}
} else {
System.out.println("Mail config is null. Cannot send");
}
}
public List<String> GetMail(String playerUuid) {
List<String> mail = null;
if (mailConfig.mailList.containsKey(playerUuid)) {
mail = mailConfig.mailList.get(playerUuid);
}
return mail;
}
public void ClearMail(String playerUuid) {
if (mailConfig != null && mailConfig.mailList.containsKey(playerUuid)) {
mailConfig.mailList.remove(playerUuid);
}
}
public void FlashConfig() {
if (mailConfig != null) {
try {
config.WriteToJsonFile(CONFIG_FILE, mailConfig);
} catch (Exception e) {
System.out.println("Could not flash mail config");
}
}
}
}

View File

@ -0,0 +1,152 @@
/*
*
* ChatUtil
*
* Helpful utility for pretty printing in chat in the game with different supported functions and levels
*
*/
package jesse.keeblarcraft.Utils;
import org.slf4j.Logger;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
public class ChatUtil {
//This is a private class only used internally to get ANSI colors
private static class ConsoleColor {
public static String getColor(CONSOLE_COLOR color) {
String ret = "";
switch(color) {
case RED:
ret = "31";
break;
case GREEN:
ret = "32";
break;
case YELLOW:
ret = "33";
break;
case BLUE:
ret = "34";
break;
case MAGENTA:
ret = "35";
break;
case CYAN:
ret = "36";
break;
}
return ret;
}
}
public static enum CONSOLE_COLOR {
RED,
GREEN,
YELLOW,
BLUE,
MAGENTA,
CYAN;
}
static int CHATBOX_WIDTH_CHARS = 80; // Maximum length of the textbox in individual characters
// Helpful print wrapper function
static public void SendPlayerMsg(ServerPlayerEntity player, String text) {
player.sendMessage(Text.literal(text));
}
/// TODO: Add this back in later under a chat ticket
// Prints a table of data in chat
// static public void ChatBlock(ServerPlayerEntity player, HashMap<Text, List<Text>> table) {
// ///DEBUG
// for (Entry<Text, List<Text>> entry : table.entrySet()) {
// for (int debug = 0; debug < entry.getValue().size(); debug++) {
// System.out.println("KEY: " + entry.getKey().toString() + " VALUE: " + entry.getValue().get(debug).toString());
// }
// }
// // The user will likely pass in text strings longer than the character limit for num of columns; therefore
// // we are required to split these into this finalPrintList structure
// HashMap<Text, ArrayList<Text>> finalPrintList = new HashMap<Text, ArrayList<Text>>();
// int maxColumnWidth = CHATBOX_WIDTH_CHARS / table.size(); // Represents max char allowance per data column
// maxColumnWidth -= table.size(); // Represents a separating '|' between each column
// // This first behemoth of a loop is to take the given table hashmap and look at
// // the Text values & split them
// // should their size exceed the maxColumnWidth given for each entry key
// System.out.println("Entry data is size " + table.size());
// for (Entry<Text, List<Text>> entry : table.entrySet()) {
// // Each text line found cannot be longer than "maxColumnWidth" or else it must
// // wrap which splits it
// // into two texts; thus adding an additional row that is required for iteration.
// // Each split text must
// // maintain the same formatting as the root text it is split from
// finalPrintList.put(entry.getKey(), new ArrayList<Text>()); // Instantiate the key & array
// System.out.println("Map size is " + finalPrintList.size());
// System.out.println("Entry value size is " + entry.getValue().size());
// for (Text item : entry.getValue()) {
// int numItems = (int) Math.ceil((item.getString().length() / maxColumnWidth));
// int strOffset = numItems; // Represents number of items per string
// System.out.println("numItems: " + numItems);
// System.out.println("strOffset: " + strOffset);
// for (int offset = 0; offset <= numItems; offset++) { /// TODO: might need to be <=
// int start = strOffset * offset; // Multiple from start of string to needed point
// int end = start + strOffset; // The original start offset + the width spacer
// String substr = item.toString().substring(start, end); // Contains the string to be Textified
// MutableText newText = Text.literal(substr).setStyle(item.getStyle());
// finalPrintList.get(entry.getKey()).add(newText); // Add back into list
// System.out.println("SPLIT DEBUG: " + newText.toString());
// }
// }
// }
// // This loop does the printing of the table in chat
// int tempPreventInfiniteLoops = 10;
// while (finalPrintList.size() != 0) {
// // This is a one time print
// MutableText line = Text.literal("");
// for (Entry<Text, ArrayList<Text>> entry : finalPrintList.entrySet()) {
// if (entry.getValue().size() != 0) {
// line.append(entry.getValue().get(0));
// System.out.println("new line is now " + line.toString());
// line.append("|");
// } else {
// finalPrintList.remove(entry.getKey()); // Clear the key; as we are done with this column for
// // printing
// }
// player.sendMessage(line);
// String debugPrint = line.toString();
// System.out.println("Debug line to be printed: " + debugPrint);
// line = Text.literal("");
// break;
// }
// tempPreventInfiniteLoops--;
// if (tempPreventInfiniteLoops <= 0) {
// return;
// }
// }
// }
// Returns a string with the proper ANSI encoding for the specified CONSOLE_COLOR
static public String ColoredString(String msg, CONSOLE_COLOR color) {
return "\033[" + ConsoleColor.getColor(color) + "m" + msg + "\033[0m";
}
// Takes in a (already initialized) logger object and prints to console
static public void LoggerColored(String msg, CONSOLE_COLOR color, Logger logger) {
logger.info(ColoredString(msg, color));
}
}

View File

@ -1,26 +0,0 @@
package jesse.keeblarcraft.Utils.CommonStructures;
public class Pair<KEY, VALUE> {
KEY key;
VALUE value;
public Pair(KEY key, VALUE val) {
this.key = key;
this.value = val;
}
public KEY GetKey() {
return key;
}
public VALUE GetValue() {
return value;
}
public void SetKey(KEY newKey) {
this.key = newKey;
}
public void SetValue(VALUE newValue) {
this.value = newValue;
}
}

View File

@ -1,24 +1,54 @@
/* package jesse.keeblarcraft.Utils;
*
* ChatMsg
*
* Helpful utility for pretty printing in chat in the game with different supported functions and levels
*
*/
package jesse.keeblarcraft.ChatStuff;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import jesse.keeblarcraft.ChatStuff.ChatFormatting.COLOR_CODE;
import net.minecraft.text.ClickEvent; import net.minecraft.text.ClickEvent;
import net.minecraft.text.HoverEvent; import net.minecraft.text.HoverEvent;
import net.minecraft.text.MutableText; import net.minecraft.text.MutableText;
import net.minecraft.text.Style; import net.minecraft.text.Style;
import net.minecraft.text.Text; import net.minecraft.text.Text;
public class ChatMsg { 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 /// @fn MakeCopyableTxt
/// ///
@ -109,28 +139,7 @@ public class ChatMsg {
/// @return Formatted string of colored text /// @return Formatted string of colored text
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public String ColorMsg(Integer msg, COLOR_CODE color) { public String ColorMsg(Integer msg, COLOR_CODE color) {
return ChatFormatting.GetColor(color) + msg + ChatFormatting.COLOR_END; return getColor(color) + msg + COLOR_END;
}
/////////////////////////////////////////////////////////////////////////////
/// @fn ColorMsg
///
/// @param[in] msg is an Text object
///
/// @param[in] color is the color option
///
/// @brief Creates a formatted string that will be colored at the
/// specification of the developer
///
/// @return Text object but with the minecraft color injected around
/// string
///
/// @note THIS WILL REMOVE FORMATTING ON THE TEXT. If you need to keep
/// formatting/other specialties, format a string with the color
/// first with functions inside this class.
/////////////////////////////////////////////////////////////////////////////
public Text ColorMsg(Text msg, COLOR_CODE color) {
return Text.of(ChatFormatting.GetColor(color) + msg.getString() + ChatFormatting.COLOR_END);
} }
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
@ -151,7 +160,7 @@ public class ChatMsg {
List<String> retList = new ArrayList<String>(); List<String> retList = new ArrayList<String>();
for (String str : msg) { for (String str : msg) {
retList.add(ChatFormatting.GetColor(color) + str + ChatFormatting.COLOR_END); retList.add(getColor(color) + str + COLOR_END);
} }
return retList; return retList;
@ -170,7 +179,7 @@ public class ChatMsg {
/// @return Formatted string of colored text /// @return Formatted string of colored text
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public String ColorMsg(String msg, COLOR_CODE color) { public String ColorMsg(String msg, COLOR_CODE color) {
return ChatFormatting.GetColor(color) + msg + ChatFormatting.COLOR_END; return getColor(color) + msg + COLOR_END;
} }
// Parses a help command and color codes it. assume everything up to first '.' is the // Parses a help command and color codes it. assume everything up to first '.' is the
@ -191,7 +200,7 @@ public class ChatMsg {
/// @return Formatted string of colored text /// @return Formatted string of colored text
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public String FormatMsg(String helpCmd, COLOR_CODE primaryColor, COLOR_CODE secondaryColor) { public String FormatMsg(String helpCmd, COLOR_CODE primaryColor, COLOR_CODE secondaryColor) {
String coloredStr = ChatFormatting.GetColor(primaryColor); String coloredStr = getColor(primaryColor);
List<String> splitStr = List.of(helpCmd.split("\\.")); List<String> splitStr = List.of(helpCmd.split("\\."));
Boolean isFirst = true; Boolean isFirst = true;
@ -199,12 +208,12 @@ public class ChatMsg {
if (isFirst) { if (isFirst) {
coloredStr += str; coloredStr += str;
isFirst = false; isFirst = false;
coloredStr += ChatFormatting.GetColor(secondaryColor); coloredStr += getColor(secondaryColor);
} else { } else {
coloredStr += str; coloredStr += str;
} }
} }
return coloredStr + ChatFormatting.COLOR_END; return coloredStr + COLOR_END;
} }
} }

View File

@ -1,26 +0,0 @@
package jesse.keeblarcraft.Utils;
import com.mojang.brigadier.context.CommandContext;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
public class PlayerChecks {
public static Boolean HasPermission(CommandContext<ServerCommandSource> context) {
if (context.getSource().isExecutedByPlayer() && HasPermission(context.getSource().getPlayer())) {
return true;
} else {
return false;
}
}
public static Boolean HasPermission(ServerPlayerEntity player) {
if (player.hasPermissionLevel(4)) {
return true;
} else {
player.sendMessage(Text.of("You do not have permission to use this command."));
return false;
}
}
}

View File

@ -14,8 +14,9 @@ import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import jesse.keeblarcraft.Keeblarcraft;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_CREATE_EXCEPTION;
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION; import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
// Singleton class is designed to help the mod set itself up and create all the important things. It does two things: // Singleton class is designed to help the mod set itself up and create all the important things. It does two things:
@ -31,7 +32,9 @@ public final class Setup {
private static Setup static_inst; private static Setup static_inst;
private static String GLOBAL_CONFIG = "config/keeblarcraft/"; private static String GLOBAL_CONFIG = "config/keeblarcraft/";
public Setup() {} public Setup() {
System.out.println(ChatUtil.ColoredString("Running system setup and checks...", CONSOLE_COLOR.BLUE));
}
// Returns the singleton object // Returns the singleton object
public static Setup GetInstance() { public static Setup GetInstance() {
@ -48,23 +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("misc"); 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()
@ -76,32 +80,45 @@ public final class Setup {
ConfigManager conf = new ConfigManager(); ConfigManager conf = new ConfigManager();
// Create directory check // Create directory check
try {
has_write = conf.CreateDirectory("test_dir"); has_write = conf.CreateDirectory("test_dir");
System.out.println(ChatUtil.ColoredString("test_dir created! has write: ", CONSOLE_COLOR.GREEN) + (has_write ? ChatUtil.ColoredString("YES", CONSOLE_COLOR.YELLOW) : ChatUtil.ColoredString("NO", CONSOLE_COLOR.YELLOW)));
} catch (DIRECTORY_CREATE_EXCEPTION e) {
System.out.println(ChatUtil.ColoredString("Failed to create test directory or it already exists", CONSOLE_COLOR.MAGENTA));
has_write = false;
}
if (!has_write) { // Write to disk then read that data back
Keeblarcraft.LOGGER.error("Uh oh! It appears we could not successfully identify that we have write permissions. Attempt to create a directory failed."); if (has_write) {
} else { try {
has_write = conf.CreateFile("test_dir/test_note.txt"); has_write = conf.CreateFile("test_dir/test_note.txt");
has_write = conf.WriteToFile("test_dir/test_note.txt", "test_write_read", "w"); has_write = conf.WriteToFile("test_dir/test_note.txt", "test_write_read", "w");
List<String> lines = conf.GetFileLines("test_dir/test_note.txt"); List<String> lines = conf.GetFile("test_dir/test_note.txt");
if (lines.size() == 0) { if (lines.size() == 0) {
has_read = false; has_read = false;
} else { } else {
has_read = true; has_read = true;
} }
} catch (Exception e) {
System.out.println(ChatUtil.ColoredString("Failed to create or write to test dir file ", CONSOLE_COLOR.RED));
has_read = false;
}
}
// Delete directory if created (it's a temporary dir)
if (has_write) {
try {
has_write = conf.DeleteFile("test_dir/test_note.txt"); has_write = conf.DeleteFile("test_dir/test_note.txt");
has_write = conf.DeleteDirectory("test_dir"); has_write = conf.DeleteDirectory("test_dir");
} catch (Exception e) {
if (!has_write) { System.out.println(ChatUtil.ColoredString("Lost access to writing mid-way", CONSOLE_COLOR.RED));
Keeblarcraft.LOGGER.error("Uh oh! It appears we lost the ability to write or delete files after making one. Something is seriously wrong!"); has_write = false;
} }
} }
//need to be able to take in raw booleans for coloredstrings functions
Keeblarcraft.LOGGER.debug("CHECKS DEBUG: Value of has_write: "+has_write.toString()+". Value of has_read: "+has_read.toString()); System.out.println(ChatUtil.ColoredString("CHECKS DEBUG: Value of has_write: ", CONSOLE_COLOR.BLUE) + ChatUtil.ColoredString(has_write.toString(), CONSOLE_COLOR.YELLOW) + ChatUtil.ColoredString(". Value of has_read: ", CONSOLE_COLOR.BLUE) + ChatUtil.ColoredString(has_read.toString(), CONSOLE_COLOR.YELLOW));
// return has_write && has_read; return has_write && has_read;
return true; /// TODO: ConfigManager has been rewritten so much that the above code is out dated. Fix later return true for now
} }
// RunSetup // RunSetup
@ -118,9 +135,9 @@ public final class Setup {
for (Integer i = 0; i < DIRECTORY_LIST.size(); i++) { for (Integer i = 0; i < DIRECTORY_LIST.size(); i++) {
if ( ! conf.DoesDirectoryExist(DIRECTORY_LIST.get(i))) { if ( ! conf.DoesDirectoryExist(DIRECTORY_LIST.get(i))) {
conf.CreateDirectory(DIRECTORY_LIST.get(i)); conf.CreateDirectory(DIRECTORY_LIST.get(i));
Keeblarcraft.LOGGER.debug("Creating directory " + DIRECTORY_LIST.get(i)); System.out.println(ChatUtil.ColoredString("Creating directory ", CONSOLE_COLOR.GREEN) + ChatUtil.ColoredString(DIRECTORY_LIST.get(i), CONSOLE_COLOR.YELLOW) + ChatUtil.ColoredString("...", CONSOLE_COLOR.GREEN));
} else { } else {
Keeblarcraft.LOGGER.debug(DIRECTORY_LIST.get(i) + " already exists. Skipping creation."); System.out.println(ChatUtil.ColoredString("Directory ", CONSOLE_COLOR.BLUE) + conf.DoesDirectoryExist(DIRECTORY_LIST.get(i)) + ChatUtil.ColoredString(" already exists. Skipping... ", CONSOLE_COLOR.BLUE));
} }
} }
@ -128,20 +145,20 @@ public final class Setup {
for (Integer i = 0; i < FILE_LIST.size(); i++) { for (Integer i = 0; i < FILE_LIST.size(); i++) {
if ( ! conf.DoesFileExist(FILE_LIST.get(i))) { if ( ! conf.DoesFileExist(FILE_LIST.get(i))) {
conf.CreateFile(FILE_LIST.get(i)); conf.CreateFile(FILE_LIST.get(i));
Keeblarcraft.LOGGER.debug("Creating file " + DIRECTORY_LIST.get(i)); System.out.println(ChatUtil.ColoredString("Creating file ", CONSOLE_COLOR.GREEN) + ChatUtil.ColoredString(FILE_LIST.get(i), CONSOLE_COLOR.YELLOW) + ChatUtil.ColoredString("...", CONSOLE_COLOR.GREEN));
} else { } else {
Keeblarcraft.LOGGER.debug(DIRECTORY_LIST.get(i) + " already exists. Skipping creation."); System.out.println(ChatUtil.ColoredString("File ", CONSOLE_COLOR.BLUE) + conf.DoesDirectoryExist(FILE_LIST.get(i)) + ChatUtil.ColoredString(" already exists. Skipping...", CONSOLE_COLOR.BLUE));
} }
} }
} catch (Exception e) { } catch (Exception e) {
throw new SETUP_FAILED_EXCEPTION(); throw new SETUP_FAILED_EXCEPTION();
} }
} else { } else {
Keeblarcraft.LOGGER.error("The setup phase failed in its processing and has determined it does not have necessary read or write priviliges in this hosted area and will now exit."); System.out.println(ChatUtil.ColoredString("RunChecks() failed in its process. This mod has deemed it does not have read or write privileges in its hosted area and will now exit.", CONSOLE_COLOR.RED));
throw new SETUP_FAILED_EXCEPTION(); throw new SETUP_FAILED_EXCEPTION();
} }
Keeblarcraft.LOGGER.debug("DID SETUP COMPLETE SUCCESSFULLY? " + (ret ? "YES":"NO")); System.out.println(ChatUtil.ColoredString("DID SETUP COMPLETE SUCCESSFULLY? ", CONSOLE_COLOR.YELLOW) + (ret ? ChatUtil.ColoredString("YES", CONSOLE_COLOR.YELLOW) : ChatUtil.ColoredString("NO", CONSOLE_COLOR.YELLOW)));
return ret; return ret;
} }

View File

@ -1,25 +0,0 @@
package jesse.keeblarcraft.datagen;
import jesse.keeblarcraft.CustomBlocks.BlockManager;
import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput;
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider;
import net.minecraft.data.client.BlockStateModelGenerator;
import net.minecraft.data.client.ItemModelGenerator;
public class KeeblarModelProvider extends FabricModelProvider {
public KeeblarModelProvider(FabricDataOutput output) {
super(output);
}
@Override
public void generateBlockStateModels(BlockStateModelGenerator blockStateModelGenerator) {
blockStateModelGenerator.registerSimpleState(BlockManager.GetBlock("faction_base_block"));
}
@Override
public void generateItemModels(ItemModelGenerator itemModelGenerator) {
}
}

View File

@ -1,30 +0,0 @@
package jesse.keeblarcraft.mixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.minecraft.entity.Entity;
import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler;
@Mixin(targets = "net.minecraft.server.network.ServerPlayNetworkHandler$1")
public abstract class PlayerEntityInteractionHandler implements PlayerInteractEntityC2SPacket.Handler {
// Unsure what @Shadow is doing, but I'm sure fabric wiki can explain
// @Shadow(aliases = "field_28963") @Final private ServerPlayNetworkHandler field_28963; // I assume this is just a bad named field which is the ServerPlayNetworkHandler
// @Shadow(aliases = "field_28962") @Final private Entity field_28962; // I assume this is just a bad named field which is the Entity in question depending on the function
// // Probably not required for a tool since this is hitting, but you would need to check this if you DID want to make a longer reaching sword or something. Attack is
// // in PlayerEntity but this mixin targets the server handler because the server dictates hitting between stuff
// @Inject(method = "attack()V", at = @At("HEAD"), require = 1, allow = 1, cancellable = true)
// private void isActuallyInHitRange(final CallbackInfo callback) {
// // All we are doing in this class is telling the 'attack' function to return false immediately if the two entities are not within a squared distance of each other.
// // 100 hard coded because value of hit range is hard coded '10' in the ClientPlayerInteractionManagerMixin in the client section (10^2)
// if (!(this.field_28963.player.squaredDistanceTo(this.field_28962) <= 100)) { // 10^2 becauses 10 blocks chosen in Client mixin
// callback.cancel();
// }
// }
}

View File

@ -1,56 +0,0 @@
package jesse.keeblarcraft.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import jesse.keeblarcraft.Keeblarcraft;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
// MIXIN CHEAT SHEET:
// https://wiki.fabricmc.net/tutorial:mixin_examples
// Tutorial I referenced for this knowledge (outside fabric wiki): https://www.youtube.com/watch?v=HQUkWjMWTik
// MAKE SURE YOU READ fabric_mod.json and the keeblarcraft.mixin.json!! These injections are not instantiated anywhere else because mixins are special
// because all this code is essentially injected (pasted) into their respective areas during compilation.
//
// PLEASE SEE https://wiki.fabricmc.net/tutorial:mixin_injects FOR ALL THE PARAMETER TYPES OF INJECTION (you will likely have a question about all the types after reading
// bullet point #3 in the below injection explanation because I only explain 'Z' in that case)
@Mixin(PlayerEntity.class)
// *THIS* CLASS MUST BE ABSTRACT - BUT NOT TRUE FOR EVERY MIXIN
public abstract class PlayerMixin {
// Example 0: Base injection (HEAD)
// EXPLANATION OF THI MAGIC STRING:
// This string MUST be written as so; BUT - it's not so bad! It has logic to it - obviously. Some known, some still a bit not
// 1. 'dropItem' is the method we are overriding, and then we are just specifying exactly (which is required) where that method is at
// 2. 'Lnet/minecraft/item/ItemStack' -> First argument inside method we are injecting in. In this case, the argument is an object 'ItemStack' so we specify
// that this is the net/minecraft/item/ItemStack type. WHY THE 'L' AT START? Don't know - but it's used in EVERY example
// so it can be assumed you always need it. It's consistently there, so not a huge deal.
// 3. The 'ZZ' here are the other parameters inside the method which are java defaults - 'Z' happens to stand for boolean. It seems semicolons aren't needed
// between defaults since it just goes 'ZZ' and the parameter finishes with two booleans. Please CTRL+CLICK into the PlayerEntity class and search for 'dropItem' to
// familiarize yourself with the signature of the function.
// 4. The appending 'Lnet/minecraft/entity/ItemEntity' is the RETURN TYPE of this method
// 5. WHAT IS THE 'at = @At' syntax? Well; it is VERY Helpful to familiarize yourself with some areas on the fabric cheat sheet (https://wiki.fabricmc.net/tutorial:mixin_examples)
// but to give a brief explanation of it - it's just WHERE you are injecting your code at inside this function. 'HEAD' means the very top. 'TAIL' means at the end. There also
// is ways to inject by some offset into the function, and whatever a 'slice' is but I'm not looking at those right now. You get the idea
// 6. WHAT IS THE 'cancellable = true'
@Inject(method = "dropItem(Lnet/minecraft/item/ItemStack;ZZ)Lnet/minecraft/entity/ItemEntity;", at = @At("HEAD"), cancellable = true)
// THE METHOD CAN BE CALLED WHATEVER - But make sure it takes in the same parameters as the method you are mixing into ('mixin')
// 1. What's the 'CallbackInfoReturnable<ItemEntity> cir' here? This can be the item we return with inside our injection. You need to picture the code in this
// function as literally being copied+pasted into what you are injecting into (at the 'HEAD', in this case).
// 2. Why is this function 'void' if dropItem is not? -> The last parameter actually covers this case if we need to return but it's not required - remember this is a copy and
// paste of code into the function itself so it's not really relevant that our MIXIN function here returns anything
public void dropItem0(ItemStack stack, boolean throwRandomly, boolean retainOwnership, CallbackInfoReturnable<ItemEntity> cir) {
// WHY THE CAST LIKE THIS?
// This is the starting work required to get 'this' from the perspective of PlayerEntity
// 1. Remember that 'this' is actually NOT the PlayerEntity class, but we want to use the methods and functions from that class
// 2. Casting (Object) 'this' gets us the 'PlayerMixin' class as a general object that we can cast into anything else
// 3. Casting '(Object) this' into 'PlayerEntity' gets us to the mixin inject - and NOW we can store the result of this cast into the type we want as a reference
// which is the 'PlayerEntity' on the left hand side. Now we can access stuff from that class AS IF WE ARE CODING INSIDE OF THAT CLASS :)))
PlayerEntity player = (PlayerEntity) (Object) this;
Keeblarcraft.LOGGER.info("PLAYER MIXIN: " + player.getEntityName());
}
}

View File

@ -1,40 +0,0 @@
package jesse.keeblarcraft.mixin;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Constant;
import org.spongepowered.asm.mixin.injection.ModifyConstant;
import org.spongepowered.asm.mixin.injection.Redirect;
import net.minecraft.network.listener.ServerPlayPacketListener;
import net.minecraft.server.network.ServerPlayNetworkHandler;
@Mixin(ServerPlayNetworkHandler.class)
public abstract class ServerPlayNetworkHandlerMixin implements ServerPlayPacketListener {
// Truth be told not required for a pickaxe or tool probably
// @Redirect(
// method = "onPlayerInteractEntity(Lnet/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket;)V",
// at = @At(value = "FIELD", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;MAX_BREAK_SQUARED_DISTANCE:D", opcode = Opcodes.GETSTATIC))
// private double getActualAttackRange() {
// return 100; // 10^2 becauses 10 blocks chosen in Client mixin
// }
// // Essentially replaces the 'MAX_BREAK_SQUARED_DISTANCE' value with the value we have in the function (100), or 10 blocks which bc 10^2
// @Redirect(
// method = "onPlayerInteractBlock(Lnet/minecraft/network/packet/c2s/play/PlayerInteractBlockC2SPacket;)V",
// at = @At(value = "FIELD", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;MAX_BREAK_SQUARED_DISTANCE:D", opcode = Opcodes.GETSTATIC))
// private double getActualReachDistance() {
// return 100; // 10^2 becauses 10 blocks chosen in Client mixin
// }
// // Search '64' inside the same onPlayerInteractBlock, would also need to replace that value maybe. This is in the github reference for that block breaking
// // im not 100% sure what this is doing. If it's squared then sqrt(64) = 8 blocks but I'm not sure what 8 would represent here.
// @ModifyConstant(
// method = "onPlayerInteractBlock(Lnet/minecraft/network/packet/c2s/play/PlayerInteractBlockC2SPacket;)V",
// require = 1, allow = 1, constant = @Constant(doubleValue = 64.0))
// private double getActualReachDistance(final double reachDistance) {
// return 100; // 10^2 becauses 10 blocks chosen in Client mixin
// }
}

View File

@ -1,24 +0,0 @@
package jesse.keeblarcraft.mixin;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.network.ServerPlayerInteractionManager;
// This class is needed to validate the actual block breaking
@Mixin(ServerPlayerInteractionManager.class)
public abstract class ServerPlayerInteractionManagerMixin {
// @Shadow @Final protected ServerPlayerEntity player;
// @Redirect(
// method = "processBlockBreakingAction",
// at = @At(value = "FIELD", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;MAX_BREAK_SQUARED_DISTANCE:D", opcode = Opcodes.GETSTATIC))
// private double getActualReachDistance() {
// return 100; // 10^2 becauses 10 blocks chosen in Client mixin
// }
}

View File

@ -1,7 +0,0 @@
{
"variants": {
"": {
"model": "keeblarcraft:block/faction_base_block"
}
}
}

View File

@ -9,7 +9,6 @@
"block.keeblarcraft.example_block": "Keeblarcraft example block", "block.keeblarcraft.example_block": "Keeblarcraft example block",
"block.keeblarcraft.example_block_ore": "Keeblarcraft example block ore", "block.keeblarcraft.example_block_ore": "Keeblarcraft example block ore",
"block.keeblarcraft.example_statue": "Keeblarcraft example statue", "block.keeblarcraft.example_statue": "Keeblarcraft example statue",
"block.keeblarcraft.faction_base_block": "Factions Base Block",
"category.keeblarcraft.test": "Keeblarcraft bindings", "category.keeblarcraft.test": "Keeblarcraft bindings",
"key.keeblarcraft.treemap": "Tree GUI", "key.keeblarcraft.treemap": "Tree GUI",

View File

@ -1,232 +0,0 @@
{
"credit": "Made with Blockbench",
"texture_size": [64, 64],
"textures": {
"0": "keeblarcraft:block/faction_base_block",
"particle": "keeblarcraft:block/faction_base_block"
},
"elements": [
{
"from": [12, 0, 2],
"to": [14, 3, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [2, 0, 2]},
"faces": {
"north": {"uv": [2, 6, 2.5, 6.75], "texture": "#0"},
"east": {"uv": [2.5, 2, 5.5, 2.75], "texture": "#0"},
"south": {"uv": [6, 3.25, 6.5, 4], "texture": "#0"},
"west": {"uv": [2.5, 2.75, 5.5, 3.5], "texture": "#0"},
"up": {"uv": [3, 8, 2.5, 5], "texture": "#0"},
"down": {"uv": [3.5, 5, 3, 8], "texture": "#0"}
}
},
{
"from": [2, 0, 2],
"to": [4, 3, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [-8, 0, 2]},
"faces": {
"north": {"uv": [5.75, 6, 6.25, 6.75], "texture": "#0"},
"east": {"uv": [2.5, 3.5, 5.5, 4.25], "texture": "#0"},
"south": {"uv": [0, 6.25, 0.5, 7], "texture": "#0"},
"west": {"uv": [0, 4.25, 3, 5], "texture": "#0"},
"up": {"uv": [4, 8, 3.5, 5], "texture": "#0"},
"down": {"uv": [4.5, 5, 4, 8], "texture": "#0"}
}
},
{
"from": [7, 0, 5],
"to": [9, 2, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [-3, 0, 3]},
"faces": {
"north": {"uv": [1.5, 6.25, 2, 6.75], "texture": "#0"},
"east": {"uv": [4.5, 5, 6, 5.5], "texture": "#0"},
"south": {"uv": [6.25, 4.5, 6.75, 5], "texture": "#0"},
"west": {"uv": [5.5, 2, 7, 2.5], "texture": "#0"},
"up": {"uv": [6, 4, 5.5, 2.5], "texture": "#0"},
"down": {"uv": [5, 5.5, 4.5, 7], "texture": "#0"}
}
},
{
"from": [3, 5, 4],
"to": [13, 7, 12],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 5, 7]},
"faces": {
"north": {"uv": [5, 0, 7.5, 0.5], "texture": "#0"},
"east": {"uv": [5, 1, 7, 1.5], "texture": "#0"},
"south": {"uv": [5, 0.5, 7.5, 1], "texture": "#0"},
"west": {"uv": [5, 1.5, 7, 2], "texture": "#0"},
"up": {"uv": [2.5, 2, 0, 0], "texture": "#0"},
"down": {"uv": [2.5, 2, 0, 4], "texture": "#0"}
}
},
{
"from": [3, 1, 4],
"to": [13, 5, 7],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 2, 5]},
"faces": {
"north": {"uv": [2.5, 0, 5, 1], "texture": "#0"},
"east": {"uv": [5.5, 4, 6.25, 5], "texture": "#0"},
"south": {"uv": [2.5, 1, 5, 2], "texture": "#0"},
"west": {"uv": [5, 5.5, 5.75, 6.5], "texture": "#0"},
"up": {"uv": [5.5, 5, 3, 4.25], "texture": "#0"},
"down": {"uv": [2.5, 5, 0, 5.75], "texture": "#0"}
}
},
{
"from": [3, 7, 4],
"to": [13, 8, 5],
"rotation": {"angle": 0, "axis": "y", "origin": [5, 7, 3]},
"faces": {
"north": {"uv": [0, 4, 2.5, 4.25], "texture": "#0"},
"east": {"uv": [2, 7.25, 2.25, 7.5], "texture": "#0"},
"south": {"uv": [0, 5.75, 2.5, 6], "texture": "#0"},
"west": {"uv": [2.25, 7.25, 2.5, 7.5], "texture": "#0"},
"up": {"uv": [8.25, 5.75, 5.75, 5.5], "texture": "#0"},
"down": {"uv": [8.25, 5.75, 5.75, 6], "texture": "#0"}
}
},
{
"from": [3.001, 6.999, 4.001],
"to": [4.001, 7.999, 9.001],
"rotation": {"angle": 0, "axis": "y", "origin": [5, 7, 6]},
"faces": {
"north": {"uv": [4.5, 7.25, 4.75, 7.5], "texture": "#0"},
"east": {"uv": [6, 5, 7.25, 5.25], "texture": "#0"},
"south": {"uv": [7.25, 4.5, 7.5, 4.75], "texture": "#0"},
"west": {"uv": [6, 5.25, 7.25, 5.5], "texture": "#0"},
"up": {"uv": [0.75, 7.5, 0.5, 6.25], "texture": "#0"},
"down": {"uv": [1, 6.25, 0.75, 7.5], "texture": "#0"}
}
},
{
"from": [11.99, 6.999, 4.001],
"to": [12.99, 7.999, 9.001],
"rotation": {"angle": 0, "axis": "y", "origin": [14, 7, 6]},
"faces": {
"north": {"uv": [4.75, 7.25, 5, 7.5], "texture": "#0"},
"east": {"uv": [6.25, 4, 7.5, 4.25], "texture": "#0"},
"south": {"uv": [7.25, 4.75, 7.5, 5], "texture": "#0"},
"west": {"uv": [6.25, 4.25, 7.5, 4.5], "texture": "#0"},
"up": {"uv": [1.25, 7.5, 1, 6.25], "texture": "#0"},
"down": {"uv": [1.5, 6.25, 1.25, 7.5], "texture": "#0"}
}
},
{
"from": [5, 7, 6],
"to": [7, 8, 8],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 5]},
"faces": {
"north": {"uv": [6.5, 3.75, 7, 4], "texture": "#0"},
"east": {"uv": [6.75, 6, 7.25, 6.25], "texture": "#0"},
"south": {"uv": [6.75, 6.25, 7.25, 6.5], "texture": "#0"},
"west": {"uv": [6.75, 6.5, 7.25, 6.75], "texture": "#0"},
"up": {"uv": [6.75, 6.5, 6.25, 6], "texture": "#0"},
"down": {"uv": [7, 3.25, 6.5, 3.75], "texture": "#0"}
}
},
{
"from": [9, 7, 6],
"to": [11, 8, 8],
"rotation": {"angle": 0, "axis": "y", "origin": [11, 7, 5]},
"faces": {
"north": {"uv": [6.75, 6.75, 7.25, 7], "texture": "#0"},
"east": {"uv": [0, 7, 0.5, 7.25], "texture": "#0"},
"south": {"uv": [7, 1, 7.5, 1.25], "texture": "#0"},
"west": {"uv": [7, 1.25, 7.5, 1.5], "texture": "#0"},
"up": {"uv": [5.5, 7, 5, 6.5], "texture": "#0"},
"down": {"uv": [6.75, 6.5, 6.25, 7], "texture": "#0"}
}
},
{
"from": [9, 7, 9],
"to": [11, 8, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [11, 7, 8]},
"faces": {
"north": {"uv": [7, 1.5, 7.5, 1.75], "texture": "#0"},
"east": {"uv": [7, 1.75, 7.5, 2], "texture": "#0"},
"south": {"uv": [7, 2, 7.5, 2.25], "texture": "#0"},
"west": {"uv": [7, 2.25, 7.5, 2.5], "texture": "#0"},
"up": {"uv": [2, 7.25, 1.5, 6.75], "texture": "#0"},
"down": {"uv": [2.5, 6.75, 2, 7.25], "texture": "#0"}
}
},
{
"from": [5, 7, 9],
"to": [7, 8, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [7, 7, 8]},
"faces": {
"north": {"uv": [7, 3.25, 7.5, 3.5], "texture": "#0"},
"east": {"uv": [7, 3.5, 7.5, 3.75], "texture": "#0"},
"south": {"uv": [7, 3.75, 7.5, 4], "texture": "#0"},
"west": {"uv": [4.5, 7, 5, 7.25], "texture": "#0"},
"up": {"uv": [7.25, 5, 6.75, 4.5], "texture": "#0"},
"down": {"uv": [6, 6.75, 5.5, 7.25], "texture": "#0"}
}
},
{
"from": [11, 7, 2],
"to": [12, 8, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [10, 6, 2]},
"faces": {
"north": {"uv": [5, 7.25, 5.25, 7.5], "texture": "#0"},
"east": {"uv": [5, 7, 5.5, 7.25], "texture": "#0"},
"south": {"uv": [7.25, 5, 7.5, 5.25], "texture": "#0"},
"west": {"uv": [6, 7, 6.5, 7.25], "texture": "#0"},
"up": {"uv": [6.75, 7.5, 6.5, 7], "texture": "#0"},
"down": {"uv": [7, 7, 6.75, 7.5], "texture": "#0"}
}
},
{
"from": [4, 7, 2],
"to": [5, 8, 4],
"rotation": {"angle": 0, "axis": "y", "origin": [3, 6, 2]},
"faces": {
"north": {"uv": [5.25, 7.25, 5.5, 7.5], "texture": "#0"},
"east": {"uv": [7, 7, 7.5, 7.25], "texture": "#0"},
"south": {"uv": [7.25, 5.25, 7.5, 5.5], "texture": "#0"},
"west": {"uv": [0, 7.25, 0.5, 7.5], "texture": "#0"},
"up": {"uv": [1.75, 7.75, 1.5, 7.25], "texture": "#0"},
"down": {"uv": [2, 7.25, 1.75, 7.75], "texture": "#0"}
}
},
{
"from": [4, 7, 1],
"to": [12, 8, 2],
"rotation": {"angle": 0, "axis": "y", "origin": [6, 6, 0]},
"faces": {
"north": {"uv": [0, 6, 2, 6.25], "texture": "#0"},
"east": {"uv": [5.5, 6.5, 5.75, 6.75], "texture": "#0"},
"south": {"uv": [6, 2.5, 8, 2.75], "texture": "#0"},
"west": {"uv": [6, 6.75, 6.25, 7], "texture": "#0"},
"up": {"uv": [8, 3, 6, 2.75], "texture": "#0"},
"down": {"uv": [8, 3, 6, 3.25], "texture": "#0"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [-138.53, -0.13, 178.31],
"translation": [-0.25, 2.75, -2.5],
"scale": [0.77734, 0.5625, 0.76172]
},
"thirdperson_lefthand": {
"rotation": [-173.23, 0.42, -179.8],
"translation": [0.25, 0, -3.5],
"scale": [0.60156, 0.42188, 0.58984]
},
"gui": {
"rotation": [44.5, 31.22, -19.39],
"translation": [1.75, 3, 0],
"scale": [0.88281, 0.87109, 1.02539]
},
"head": {
"rotation": [180, 0.5, 180],
"translation": [0, 10, 0],
"scale": [1.94141, 1.45703, 2.06641]
},
"fixed": {
"rotation": [90, 40, -180],
"translation": [0, 0, -7],
"scale": [1.17188, 1, 1]
}
}
}

View File

@ -1,3 +0,0 @@
{
"parent": "keeblarcraft:block/faction_base_block"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

View File

@ -28,9 +28,6 @@
"jesse.keeblarcraft.world.biome.ModTerrablenderAPI" "jesse.keeblarcraft.world.biome.ModTerrablenderAPI"
] ]
}, },
"mixins": [
"keeblarcraft.mixins.json"
],
"depends": { "depends": {
"fabricloader": ">=0.15.11", "fabricloader": ">=0.15.11",
"minecraft": "~1.20", "minecraft": "~1.20",

View File

@ -1,18 +0,0 @@
{
"required": true,
"minVersion": "0.8",
"package": "jesse.keeblarcraft.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
"PlayerMixin",
"ServerPlayNetworkHandlerMixin",
"PlayerEntityInteractionHandler",
"ServerPlayerInteractionManagerMixin"
],
"client": [
"ClientPlayerInteractionManagerMixin"
],
"injectors": {
"defaultRequire": 1
}
}