From 30ec13335866780370fcff6f024a731297bab6c8 Mon Sep 17 00:00:00 2001 From: Jkibbels Date: Fri, 29 Nov 2024 04:00:14 -0500 Subject: [PATCH] last minute pre-ship stuff --- installmod.sh | 3 +- .../27b8b1d6af601e15f202616061490ff2b85aa40c | 3 + .../Commands/CustomCommandManager.java | 2 + .../keeblarcraft/Commands/MiscCommands.java | 164 ++++++++++++++++++ .../keeblarcraft/ConfigMgr/ConfigManager.java | 22 ++- .../keeblarcraft/ConfigMgr/GeneralConfig.java | 102 +++++++++++ .../BlockEntities/MagicChestBlockEntity.java | 86 +++++++++ .../CustomBlocks/Blocks/MagicChestBlock.java | 43 +++++ .../EventMgr/DimensionLoadingEvent.java | 148 ++++++++++------ .../EventMgr/PlayerJoinListener.java | 57 ++++++ .../java/jesse/keeblarcraft/Keeblarcraft.java | 31 +++- .../keeblarcraft/Utils/DirectionalVec.java | 14 ++ .../world/ImplementedInventory.java | 138 +++++++++++++++ 13 files changed, 747 insertions(+), 66 deletions(-) create mode 100644 src/main/generated/.cache/27b8b1d6af601e15f202616061490ff2b85aa40c create mode 100644 src/main/java/jesse/keeblarcraft/Commands/MiscCommands.java create mode 100644 src/main/java/jesse/keeblarcraft/ConfigMgr/GeneralConfig.java create mode 100644 src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/MagicChestBlockEntity.java create mode 100644 src/main/java/jesse/keeblarcraft/CustomBlocks/Blocks/MagicChestBlock.java create mode 100644 src/main/java/jesse/keeblarcraft/EventMgr/PlayerJoinListener.java create mode 100644 src/main/java/jesse/keeblarcraft/Utils/DirectionalVec.java create mode 100644 src/main/java/jesse/keeblarcraft/world/ImplementedInventory.java diff --git a/installmod.sh b/installmod.sh index d540e99..f2e4c7b 100755 --- a/installmod.sh +++ b/installmod.sh @@ -1,4 +1,5 @@ #!/bin/bash rm ~/.minecraft/mods/keeblarcraft* # What else could be named this? Really now? cp build/libs/keeblarcraft-0.0.1.jar ~/.minecraft/mods -echo Moved minecraft to mods dir \ No newline at end of file +cp build/libs/keeblarcraft-0.0.1.jar run/mods +echo Moved minecraft to mods dir diff --git a/src/main/generated/.cache/27b8b1d6af601e15f202616061490ff2b85aa40c b/src/main/generated/.cache/27b8b1d6af601e15f202616061490ff2b85aa40c new file mode 100644 index 0000000..1b4f5fe --- /dev/null +++ b/src/main/generated/.cache/27b8b1d6af601e15f202616061490ff2b85aa40c @@ -0,0 +1,3 @@ +// 1.20 2024-11-28T23:06:30.379882793 keeblarcraft/Keeblarcraft World Generation +afc3340283d1101601bd4d2ca96341a58eceaf83 data/keeblarcraft/dimension_type/keeblarcraftdim_type.json +4398eda2b0c28b2c754c45f5805534bf1921b243 data/keeblarcraft/worldgen/biome/test_biome.json diff --git a/src/main/java/jesse/keeblarcraft/Commands/CustomCommandManager.java b/src/main/java/jesse/keeblarcraft/Commands/CustomCommandManager.java index bdb91bf..9ffb9ba 100644 --- a/src/main/java/jesse/keeblarcraft/Commands/CustomCommandManager.java +++ b/src/main/java/jesse/keeblarcraft/Commands/CustomCommandManager.java @@ -23,6 +23,7 @@ public class CustomCommandManager { BankCommands bankCommands = new BankCommands(); AttributeCommands attributeCommands = new AttributeCommands(); FactionCommands factionCommands = new FactionCommands(); + MiscCommands miscCommands = new MiscCommands(); // REGISTER COMMANDS BELOW System.out.println(ChatUtil.ColoredString("REGISTERING CUSTOM COMMAND EXTENSIONS BELOW", CONSOLE_COLOR.BLUE)); @@ -31,5 +32,6 @@ public class CustomCommandManager { bankCommands.RegisterCommands(); attributeCommands.RegisterCommands(); factionCommands.RegisterFactionCommands(); + miscCommands.RegisterCommands(); } } diff --git a/src/main/java/jesse/keeblarcraft/Commands/MiscCommands.java b/src/main/java/jesse/keeblarcraft/Commands/MiscCommands.java new file mode 100644 index 0000000..ecb3251 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/Commands/MiscCommands.java @@ -0,0 +1,164 @@ +package jesse.keeblarcraft.Commands; + +import org.apache.logging.log4j.core.jmx.Server; + +import com.mojang.brigadier.arguments.StringArgumentType; + +import jesse.keeblarcraft.Keeblarcraft; +import jesse.keeblarcraft.ConfigMgr.ConfigManager; +import jesse.keeblarcraft.ConfigMgr.GeneralConfig; +import jesse.keeblarcraft.EventMgr.DimensionLoadingEvent; +import jesse.keeblarcraft.Utils.DirectionalVec; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.ChestBlock; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.command.argument.EntityArgumentType; +import net.minecraft.inventory.EnderChestInventory; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.nbt.NbtList; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraft.world.dimension.DimensionType; + +public class MiscCommands { + ConfigManager config = new ConfigManager(); + + public void RegisterCommands() { + // CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + + // var magicInv = CommandManager.literal("magic-inv").build(); + // var claim = CommandManager.literal("claim").executes(context -> ClaimInventory(context.getSource().getPlayer())).build(); + + // dispatcher.getRoot().addChild(magicInv); + // magicInv.addChild(claim); + // }); + + // CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + + // var eChest = CommandManager.literal("enderchest").build(); + // var player = CommandManager.argument("PLAYER", EntityArgumentType.player()).executes( + // context -> GetEnderchestOfPlayer(context.getSource().getPlayer(), EntityArgumentType.getPlayer(context, "PLAYER")) + // ).build(); + + // dispatcher.getRoot().addChild(eChest); + // eChest.addChild(player); + + // // Alias + // dispatcher.register(CommandManager.literal("echest").redirect(eChest)); + // }); + + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + + var forceSpawn = CommandManager.literal("set-global-spawn").executes(context -> ForceGlobalSpawn(context.getSource().getPlayer())).build(); + + dispatcher.getRoot().addChild(forceSpawn); + }); + + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { + + var warp = CommandManager.literal("warp").build(); + + var warpLoc = CommandManager.argument("LOCATION", StringArgumentType.string()) + .executes(context -> Warp(context.getSource().getPlayer(), StringArgumentType.getString(context, "LOCATION"))).build(); + + dispatcher.getRoot().addChild(warp); + warp.addChild(warpLoc); + }); + } + + public int Warp(ServerPlayerEntity player, String location) { + + if (player.hasPermissionLevel(4)) { + // hard coding spawn as only valid warp location. a more robust warp system can come later + DirectionalVec coords = GeneralConfig.GetInstance().GetSpawnCoords(); + var server = player.getServer(); + + System.out.println("Warping! Is server null? " + (server == null ? "YES":"NO")); + System.out.println("Vakye if coords.x: " + coords.x); + System.out.println("Value of coords.world: " + coords.world.toString()); + player.teleport(server.getWorld(coords.world), (float)coords.x, (float)coords.y, + (float)coords.z, (float)coords.yaw, (float)coords.pitch); + } else { + player.sendMessage(Text.of("This command is only available to server admins at the moment!")); + } + + return 0; + } + + public int ForceGlobalSpawn(ServerPlayerEntity player) { + if (player.hasPermissionLevel(4)) { + Vec3d coords = player.getPos(); + DirectionalVec spawnVec = new DirectionalVec(); + spawnVec.x = coords.x; + spawnVec.y = coords.y; + spawnVec.z = coords.z; + spawnVec.pitch = player.getPitch(); + spawnVec.yaw = player.getYaw(); + spawnVec.world = player.getWorld().getRegistryKey(); + player.sendMessage(Text.of("Global spawn has been set to [X, Y, Z]--[YAW, PITCH]: [" + + spawnVec.x + " " + spawnVec.y + " " + spawnVec.z + "]--" + "[" + spawnVec.yaw + " " + spawnVec.pitch + "]" + " IN WORLD " + + player.getWorld().asString())); + + GeneralConfig.GetInstance().SetSpawnCoords(spawnVec); + } else { + player.sendMessage(Text.of("You do not have permission to use this command.")); + } + + return 0; + } + + public int GetEnderchestOfPlayer(ServerPlayerEntity cmdInitiator, ServerPlayerEntity targetPlayer) { + + // if (cmdInitiator.hasPermissionLevel(4)) { + // EnderChestInventory enderInv = targetPlayer.getEnderChestInventory(); + // enderInv. + + // } else { + + // } + + return 0; + } + + // public int ClaimInventory(ServerPlayerEntity player) { + // Vec3d playerPosition = player.getPos(); + // BlockPos blockPosition = new BlockPos((int) playerPosition.x + 4, (int) playerPosition.y, (int) playerPosition.z).east(); + // BlockPos blockPosition2 = new BlockPos((int) playerPosition.x + 3, (int) playerPosition.y, (int) playerPosition.z).east(); + + + // // Verify we can place the blocks before loading cached inventory + // if (player.getWorld().setBlockState(blockPosition, chestState) + // && player.getWorld().setBlockState(blockPosition2, chestState)) { + + // // The below code WILL remove the inventory from the dimension cache. Only get + // // it when we succeed in placing chests! + // NbtList nbtInventory = DimensionLoadingEvent.GetInstance().GetInventory(player.getUuidAsString()); + // if (nbtInventory != null) { + // BlockEntity block = player.getWorld().getBlockEntity(blockPosition); + // BlockEntity block2 = player.getWorld().getBlockEntity(blockPosition2); + + // if (block != null && block2 != null) { + // block.markDirty(); + // block2.markDirty(); + // } + + // player.sendMessage(Text.of("Look around, your magic inventory chest was placed near you!")); + // } + // } else { + // player.sendMessage(Text.of("Well, this is embarassing! Could not place magic inventory chest near you!")); + // } + + // return 0; + // } +} diff --git a/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java b/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java index b727b41..8554cea 100644 --- a/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java +++ b/src/main/java/jesse/keeblarcraft/ConfigMgr/ConfigManager.java @@ -32,6 +32,9 @@ import java.util.ArrayList; 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.NbtIo; +import net.minecraft.nbt.NbtList; public class ConfigManager { @@ -87,6 +90,22 @@ public class ConfigManager { return ret; } + // Writes NBT (binary?) data to a file + public void WriteNbtListToFile(String fileName, NbtList data) { + fileName = "config/keeblarcraft/" + fileName; + + File file = new File(fileName); + + try { + for (int i = 0; i < data.size(); i++) { + NbtIo.write(data.getCompound(i), file); + } + } catch (IOException e) { + System.out.println("In an attempt to write nbt list to file we encountered an error..."); + e.printStackTrace(); + } + } + // WriteToFile // // Will write or append to file (valid modes: "w" or "a") if file is available. Returns false if not @@ -137,7 +156,7 @@ public class ConfigManager { writer.flush(); writer.close(); } catch (JsonIOException | IOException e) { - System.out.println(ChatUtil.ColoredString("Could not successfully write to json file", CONSOLE_COLOR.RED)); + System.out.println(ChatUtil.ColoredString("Could not successfully write to json file [" + fileName + "]", CONSOLE_COLOR.RED)); throw new FILE_WRITE_EXCEPTION(); } } @@ -149,6 +168,7 @@ public class ConfigManager { Gson gson = new Gson(); 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 // return value in the future - but for now throw JsonSyntaxException no matter what exception is caught diff --git a/src/main/java/jesse/keeblarcraft/ConfigMgr/GeneralConfig.java b/src/main/java/jesse/keeblarcraft/ConfigMgr/GeneralConfig.java new file mode 100644 index 0000000..143ff98 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/ConfigMgr/GeneralConfig.java @@ -0,0 +1,102 @@ +package jesse.keeblarcraft.ConfigMgr; + +import java.util.ArrayList; +import java.util.List; + +import jesse.keeblarcraft.Utils.DirectionalVec; +import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION; + +public class GeneralConfig { + private static GeneralConfig static_inst; + ConfigManager cfgMgr = new ConfigManager(); + private ImplementedConfig config; + + public static GeneralConfig GetInstance() { + if (static_inst == null) { + static_inst = new GeneralConfig(); + } + + return static_inst; + } + + // Guarentee to not be null + public ImplementedConfig GetConfig() { + if (config == null) { + config = new ImplementedConfig(); + FlashConfig(); + } + + return config; + } + + public GeneralConfig() { + Boolean existingFile = false; + try { + config = cfgMgr.GetJsonObjectFromFile("general.json", ImplementedConfig.class); + + System.out.println("Read in config. Random value: " + config.global_spawn.x); + existingFile = true; + } catch(Exception e) { + System.out.println("FAILED TO READ IN GENERALCONFIG"); + e.printStackTrace(); + } + + if (!existingFile) { + config = new ImplementedConfig(); + FlashConfig(); + } + + if (config == null) { + config = new ImplementedConfig(); + FlashConfig(); + } + } + + // Can return null; if null then do not spawn the player because global spawn wasn't set! + public DirectionalVec GetSpawnCoords() { + System.out.println("GetSpawnCoords called. is global_spawn null? " + (config.global_spawn == null ? "YES": "NO")); + return config.global_spawn; + } + + public void SetSpawnCoords(DirectionalVec vec) { + config.global_spawn = vec; + FlashConfig(); + } + + // The idea behind this function is a one time check option. If you have the UUID, they must now be joining + // so we wrap adding them to the list in one check + public Boolean IsNewPlayer(String uuid) { + System.out.println("IsNewPlayer called. List has: " + config.playerList); + Boolean isNew = !config.playerList.contains(uuid); + + System.out.println("Value of isNew is " + isNew); + + if (isNew) { + config.playerList.add(uuid); + FlashConfig(); + } + return isNew; + } + + public String GetMOTD() { + return config.MOTD; + } + + private class ImplementedConfig { + public String MOTD = "Welcome to the server! Have fun!"; + + // This is lazy, but this will fill with every unique UUID that has joined the server. This is how I am checking + // to see if a player has just joined the server for a first time or not + public List playerList = new ArrayList<>(); + DirectionalVec global_spawn; + } + + private void FlashConfig() { + System.out.println("Attempting to write generalconfig to file. Is null? " + (config == null ? "YES" : "NO")); + try { + cfgMgr.WriteToJsonFile("general.json", config); + } catch (FILE_WRITE_EXCEPTION e) { + System.out.println("Caught FileWriteException from general config writing. uh oh!"); + } + } +} diff --git a/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/MagicChestBlockEntity.java b/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/MagicChestBlockEntity.java new file mode 100644 index 0000000..91ebeed --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/CustomBlocks/BlockEntities/MagicChestBlockEntity.java @@ -0,0 +1,86 @@ +// package jesse.keeblarcraft.CustomBlocks.BlockEntities; + +// import jesse.keeblarcraft.Keeblarcraft; +// import jesse.keeblarcraft.CustomBlocks.BlockManager; +// import jesse.keeblarcraft.world.ImplementedInventory; + +// import net.minecraft.block.BlockState; +// import net.minecraft.block.entity.BlockEntity; +// import net.minecraft.entity.player.PlayerEntity; +// import net.minecraft.entity.player.PlayerInventory; +// import net.minecraft.inventory.Inventories; +// import net.minecraft.item.ItemStack; +// import net.minecraft.nbt.NbtCompound; +// import net.minecraft.registry.RegistryWrapper; +// import net.minecraft.screen.NamedScreenHandlerFactory; +// import net.minecraft.screen.PropertyDelegate; // for syncing client + server +// import net.minecraft.screen.ScreenHandler; +// import net.minecraft.text.Text; +// import net.minecraft.util.collection.DefaultedList; +// import net.minecraft.util.math.BlockPos; + +// public class MagicChestBlockEntity extends BlockEntity implements NamedScreenHandlerFactory, ImplementedInventory { +// private final DefaultedList inventory = DefaultedList.ofSize(256, ItemStack.EMPTY); + +// protected final PropertyDelegate propertyDelegate; +// private int progress = 0; +// private int maxProgress = 72; + +// public MagicChestBlockEntity(BlockPos pos, BlockState state) { +// super(Keeblarcraft.MAGIC_CHEST_BLOCK_ENTITY, pos, state); +// this.propertyDelegate = new PropertyDelegate() { + +// @Override +// public int get(int index) { +// return switch(index) { +// case 0 -> MagicChestBlockEntity.this.progress; +// case 1 -> MagicChestBlockEntity.this.maxProgress; +// default -> 0; +// }; +// } + +// @Override +// public void set(int index, int value) { +// switch (index) { +// case 0 -> MagicChestBlockEntity.this.progress = value; +// case 1 -> MagicChestBlockEntity.this.maxProgress = value; +// }; +// } + +// // MUST be size of how many integers we are synchronizing +// @Override +// public int size() { +// return 2; +// } + +// }; +// } + +// @Override +// public ScreenHandler createMenu(int syncId, PlayerInventory playerInventory, PlayerEntity player) { +// // Screen handler will sync the inventory +// return new MagicChestScreenHandler(syncId, playerInventory, this); +// } + +// @Override +// public DefaultedList getItems() { +// return inventory; +// } + +// @Override +// public Text getDisplayName() { +// return Text.translatable(getCachedState().getBlock().getTranslationKey()); +// } + +// @Override +// public void readNbt(NbtCompound nbt) { +// super.readNbt(nbt); +// Inventories.readNbt(nbt, this.inventory); +// } + +// @Override +// public void writeNbt(NbtCompound nbt) { +// super.writeNbt(nbt); +// Inventories.writeNbt(nbt, this.inventory); +// } +// } diff --git a/src/main/java/jesse/keeblarcraft/CustomBlocks/Blocks/MagicChestBlock.java b/src/main/java/jesse/keeblarcraft/CustomBlocks/Blocks/MagicChestBlock.java new file mode 100644 index 0000000..ad0f541 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/CustomBlocks/Blocks/MagicChestBlock.java @@ -0,0 +1,43 @@ +// package jesse.keeblarcraft.CustomBlocks.Blocks; + +// import jesse.keeblarcraft.CustomBlocks.BlockEntities.MagicChestBlockEntity; +// import net.minecraft.block.BlockRenderType; +// import net.minecraft.block.BlockState; +// import net.minecraft.block.BlockWithEntity; +// import net.minecraft.block.entity.BlockEntity; +// import net.minecraft.entity.player.PlayerEntity; +// import net.minecraft.screen.NamedScreenHandlerFactory; +// import net.minecraft.util.ActionResult; +// import net.minecraft.util.Hand; +// import net.minecraft.util.hit.BlockHitResult; +// import net.minecraft.util.math.BlockPos; +// import net.minecraft.world.World; + +// public class MagicChestBlock extends BlockWithEntity { +// public MagicChestBlock(Settings settings) { +// super(settings); +// } + +// @Override +// public BlockEntity createBlockEntity(BlockPos pos, BlockState state) { +// return new MagicChestBlockEntity(pos, state); +// } + +// @Override +// public BlockRenderType getRenderType(BlockState state) { +// return BlockRenderType.MODEL; +// } + +// @Override +// public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { +// if (!world.isClient) { +// NamedScreenHandlerFactory screenHandlerFactory = ((MagicChestBlockEntity) world.getBlockEntity(pos)); + +// if (screenHandlerFactory != null) { +// player.openHandledScreen(screenHandlerFactory); +// } +// } + +// return ActionResult.SUCCESS; +// } +// } diff --git a/src/main/java/jesse/keeblarcraft/EventMgr/DimensionLoadingEvent.java b/src/main/java/jesse/keeblarcraft/EventMgr/DimensionLoadingEvent.java index 87536f5..79e0d50 100644 --- a/src/main/java/jesse/keeblarcraft/EventMgr/DimensionLoadingEvent.java +++ b/src/main/java/jesse/keeblarcraft/EventMgr/DimensionLoadingEvent.java @@ -3,23 +3,30 @@ package jesse.keeblarcraft.EventMgr; import java.util.HashMap; import java.util.Map.Entry; -import javax.naming.InvalidNameException; - import jesse.keeblarcraft.ConfigMgr.ConfigManager; import jesse.keeblarcraft.Utils.ChatUtil; import jesse.keeblarcraft.Utils.ChatUtil.CONSOLE_COLOR; import jesse.keeblarcraft.Utils.CustomExceptions.FILE_WRITE_EXCEPTION; import jesse.keeblarcraft.world.dimension.ModDimensions; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtList; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.Text; public class DimensionLoadingEvent { + private static DimensionLoadingEvent static_inst; + + public static DimensionLoadingEvent GetInstance() { + if (static_inst == null) { + static_inst = new DimensionLoadingEvent(); + } + + return static_inst; + } - // private static List inventories = new ArrayList(); private static class InventoryWrapper { - public HashMap inventories = new HashMap(); + public HashMap inventories = new HashMap(); } private static InventoryWrapper iw = new InventoryWrapper(); @@ -29,72 +36,99 @@ public class DimensionLoadingEvent { public DimensionLoadingEvent() { // read config - Boolean existingFile = false; - try { - iw = config.GetJsonObjectFromFile(CONFIG_LOCATION, InventoryWrapper.class); - existingFile = true; - } catch (Exception e) { - // Do nothing. This means the file does not exist - } + // Boolean existingFile = false; + // try { + // iw = config.GetJsonObjectFromFile(CONFIG_LOCATION, InventoryWrapper.class); - // In the event the above code failed out, this means a new file has to be created for the player's uuid - if (!existingFile) - { - System.out.println(ChatUtil.ColoredString("Trying to create new file", CONSOLE_COLOR.BLUE)); - try { - FlashConfig(); - } catch (Exception e) { - System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED)); - } - } else { - System.out.println(ChatUtil.ColoredString("Moving on", CONSOLE_COLOR.BLUE)); - } + // for (Entry entry : iw.inventories.entrySet()) { + // System.out.println("Found entry for UUID " + entry.getKey()); + // } + // System.out.println("Size of iw.inventories: " + iw.inventories.size()); + + // System.out.println("Json object was found!"); + // existingFile = true; + // } catch (Exception e) { + // System.out.println("Exception was raised when reading json file for stuff"); + // e.printStackTrace(); + // // 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 + // if (!existingFile) + // { + // System.out.println("Creating new file"); + // System.out.println(ChatUtil.ColoredString("Trying to create new file", CONSOLE_COLOR.BLUE)); + // try { + // FlashConfig(); + // } catch (Exception e) { + // System.out.println(ChatUtil.ColoredString("Could not write to file", CONSOLE_COLOR.RED)); + // } + // } else { + // System.out.println(ChatUtil.ColoredString("Moving on", CONSOLE_COLOR.BLUE)); + // } } // TODO: In the future when the attribute system is more complete this will need to filter a whitelist of items // from the that system + story mode because some items will be able to transcend dimensions! - public static void HandleWorldMove(ServerPlayerEntity player, ServerWorld origin, ServerWorld destination) { - if (destination.getDimensionEntry().matchesKey(ModDimensions.KEEBLAR_DIM_TYPE)) { - // Make sure player is in map. For now we only care about storing OVERWORLD inventory. We DO NOT care about - // the dimension inventory! - if (!iw.inventories.containsKey(player.getUuidAsString())) { - PlayerInventory copyInv = new PlayerInventory(player); - copyInv.clone(player.getInventory()); - iw.inventories.put(player.getUuidAsString(), copyInv); - player.getInventory().clear(); - } else { - System.out.println("Player in system. Ignoring"); - } - } else if (origin.getDimensionEntry().matchesKey(ModDimensions.KEEBLAR_DIM_TYPE)) { - if (iw.inventories.containsKey(player.getUuidAsString())) { - System.out.println("Player is in map. Cloning our inventory back to them..."); - player.getInventory().clone(iw.inventories.get(player.getUuidAsString())); - iw.inventories.remove(player.getUuidAsString()); - } else { - System.out.println("Player not in system. Ignoring"); - } - } else { - System.out.println("dest TYPE - KEY" + destination.getDimensionEntry().getType().toString() + " -- " + destination.getDimensionEntry().getKey().toString()); - System.out.println("orig TYPE - KEY: " + origin.getDimensionEntry().getType().toString() + " -- "+ origin.getDimensionEntry().getKey().toString()); - } + public void HandleWorldMove(ServerPlayerEntity player, ServerWorld origin, ServerWorld destination) { + // System.out.println("World move event called!"); + // if (destination.getDimensionEntry().matchesKey(ModDimensions.KEEBLAR_DIM_TYPE)) { + // // Make sure player is in map. For now we only care about storing OVERWORLD inventory. We DO NOT care about + // // the dimension inventory! + // System.out.println("Trying to locate player in inventory map. Player uuid is " + player.getUuidAsString()); + // if (!iw.inventories.containsKey(player.getUuidAsString())) { + // // Copy the nbt into the list + // NbtList inventoryNbt = new NbtList(); + // player.getInventory().writeNbt(inventoryNbt); + + // iw.inventories.put(player.getUuidAsString(), inventoryNbt); + // player.getInventory().clear(); + // } else { + // System.out.println("Player in system. Ignoring"); + // } + // } else if (origin.getDimensionEntry().matchesKey(ModDimensions.KEEBLAR_DIM_TYPE)) { + // if (iw.inventories.containsKey(player.getUuidAsString())) { + // System.out.println("Player is in map. Cloning our inventory back to them..."); + // player.getInventory().readNbt(iw.inventories.get(player.getUuidAsString())); + // iw.inventories.remove(player.getUuidAsString()); + // } else { + // System.out.println("Player not in system. Ignoring"); + // } + // } else { + // System.out.println("dest TYPE - KEY" + destination.getDimensionEntry().getType().toString() + " -- " + destination.getDimensionEntry().getKey().toString()); + // System.out.println("orig TYPE - KEY: " + origin.getDimensionEntry().getType().toString() + " -- "+ origin.getDimensionEntry().getKey().toString()); + // } + + // FlashConfig(); } // needs to be tested - public static void ResetInventories() { - System.out.println("ResetInventories: inventory size: " + iw.inventories.size()); - for (Entry entry : iw.inventories.entrySet()) { - PlayerEntity player = entry.getValue().player; + public void SaveInventories() { + System.out.println("Call to save inventories. Flashing IW.Inventories with size " + iw.inventories.size()); + FlashConfig(); + } - System.out.println("Found PlayerEntity"); - player.getInventory().clone(entry.getValue()); + public void CheckPlayer(ServerPlayerEntity player) { + // Check the players logged in world. If they are logging into the overworld - we need to see if they are in our + // map and give them the inventory back + if ((!player.getWorld().getDimensionEntry().matchesKey(ModDimensions.KEEBLAR_DIM_TYPE)) && iw.inventories.containsKey(player.getUuidAsString())) { + // We need to store the contents of the nbt into a regular inventory and magical chest and give it back to the player + player.sendMessage(Text.of("[IMPORTANT]: It appears you have a saved inventory of items on the server! You can claim it with /magic-inventory claim")); } } + // Fetches an inventory from this list. Use MagicInventory to store it along the transfer way! + public NbtList GetInventory(String uuid) { + NbtList nbt = iw.inventories.get(uuid); + iw.inventories.remove(uuid); + return nbt; + } + public void FlashConfig() { try { - config.WriteToJsonFile(CONFIG_LOCATION, iw.inventories); + config.WriteToJsonFile(CONFIG_LOCATION, iw); } catch (FILE_WRITE_EXCEPTION e) { - System.out.println(ChatUtil.ColoredString("Could not flash notes configuration file", CONSOLE_COLOR.RED)); + System.out.println(ChatUtil.ColoredString("Could not flash dimension loading configuration file", CONSOLE_COLOR.RED)); } } } diff --git a/src/main/java/jesse/keeblarcraft/EventMgr/PlayerJoinListener.java b/src/main/java/jesse/keeblarcraft/EventMgr/PlayerJoinListener.java new file mode 100644 index 0000000..3009488 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/EventMgr/PlayerJoinListener.java @@ -0,0 +1,57 @@ +package jesse.keeblarcraft.EventMgr; + +import jesse.keeblarcraft.AttributeMgr.AttributeMgr; +import jesse.keeblarcraft.AttributeMgr.AttributeTree; +import jesse.keeblarcraft.ConfigMgr.ConfigManager; +import jesse.keeblarcraft.ConfigMgr.GeneralConfig; +import jesse.keeblarcraft.Utils.DirectionalVec; +import net.fabricmc.fabric.api.networking.v1.PacketSender; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.Text; + +public class PlayerJoinListener { + private static PlayerJoinListener static_inst; + private ConfigManager config = new ConfigManager(); + + public static PlayerJoinListener GetInstance() { + if (static_inst == null) { + static_inst = new PlayerJoinListener(); + } + return static_inst; + } + + public void HandleServerJoinEvent(ServerPlayNetworkHandler handler, PacketSender sender, MinecraftServer server) { + var player = handler.player; + + // Handle skill tree map instance + if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == false) { + AttributeMgr.activeTrees.put(player.getUuidAsString(), new AttributeTree(player.getUuidAsString())); + } + + // Handle first time joining events (world spawn teleport, MOTD, etc) + System.out.println("Running first time login stuff"); + IsFirstTimeLogin(player, server); + } + + private void IsFirstTimeLogin(ServerPlayerEntity player, MinecraftServer server) { + // Send the MOTD + Spawn in global spawn + player.sendMessage(Text.of(GeneralConfig.GetInstance().GetMOTD())); + if (GeneralConfig.GetInstance().IsNewPlayer(player.getUuidAsString())) { + DirectionalVec coords = GeneralConfig.GetInstance().GetSpawnCoords(); + if (coords != null) { + System.out.println("Coords is not null"); + System.out.println("Coords world key: " + server.getWorld(coords.world).asString()); + player.teleport(server.getWorld(coords.world), (float)coords.x, (float)coords.y, + (float)coords.z, (float)coords.yaw, (float)coords.pitch); + } else { + System.out.println("Coords is a null object"); + System.out.println("Coords were null. Not warping player"); + } + } else { + System.out.println("Not a new player! Not running anything"); + } + } +} diff --git a/src/main/java/jesse/keeblarcraft/Keeblarcraft.java b/src/main/java/jesse/keeblarcraft/Keeblarcraft.java index a1fbe7b..5360ce4 100644 --- a/src/main/java/jesse/keeblarcraft/Keeblarcraft.java +++ b/src/main/java/jesse/keeblarcraft/Keeblarcraft.java @@ -18,7 +18,10 @@ 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.kyrptonaught.customportalapi.api.CustomPortalBuilder; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; import net.minecraft.block.Blocks; +import net.minecraft.block.entity.BlockEntityType; import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerInventory; @@ -27,6 +30,7 @@ import net.minecraft.registry.Registries; import net.minecraft.registry.Registry; import net.minecraft.resource.featuretoggle.FeatureSet; import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.text.Text; import net.minecraft.util.Identifier; import org.slf4j.Logger; @@ -37,8 +41,11 @@ import jesse.keeblarcraft.AttributeMgr.AttributeTree; import jesse.keeblarcraft.BankMgr.BankManager; import jesse.keeblarcraft.Commands.CustomCommandManager; import jesse.keeblarcraft.CustomBlocks.BlockList; +// import jesse.keeblarcraft.CustomBlocks.BlockEntities.MagicChestBlockEntity; +// import jesse.keeblarcraft.CustomBlocks.Blocks.MagicChestBlock; import jesse.keeblarcraft.CustomItems.ItemManager; import jesse.keeblarcraft.EventMgr.DimensionLoadingEvent; +import jesse.keeblarcraft.EventMgr.PlayerJoinListener; import jesse.keeblarcraft.EventMgr.ServerTickListener; import jesse.keeblarcraft.GuiMgr.TreeHandler; import jesse.keeblarcraft.Utils.CustomExceptions.SETUP_FAILED_EXCEPTION; @@ -56,6 +63,12 @@ public class Keeblarcraft implements ModInitializer { Identifier.of(Keeblarcraft.MOD_ID, "tree_gui"), new ScreenHandlerType<>(TreeHandler::new, FeatureSet.empty())); + // public static final Block MAGIC_CHEST_BLOCK = Registry.register(Registries.BLOCK, Identifier.of(Keeblarcraft.MOD_ID, "magic_chest_block"), + // new MagicChestBlock(AbstractBlock.Settings.copy(Blocks.CHEST))); + + // public static final BlockEntityType MAGIC_CHEST_BLOCK_ENTITY = Registry.register(Registry.BLOCK_ENTITY_TYPE, + // Identifier.of(Keeblarcraft.MOD_ID, "magic_chest_block_entity"), BlockEntityType.Builder.create(MagicChestBlockEntity::new, MAGIC_CHEST_BLOCK).build()); + CustomCommandManager cmdMgr = new CustomCommandManager(); Setup setup = Setup.GetInstance(); @@ -75,12 +88,16 @@ public class Keeblarcraft implements ModInitializer { // 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..."); + // 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())); - } + // if (AttributeMgr.activeTrees.containsKey(player.getUuidAsString()) == false) { + // AttributeMgr.activeTrees.put(player.getUuidAsString(), new AttributeTree(player.getUuidAsString())); + // } + + System.out.println("ServerPlayConnectionEvents.JOIN called"); + PlayerJoinListener.GetInstance().HandleServerJoinEvent(handler, sender, server); }); ServerPlayConnectionEvents.DISCONNECT.register((handler, server) -> { @@ -94,13 +111,13 @@ public class Keeblarcraft implements ModInitializer { ServerEntityWorldChangeEvents.AFTER_PLAYER_CHANGE_WORLD.register((player, origin, destination) -> { System.out.println("Calling back..."); - DimensionLoadingEvent.HandleWorldMove(player, origin, destination); + DimensionLoadingEvent.GetInstance().HandleWorldMove(player, origin, destination); }); ServerLifecycleEvents.SERVER_STOPPING.register((server) ->{ // Stuff here System.out.println("SERVER_STOPPING callback called."); - DimensionLoadingEvent.ResetInventories(); + DimensionLoadingEvent.GetInstance().SaveInventories(); }); // Initialize our ticks!! diff --git a/src/main/java/jesse/keeblarcraft/Utils/DirectionalVec.java b/src/main/java/jesse/keeblarcraft/Utils/DirectionalVec.java new file mode 100644 index 0000000..902a233 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/Utils/DirectionalVec.java @@ -0,0 +1,14 @@ +package jesse.keeblarcraft.Utils; + +import net.minecraft.registry.RegistryKey; +import net.minecraft.world.World; + +public class DirectionalVec { + // public String RegistryKeyStringWorld; + public RegistryKey world; + public double x; + public double y; + public double z; + public double yaw; + public double pitch; +} diff --git a/src/main/java/jesse/keeblarcraft/world/ImplementedInventory.java b/src/main/java/jesse/keeblarcraft/world/ImplementedInventory.java new file mode 100644 index 0000000..d8a5b69 --- /dev/null +++ b/src/main/java/jesse/keeblarcraft/world/ImplementedInventory.java @@ -0,0 +1,138 @@ +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.inventory.Inventories; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.collection.DefaultedList; + +/** + * A simple {@code Inventory} implementation with only default methods + an item + * list getter. + * + * @author Juuz + * + * @from https://wiki.fabricmc.net/tutorial:inventory + */ +public interface ImplementedInventory extends Inventory { + + /** + * Retrieves the item list of this inventory. + * Must return the same instance every time it's called. + */ + DefaultedList getItems(); + + /** + * Creates an inventory from the item list. + */ + static ImplementedInventory of(DefaultedList items) { + return () -> items; + } + + /** + * Creates a new inventory with the specified size. + */ + static ImplementedInventory ofSize(int size) { + return of(DefaultedList.ofSize(size, ItemStack.EMPTY)); + } + + /** + * Returns the inventory size. + */ + @Override + default int size() { + return getItems().size(); + } + + /** + * Checks if the inventory is empty. + * + * @return true if this inventory has only empty stacks, false otherwise. + */ + @Override + default boolean isEmpty() { + for (int i = 0; i < size(); i++) { + ItemStack stack = getStack(i); + if (!stack.isEmpty()) { + return false; + } + } + return true; + } + + /** + * Retrieves the item in the slot. + */ + @Override + default ItemStack getStack(int slot) { + return getItems().get(slot); + } + + /** + * Removes items from an inventory slot. + * + * @param slot The slot to remove from. + * @param count How many items to remove. If there are less items in the slot + * than what are requested, + * takes all items in that slot. + */ + @Override + default ItemStack removeStack(int slot, int count) { + ItemStack result = Inventories.splitStack(getItems(), slot, count); + if (!result.isEmpty()) { + markDirty(); + } + return result; + } + + /** + * Removes all items from an inventory slot. + * + * @param slot The slot to remove from. + */ + @Override + default ItemStack removeStack(int slot) { + return Inventories.removeStack(getItems(), slot); + } + + /** + * Replaces the current stack in an inventory slot with the provided stack. + * + * @param slot The inventory slot of which to replace the itemstack. + * @param stack The replacing itemstack. If the stack is too big for + * this inventory ({@link Inventory#getMaxCountPerStack()}), + * it gets resized to this inventory's maximum amount. + */ + @Override + default void setStack(int slot, ItemStack stack) { + getItems().set(slot, stack); + if (stack.getCount() > stack.getMaxCount()) { + stack.setCount(stack.getMaxCount()); + } + } + + /** + * Clears the inventory. + */ + @Override + default void clear() { + getItems().clear(); + } + + /** + * Marks the state as dirty. + * Must be called after changes in the inventory, so that the game can properly + * save + * the inventory contents and notify neighboring blocks of inventory changes. + */ + @Override + default void markDirty() { + // Override if you want behavior. + } + + /** + * @return true if the player can use the inventory, false otherwise. + */ + @Override + default boolean canPlayerUse(PlayerEntity player) { + return true; + } +}