This commit is contained in:
Jkibbels 2024-09-01 19:00:16 -04:00
parent 0ae49bbbdb
commit 88eaeeaeef
11 changed files with 157 additions and 56 deletions

View File

@ -14,14 +14,21 @@ 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.AttributeMgr.AttributeNodes.AttributeFlight; import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AttributeFlight;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AttributeMetalJacket;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Utils.ChatUtil; import jesse.keeblarcraft.Utils.ChatUtil;
import net.minecraft.server.network.ServerPlayerEntity;
public class AttributeMgr { public class AttributeMgr {
ConfigManager config; ConfigManager config;
// Global list of attributes
public static final HashMap<String, AbstractNode> attributes = new HashMap<String, AbstractNode>(); public static final HashMap<String, AbstractNode> attributes = new HashMap<String, AbstractNode>();
// This is a list of all logged in player tree's. These are kept in memory until either the mod is torn down or
// players log out for optimization reasons
public static final HashMap<String, AttributeTree> activeTrees = new HashMap<String, AttributeTree>();
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public static void RegisterAttributeClass(Class<? extends AbstractNode> classObj) { public static void RegisterAttributeClass(Class<? extends AbstractNode> classObj) {
AbstractNode test; AbstractNode test;
@ -44,9 +51,10 @@ public class AttributeMgr {
public static String ApplyAttribute(String uuid, String attributeName) { public static String ApplyAttribute(String uuid, String attributeName) {
String msg = ""; String msg = "";
if (attributes.containsKey(attributeName)) { if (attributes.containsKey(attributeName)) {
AttributeTree playerTree = new AttributeTree(uuid); AttributeTree playerTree = activeTrees.get(uuid);
AbstractNode node = attributes.get(attributeName); AbstractNode node = attributes.get(attributeName);
if (playerTree != null) {
/////////// ///////////
// debug testing // debug testing
String isNull = (node == null ? "NULL" : "NOT NULL"); String isNull = (node == null ? "NULL" : "NOT NULL");
@ -55,8 +63,11 @@ public class AttributeMgr {
// end debug testing // end debug testing
/////////// ///////////
playerTree.AddNewNode(node, 1, null, null); ///TODO: Make handling in AttributeTree of NULL parents list to be defaulted to ROOT playerTree.AddNewNode(node, 1, null, null);
msg = "Applied attribute '" + attributeName + "' successfully"; msg = "Applied attribute '" + attributeName + "' successfully";
} else {
msg = "Player tree not found!";
}
} else { } else {
msg = "Could not apply attribute, attribute name does not exist!"; msg = "Could not apply attribute, attribute name does not exist!";
} }
@ -68,5 +79,6 @@ 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
RegisterAttributeClass(AttributeFlight.class); RegisterAttributeClass(AttributeFlight.class);
RegisterAttributeClass(AttributeMetalJacket.class);
} }
} }

View File

@ -41,4 +41,12 @@ abstract public class AbstractNode {
/// attributes. 1 string per description /// attributes. 1 string per description
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
public abstract HashMap<String, List<String>> GetDetails(); public abstract HashMap<String, List<String>> GetDetails();
/////////////////////////////////////////////////////////////////////////////
/// @fn RegisterCallbacks
///
/// @brief If your node has responsive callbacks; then this is the area
/// you will register your callbacks for everything
/////////////////////////////////////////////////////////////////////////////
public abstract void RegisterCallbacks();
} }

View File

@ -12,9 +12,15 @@ package jesse.keeblarcraft.AttributeMgr.AttributeNodes;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import jesse.keeblarcraft.Keeblarcraft;
import net.fabricmc.fabric.api.event.player.AttackBlockCallback;
import net.minecraft.block.BlockState;
import net.minecraft.util.ActionResult;
public class AttributeFlight extends AbstractNode { public class AttributeFlight extends AbstractNode {
public AttributeFlight() { public AttributeFlight() {
} }
@Override @Override
@ -39,4 +45,19 @@ public class AttributeFlight extends AbstractNode {
return ret; return ret;
} }
@Override
public void RegisterCallbacks() {
// Register events here
AttackBlockCallback.EVENT.register((player, world, hand, pos, direction) -> {
BlockState state = world.getBlockState(pos);
Keeblarcraft.LOGGER.info("Callback for AttackBlockCallback called");
// 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;
});
}
} }

View File

@ -49,4 +49,8 @@ public final class AttributeMetalJacket extends AbstractNode {
return ret; return ret;
} }
@Override
public void RegisterCallbacks() {
}
} }

View File

