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.AttributeMgr.AttributeNodes.AbstractNode;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AttributeFlight;
import jesse.keeblarcraft.AttributeMgr.AttributeNodes.AttributeMetalJacket;
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.Utils.ChatUtil;
import net.minecraft.server.network.ServerPlayerEntity;
public class AttributeMgr {
ConfigManager config;
// Global list of attributes
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")
public static void RegisterAttributeClass(Class<? extends AbstractNode> classObj) {
AbstractNode test;
@ -44,9 +51,10 @@ public class AttributeMgr {
public static String ApplyAttribute(String uuid, String attributeName) {
String msg = "";
if (attributes.containsKey(attributeName)) {
AttributeTree playerTree = new AttributeTree(uuid);
AttributeTree playerTree = activeTrees.get(uuid);
AbstractNode node = attributes.get(attributeName);
if (playerTree != null) {
///////////
// debug testing
String isNull = (node == null ? "NULL" : "NOT NULL");
@ -55,8 +63,11 @@ public class AttributeMgr {
// 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";
} else {
msg = "Player tree not found!";
}
} else {
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
RegisterAttributeClass(AttributeFlight.class);
RegisterAttributeClass(AttributeMetalJacket.class);
}
}

View File

@ -41,4 +41,12 @@ abstract public class AbstractNode {
/// attributes. 1 string per description
/////////////////////////////////////////////////////////////////////////////
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.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 AttributeFlight() {
}
@Override
@ -39,4 +45,19 @@ public class AttributeFlight extends AbstractNode {
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;
}
@Override
public void RegisterCallbacks() {
}
}

View File

@ -11,6 +11,7 @@ package jesse.keeblarcraft.AttributeMgr;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.HashMap;
import jesse.keeblarcraft.Keeblarcraft;
@ -47,6 +48,23 @@ public class AttributeTree {
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
private class PlayerTree {
String uuid;
@ -74,6 +92,10 @@ public class AttributeTree {
return ret;
}
@Override
public void RegisterCallbacks() {
}
}
// Add a new node to the tree arbitrarily
@ -104,18 +126,17 @@ public class AttributeTree {
parents = (parents == null ? new ArrayList<String>() : parents);
children = (children == null ? new ArrayList<String>() : children);
System.out.println("Parent size: " + parents.size());
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
}
System.out.println("Parents size: " + parents.size());
// Node implementation here
playerAttributeTree.tree.put(newNode.GetNodeTitle(), new TreeNode(newNode, maxNodeLevel, parents, children));
long pSize = playerAttributeTree.tree.get(newNode.GetNodeTitle()).parentNodes.size();
System.out.println("parent size is " + pSize);
// if the new nodes level is not 0 we need to manually register the callbacks
if (playerAttributeTree.tree.get(newNode.GetNodeTitle()).currentNodeLevel != 0) {
playerAttributeTree.tree.get(newNode.GetNodeTitle()).thisNode.RegisterCallbacks();
}
} else {
// Some fancy error handling for console log
if (nodeReference != null) {

View File

@ -29,28 +29,50 @@ public class AttributeCommands {
// Command Root: "/attributes apply <username> <attribute name>"
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("attributes")
.then(CommandManager.literal("apply")
.then(CommandManager.argument("username", EntityArgumentType.player()))
.then(CommandManager.argument("attributeName", StringArgumentType.string()))
.executes(context -> ApplyAttribute(
EntityArgumentType.getPlayer(context, "username"),
var attributeNode = CommandManager.literal("attributes").build();
var applySubnode = CommandManager.literal("apply").build();
var playerArg = CommandManager.argument("targetPlayer", EntityArgumentType.player()).build();
var attributeNameArg = CommandManager.argument("attributeName", StringArgumentType.greedyString())
.executes(context -> ApplyAttribute
(
EntityArgumentType.getPlayer(context, "targetPlayer"),
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>"
CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> {
dispatcher.register(CommandManager.literal("attributes")
.then(CommandManager.literal("delete")
.then(CommandManager.argument("username", EntityArgumentType.player()))
.then(CommandManager.argument("attributeName", StringArgumentType.greedyString()))
.executes(context -> DeleteAttribute(
EntityArgumentType.getPlayer(context, "username"),
var attributeNode = CommandManager.literal("attributes").build();
var applySubnode = CommandManager.literal("delete").build();
var playerArg = CommandManager.argument("targetPlayer", EntityArgumentType.player()).build();
var attributeNameArg = CommandManager.argument("attributeName", StringArgumentType.greedyString())
.executes(context -> DeleteAttribute
(
EntityArgumentType.getPlayer(context, "targetPlayer"),
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>"

View File

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

View File

@ -1,20 +1,21 @@
package jesse.keeblarcraft.Utils;
package jesse.keeblarcraft.EventMgr;
import jesse.CommonServerUtils;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
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 {
CommonServerUtils config = new CommonServerUtils();
@Override
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);
}
}
// Static method to register the server tick listener
public static void initialize() {
public static void InitializeServerTicks() {
ServerTickEvents.END_SERVER_TICK.register(new ServerTickListener());
}
}

View File

@ -11,14 +11,17 @@ package jesse.keeblarcraft;
import net.fabricmc.api.ModInitializer;
// import net.minecraft.server.command.ServerCommandSource;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jesse.keeblarcraft.AttributeMgr.AttributeMgr;
import jesse.keeblarcraft.AttributeMgr.AttributeTree;
import jesse.keeblarcraft.Commands.CustomCommandManager;
import jesse.keeblarcraft.CustomBlocks.BlockManager;
import jesse.keeblarcraft.CustomItems.ItemManager;
import jesse.keeblarcraft.EventMgr.ServerTickListener;
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
import jesse.keeblarcraft.Utils.ChatUtil;
import jesse.keeblarcraft.Utils.Setup;
@ -28,9 +31,6 @@ import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
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 final Logger LOGGER = LoggerFactory.getLogger("keeblarcraft");
CustomCommandManager cmdMgr = new CustomCommandManager();
@ -50,6 +50,29 @@ public class Keeblarcraft implements ModInitializer {
LOGGER.info("\033[34m Running setup stage \033[0m");
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
LOGGER.info("\033[34m Running command registration \033[0m");
cmdMgr.RegisterCustomCommands();

View File

@ -15,6 +15,7 @@ import java.util.List;
import java.util.ArrayList;
import jesse.keeblarcraft.ConfigMgr.ConfigManager;
import jesse.keeblarcraft.EventMgr.ServerTickListener;
import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR;
import jesse.keeblarcraft.Utils.CustomExceptions.DIRECTORY_CREATE_EXCEPTION;
import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION;
@ -155,21 +156,8 @@ public final class Setup {
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)));
return ret;
}
public void onInitialize() {
// Call the setup file to register event listeners and other setup tasks
ServerTickListener.initialize();
}
}