@ -11,6 +11,7 @@ package jesse.keeblarcraft.AttributeMgr;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map.Entry;
import java.util.HashMap; import java.util.HashMap;
import jesse.keeblarcraft.Keeblarcraft; import jesse.keeblarcraft.Keeblarcraft;
@ -47,6 +48,23 @@ public class AttributeTree {
List<String> childrenNodes; List<String> childrenNodes;
} }
// This will enable the node registration of callbacks on any nodes thats level is not 0
public void RegisterActiveCallbacks() {
for(Entry<String, TreeNode> tree : playerAttributeTree.tree.entrySet()) {
if (tree.getValue().currentNodeLevel != 0) {
// We need to construct the node object if it's null. If it's not null; we assume
// the callback registration process has already happened
if (tree.getValue().thisNode == null) {
System.out.println("REGISTERACTIVECALLBACKS - NULL NODE");
tree.getValue().thisNode.RegisterCallbacks();
} else {
System.out.println("REGISTERACTIVECALLBACKS - NOT NULL NODE");
}
}
}
}
// Separate structure as this is written to the config file // Separate structure as this is written to the config file
private class PlayerTree { private class PlayerTree {
String uuid; String uuid;
@ -74,6 +92,10 @@ public class AttributeTree {
return ret; return ret;
} }
@Override
public void RegisterCallbacks() {
}
} }
// Add a new node to the tree arbitrarily // Add a new node to the tree arbitrarily
@ -104,18 +126,17 @@ public class AttributeTree {
parents = (parents == null ? new ArrayList<String>() : parents); parents = (parents == null ? new ArrayList<String>() : parents);
children = (children == null ? new ArrayList<String>() : children); children = (children == null ? new ArrayList<String>() : children);
System.out.println("Parent size: " + parents.size());
if (parents.size() == 0) { if (parents.size() == 0) {
System.out.println("Root node title: " + root.GetNodeTitle());
parents.add(root.GetNodeTitle()); // No disconnected nodes allowed! All parentless nodes are adopted by root by default parents.add(root.GetNodeTitle()); // No disconnected nodes allowed! All parentless nodes are adopted by root by default
} }
System.out.println("Parents size: " + parents.size());
// Node implementation here // Node implementation here
playerAttributeTree.tree.put(newNode.GetNodeTitle(), new TreeNode(newNode, maxNodeLevel, parents, children)); playerAttributeTree.tree.put(newNode.GetNodeTitle(), new TreeNode(newNode, maxNodeLevel, parents, children));
long pSize = playerAttributeTree.tree.get(newNode.GetNodeTitle()).parentNodes.size(); // if the new nodes level is not 0 we need to manually register the callbacks
System.out.println("parent size is " + pSize); if (playerAttributeTree.tree.get(newNode.GetNodeTitle()).currentNodeLevel != 0) {
playerAttributeTree.tree.get(newNode.GetNodeTitle()).thisNode.RegisterCallbacks();
}
} else { } else {
// Some fancy error handling for console log // Some fancy error handling for console log
if (nodeReference != null) { if (nodeReference != null) {

View File

@ -29,28 +29,50 @@ public class AttributeCommands {
// Command Root: "/attributes apply <username> <attribute name>" // Command Root: "/attributes apply <username> <attribute name>"
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("attributes") var attributeNode = CommandManager.literal("attributes").build();
.then(CommandManager.literal("apply")
.then(CommandManager.argument("username", EntityArgumentType.player())) var applySubnode = CommandManager.literal("apply").build();
.then(CommandManager.argument("attributeName", StringArgumentType.string()))
.executes(context -> ApplyAttribute( var playerArg = CommandManager.argument("targetPlayer", EntityArgumentType.player()).build();
EntityArgumentType.getPlayer(context, "username"),
var attributeNameArg = CommandManager.argument("attributeName", StringArgumentType.greedyString())
.executes(context -> ApplyAttribute
(
EntityArgumentType.getPlayer(context, "targetPlayer"),
StringArgumentType.getString(context, "attributeName"), StringArgumentType.getString(context, "attributeName"),
context context)
)))); )
.build();
// Build out the argument tree here
dispatcher.getRoot().addChild(attributeNode);
attributeNode.addChild(applySubnode);
applySubnode.addChild(playerArg);
playerArg.addChild(attributeNameArg);
}); });
// Command Root: "/attributes remove <username> <attribute name>" // Command Root: "/attributes remove <username> <attribute name>"
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("attributes") var attributeNode = CommandManager.literal("attributes").build();
.then(CommandManager.literal("delete")
.then(CommandManager.argument("username", EntityArgumentType.player())) var applySubnode = CommandManager.literal("delete").build();
.then(CommandManager.argument("attributeName", StringArgumentType.greedyString()))
.executes(context -> DeleteAttribute( var playerArg = CommandManager.argument("targetPlayer", EntityArgumentType.player()).build();
EntityArgumentType.getPlayer(context, "username"),
var attributeNameArg = CommandManager.argument("attributeName", StringArgumentType.greedyString())
.executes(context -> DeleteAttribute
(
EntityArgumentType.getPlayer(context, "targetPlayer"),
StringArgumentType.getString(context, "attributeName"), StringArgumentType.getString(context, "attributeName"),
context context)
)))); )
.build();
// Build out the argument tree here
dispatcher.getRoot().addChild(attributeNode);
attributeNode.addChild(applySubnode);
applySubnode.addChild(playerArg);
playerArg.addChild(attributeNameArg);
}); });
// Command Root: "/attribute-test <attribute_name>" // Command Root: "/attribute-test <attribute_name>"

View File

@ -10,6 +10,7 @@
package jesse.keeblarcraft.EventMgr; package jesse.keeblarcraft.EventMgr;
public class EventManager { public class EventManager {
} }

View File

@ -1,20 +1,21 @@
package jesse.keeblarcraft.Utils; package jesse.keeblarcraft.EventMgr;
import jesse.CommonServerUtils; import jesse.CommonServerUtils;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
//this lets get the MinecraftServer instance and also do stuff on the end of the tick if we wanted to // This interface is responsible for the end tick of a server world event tick
public class ServerTickListener implements ServerTickEvents.EndTick { public class ServerTickListener implements ServerTickEvents.EndTick {
CommonServerUtils config = new CommonServerUtils(); CommonServerUtils config = new CommonServerUtils();
@Override @Override
public void onEndTick(MinecraftServer server) { public void onEndTick(MinecraftServer server) {
//Code that runs on end of each tick yes this actually works and tested if (server != null) {
config.SetServerInstance(server); config.SetServerInstance(server);
} }
}
// Static method to register the server tick listener // Static method to register the server tick listener
public static void initialize() { public static void InitializeServerTicks() {
ServerTickEvents.END_SERVER_TICK.register(new ServerTickListener()); ServerTickEvents.END_SERVER_TICK.register(new ServerTickListener());
} }
} }

View File

@ -11,14 +11,17 @@ package jesse.keeblarcraft;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
// import net.minecraft.server.command.ServerCommandSource; // import net.minecraft.server.command.ServerCommandSource;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
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.Commands.CustomCommandManager; import jesse.keeblarcraft.Commands.CustomCommandManager;
import jesse.keeblarcraft.CustomBlocks.BlockManager; import jesse.keeblarcraft.CustomBlocks.BlockManager;
import jesse.keeblarcraft.CustomItems.ItemManager; import jesse.keeblarcraft.CustomItems.ItemManager;
import jesse.keeblarcraft.EventMgr.ServerTickListener;
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.ChatUtil;
import jesse.keeblarcraft.Utils.Setup; import jesse.keeblarcraft.Utils.Setup;
@ -28,9 +31,6 @@ import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
public class Keeblarcraft implements ModInitializer { public class Keeblarcraft implements ModInitializer {
// This logger is used to write text to the console and the log file.
// It is considered best practice to use your mod id as the logger's name.
// That way, it's clear which mod wrote info, warnings, and errors.
public static String MOD_ID = "keeblarcraft"; public static String MOD_ID = "keeblarcraft";
public static final Logger LOGGER = LoggerFactory.getLogger("keeblarcraft"); public static final Logger LOGGER = LoggerFactory.getLogger("keeblarcraft");
CustomCommandManager cmdMgr = new CustomCommandManager(); CustomCommandManager cmdMgr = new CustomCommandManager();
@ -50,6 +50,29 @@ public class Keeblarcraft implements ModInitializer {
LOGGER.info("\033[34m Running setup stage \033[0m"); LOGGER.info("\033[34m Running setup stage \033[0m");
setup.RunSetup(); setup.RunSetup();
// This is a very special case where this must be in this classes' initializer
// method
ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> {
var player = handler.player;
Keeblarcraft.LOGGER.info("Player " + player.getName() + " has logged in. Creating tree...");
if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == false) {
AttributeMgr.activeTrees.put(player.getUuidAsString(), new AttributeTree(player.getUuidAsString()));
}
});
ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> {
var player = handler.player;
Keeblarcraft.LOGGER.info("Player " + player.getName() + " has logged out. Deleting tree...");
if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == true) {
AttributeMgr.activeTrees.remove(player.getUuidAsString());
}
});
// Initialize our ticks!!
ServerTickListener.InitializeServerTicks();
// Run command registrations from the command manager // Run command registrations from the command manager
LOGGER.info("\033[34m Running command registration \033[0m"); LOGGER.info("\033[34m Running command registration \033[0m");
cmdMgr.RegisterCustomCommands(); cmdMgr.RegisterCustomCommands();

View File

@ -15,6 +15,7 @@ import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.EventMgr.ServerTickListener;
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR; import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_CREATE_EXCEPTION; import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_CREATE_EXCEPTION;
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION; import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
@ -155,21 +156,8 @@ public final class Setup {
throw new SETUP_FAILED_EXCEPTION(); throw new SETUP_FAILED_EXCEPTION();
} }
//testing for this
try {
onInitialize();
} catch (Exception e){
System.out.println(ChatUtil.ColoredString("servertick failed to inilize.", CONSOLE_COLOR.RED));
throw new SETUP_FAILED_EXCEPTION();
}
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))); 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;
} }
public void onInitialize() {
// Call the setup file to register event listeners and other setup tasks
ServerTickListener.initialize();
}
} }