From 4dd3bd607ddc5373054940e1ee842b60a0a52f01 Mon Sep 17 00:00:00 2001 From: Felix Cravic Date: Wed, 1 Apr 2020 13:16:18 +0200 Subject: [PATCH] Update --- build.gradle | 5 +- src/main/java/fr/themode/demo/Main.java | 25 +++++- .../fr/themode/minestom/MinecraftServer.java | 14 ++++ .../minestom/instance/block/BlockManager.java | 3 +- .../client/handler/ClientPacketsHandler.java | 2 +- .../packet/client/login/LoginStartPacket.java | 51 ++++++++---- .../client/play/ClientRecipeBookData.java | 1 - .../server/play/DeclareRecipesPacket.java | 8 +- .../fr/themode/minestom/recipe/Recipe.java | 34 ++++++++ .../minestom/recipe/RecipeManager.java | 81 +++++++++++++++++++ .../themode/minestom/recipe/ShapedRecipe.java | 42 ++++++++++ .../minestom/recipe/ShapelessRecipe.java | 35 ++++++++ .../minestom/recipe/SmeltingRecipe.java | 52 ++++++++++++ 13 files changed, 326 insertions(+), 27 deletions(-) create mode 100644 src/main/java/fr/themode/minestom/recipe/Recipe.java create mode 100644 src/main/java/fr/themode/minestom/recipe/RecipeManager.java create mode 100644 src/main/java/fr/themode/minestom/recipe/ShapedRecipe.java create mode 100644 src/main/java/fr/themode/minestom/recipe/ShapelessRecipe.java create mode 100644 src/main/java/fr/themode/minestom/recipe/SmeltingRecipe.java diff --git a/build.gradle b/build.gradle index da0d3b3d5..d63424e23 100644 --- a/build.gradle +++ b/build.gradle @@ -10,7 +10,9 @@ sourceCompatibility = 1.11 repositories { mavenCentral() - maven { url 'https://jitpack.io' } + maven { url 'https://jitpack.io'} + maven { url "https://libraries.minecraft.net"} + } def lombokDependency = 'org.projectlombok:lombok:1.18.2' @@ -34,5 +36,6 @@ dependencies { implementation 'com.github.LynnOwens:starlite:9971b899f7' // https://mvnrepository.com/artifact/com.google.code.gson/gson implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5' + compile 'com.mojang:brigadier:1.0.17' } diff --git a/src/main/java/fr/themode/demo/Main.java b/src/main/java/fr/themode/demo/Main.java index 9742ef4ff..adb0f513f 100644 --- a/src/main/java/fr/themode/demo/Main.java +++ b/src/main/java/fr/themode/demo/Main.java @@ -1,9 +1,17 @@ package fr.themode.demo; +import com.mojang.brigadier.CommandDispatcher; import fr.themode.demo.blocks.StoneBlock; import fr.themode.demo.blocks.UpdatableBlockDemo; import fr.themode.minestom.MinecraftServer; +import fr.themode.minestom.command.CommandManager; +import fr.themode.minestom.entity.Player; import fr.themode.minestom.instance.block.BlockManager; +import fr.themode.minestom.item.ItemStack; +import fr.themode.minestom.net.packet.server.play.DeclareRecipesPacket; +import fr.themode.minestom.recipe.RecipeManager; +import fr.themode.minestom.recipe.ShapelessRecipe; + public class Main { @@ -11,8 +19,21 @@ public class Main { MinecraftServer minecraftServer = MinecraftServer.init(); BlockManager blockManager = MinecraftServer.getBlockManager(); - blockManager.registerBlock(new StoneBlock()); - blockManager.registerBlock(new UpdatableBlockDemo()); + blockManager.registerCustomBlock(new StoneBlock()); + blockManager.registerCustomBlock(new UpdatableBlockDemo()); + + CommandManager commandManager = MinecraftServer.getCommandManager(); + CommandDispatcher dispatcher = commandManager.getDispatcher(); + // TODO register command + + RecipeManager recipeManager = MinecraftServer.getRecipeManager(); + ShapelessRecipe shapelessRecipe = new ShapelessRecipe("test", "groupname"); + shapelessRecipe.setResult(new ItemStack(50, (byte) 1)); + DeclareRecipesPacket.Ingredient ingredient = new DeclareRecipesPacket.Ingredient(); + ingredient.items = new ItemStack[]{new ItemStack(2, (byte) 3)}; + shapelessRecipe.addIngredient(ingredient); + recipeManager.addRecipe(shapelessRecipe); + PlayerInit.init(); diff --git a/src/main/java/fr/themode/minestom/MinecraftServer.java b/src/main/java/fr/themode/minestom/MinecraftServer.java index 07d087a5d..088b07642 100644 --- a/src/main/java/fr/themode/minestom/MinecraftServer.java +++ b/src/main/java/fr/themode/minestom/MinecraftServer.java @@ -1,6 +1,7 @@ package fr.themode.minestom; import com.github.simplenet.Server; +import fr.themode.minestom.command.CommandManager; import fr.themode.minestom.data.DataManager; import fr.themode.minestom.entity.EntityManager; import fr.themode.minestom.entity.Player; @@ -14,6 +15,7 @@ import fr.themode.minestom.net.packet.PacketReader; import fr.themode.minestom.net.packet.client.status.LegacyServerListPingPacket; import fr.themode.minestom.net.packet.server.play.KeepAlivePacket; import fr.themode.minestom.net.player.PlayerConnection; +import fr.themode.minestom.recipe.RecipeManager; import fr.themode.minestom.scoreboard.TeamManager; import fr.themode.minestom.timer.SchedulerManager; import fr.themode.minestom.utils.Utils; @@ -46,6 +48,8 @@ public class MinecraftServer { private static InstanceManager instanceManager; private static BlockManager blockManager; private static EntityManager entityManager; + private static CommandManager commandManager; + private static RecipeManager recipeManager; private static DataManager dataManager; private static TeamManager teamManager; private static SchedulerManager schedulerManager; @@ -60,6 +64,8 @@ public class MinecraftServer { instanceManager = new InstanceManager(); blockManager = new BlockManager(); entityManager = new EntityManager(); + commandManager = new CommandManager(); + recipeManager = new RecipeManager(); dataManager = new DataManager(); teamManager = new TeamManager(); schedulerManager = new SchedulerManager(); @@ -91,6 +97,14 @@ public class MinecraftServer { return entityManager; } + public static CommandManager getCommandManager() { + return commandManager; + } + + public static RecipeManager getRecipeManager() { + return recipeManager; + } + public static DataManager getDataManager() { return dataManager; } diff --git a/src/main/java/fr/themode/minestom/instance/block/BlockManager.java b/src/main/java/fr/themode/minestom/instance/block/BlockManager.java index 1f1a9e0e3..6998fa139 100644 --- a/src/main/java/fr/themode/minestom/instance/block/BlockManager.java +++ b/src/main/java/fr/themode/minestom/instance/block/BlockManager.java @@ -11,8 +11,7 @@ public class BlockManager { private Short2ObjectMap blocksInternalId = new Short2ObjectOpenHashMap<>(); private Map blocksId = new HashMap<>(); - public void registerBlock(CustomBlock block) { - CustomBlock customBlock = block; + public void registerCustomBlock(CustomBlock customBlock) { String identifier = customBlock.getIdentifier(); short id = customBlock.getId(); this.blocksInternalId.put(id, customBlock); diff --git a/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPacketsHandler.java b/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPacketsHandler.java index 62f733148..0cdfe5b06 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPacketsHandler.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/handler/ClientPacketsHandler.java @@ -14,7 +14,7 @@ public class ClientPacketsHandler { } public ClientPacket getPacketInstance(int id) { - System.out.println("RECEIVED PACKET 0x" + Integer.toHexString(id)); + //System.out.println("RECEIVED PACKET 0x" + Integer.toHexString(id)); if (id > SIZE) throw new IllegalStateException("Packet ID 0x" + Integer.toHexString(id) + " has been tried to be parsed, debug needed"); diff --git a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java index 05125698b..c6906de89 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/login/LoginStartPacket.java @@ -1,24 +1,25 @@ package fr.themode.minestom.net.packet.client.login; +import com.mojang.brigadier.CommandDispatcher; import fr.themode.minestom.MinecraftServer; +import fr.themode.minestom.command.CommandManager; import fr.themode.minestom.entity.GameMode; import fr.themode.minestom.entity.Player; -import fr.themode.minestom.item.ItemStack; -import fr.themode.minestom.item.Material; import fr.themode.minestom.net.ConnectionManager; import fr.themode.minestom.net.ConnectionState; import fr.themode.minestom.net.packet.PacketReader; import fr.themode.minestom.net.packet.client.ClientPreplayPacket; import fr.themode.minestom.net.packet.server.login.JoinGamePacket; import fr.themode.minestom.net.packet.server.login.LoginSuccessPacket; -import fr.themode.minestom.net.packet.server.play.DeclareCommandsPacket; -import fr.themode.minestom.net.packet.server.play.DeclareRecipesPacket; -import fr.themode.minestom.net.packet.server.play.PlayerInfoPacket; -import fr.themode.minestom.net.packet.server.play.SpawnPositionPacket; +import fr.themode.minestom.net.packet.server.play.*; import fr.themode.minestom.net.player.PlayerConnection; +import fr.themode.minestom.recipe.Recipe; +import fr.themode.minestom.recipe.RecipeManager; import fr.themode.minestom.world.Dimension; import fr.themode.minestom.world.LevelType; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; import java.util.function.Consumer; @@ -95,6 +96,17 @@ public class LoginStartPacket implements ClientPreplayPacket { MinecraftServer.getEntityManager().addWaitingPlayer(player); + + { + CommandManager commandManager = MinecraftServer.getCommandManager(); + CommandDispatcher dispatcher = commandManager.getDispatcher(); + String[] usages = dispatcher.getAllUsage(dispatcher.getRoot(), player, true); + for (String usage : usages) { + System.out.println("USAGE: " + usage); + } + } + + DeclareCommandsPacket declareCommandsPacket = new DeclareCommandsPacket(); DeclareCommandsPacket.Node argumentNode = new DeclareCommandsPacket.Node(); argumentNode.flags = 0b1010; @@ -117,17 +129,22 @@ public class LoginStartPacket implements ClientPreplayPacket { { - DeclareRecipesPacket recipesPacket = new DeclareRecipesPacket(); - DeclareRecipesPacket.Recipe recipe = new DeclareRecipesPacket.Recipe(); - recipe.recipeId = "crafting_shapeless"; - recipe.type = "crafting_shapeless"; - recipe.group = "test group"; - DeclareRecipesPacket.Ingredient ingredient = new DeclareRecipesPacket.Ingredient(); - ingredient.items = new ItemStack[]{new ItemStack(Material.STONE, (byte) 1)}; - recipe.ingredients = new DeclareRecipesPacket.Ingredient[]{ingredient}; - recipe.result = new ItemStack(Material.STONE, (byte) 50); - recipesPacket.recipes = new DeclareRecipesPacket.Recipe[]{recipe}; - connection.sendPacket(recipesPacket); + RecipeManager recipeManager = MinecraftServer.getRecipeManager(); + DeclareRecipesPacket declareRecipesPacket = recipeManager.getDeclareRecipesPacket(); + + connection.sendPacket(declareRecipesPacket); + + List recipesIdentifier = new ArrayList<>(); + for (Recipe recipe : recipeManager.getRecipes()) { + // TODO check condition + recipesIdentifier.add(recipe.getRecipeId()); + } + String[] identifiers = recipesIdentifier.toArray(new String[recipesIdentifier.size()]); + UnlockRecipesPacket unlockRecipesPacket = new UnlockRecipesPacket(); + unlockRecipesPacket.mode = 0; + unlockRecipesPacket.recipesId = identifiers; + unlockRecipesPacket.initRecipesId = identifiers; + connection.sendPacket(unlockRecipesPacket); } } diff --git a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientRecipeBookData.java b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientRecipeBookData.java index 9ce31a896..3ca0f60d6 100644 --- a/src/main/java/fr/themode/minestom/net/packet/client/play/ClientRecipeBookData.java +++ b/src/main/java/fr/themode/minestom/net/packet/client/play/ClientRecipeBookData.java @@ -26,7 +26,6 @@ public class ClientRecipeBookData extends ClientPlayPacket { switch (id) { case 0: reader.readSizedString((string, length) -> { - System.out.println("test: " + string); callback.run(); }); break; diff --git a/src/main/java/fr/themode/minestom/net/packet/server/play/DeclareRecipesPacket.java b/src/main/java/fr/themode/minestom/net/packet/server/play/DeclareRecipesPacket.java index 4216bb1b2..73de65010 100644 --- a/src/main/java/fr/themode/minestom/net/packet/server/play/DeclareRecipesPacket.java +++ b/src/main/java/fr/themode/minestom/net/packet/server/play/DeclareRecipesPacket.java @@ -11,6 +11,8 @@ public class DeclareRecipesPacket implements ServerPacket { @Override public void write(PacketWriter writer) { + if (recipes == null) + throw new NullPointerException("Recipes cannot be null!"); writer.writeVarInt(recipes.length); for (Recipe recipe : recipes) { recipe.write(writer); @@ -25,7 +27,7 @@ public class DeclareRecipesPacket implements ServerPacket { public static class Recipe { public String recipeId; - public String type; + public String recipeType; public String group; @@ -54,10 +56,10 @@ public class DeclareRecipesPacket implements ServerPacket { private void write(PacketWriter writer) { + writer.writeSizedString(recipeType); writer.writeSizedString(recipeId); - writer.writeSizedString(type); - switch (type) { + switch (recipeType) { case "crafting_shapeless": writer.writeSizedString(group); writer.writeVarInt(ingredients.length); diff --git a/src/main/java/fr/themode/minestom/recipe/Recipe.java b/src/main/java/fr/themode/minestom/recipe/Recipe.java new file mode 100644 index 000000000..0822b452d --- /dev/null +++ b/src/main/java/fr/themode/minestom/recipe/Recipe.java @@ -0,0 +1,34 @@ +package fr.themode.minestom.recipe; + +public class Recipe { + + protected RecipeType recipeType; + protected String recipeId; + protected String group; + + protected Recipe(RecipeType recipeType, String recipeId) { + this.recipeType = recipeType; + this.recipeId = recipeId; + } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } + + public RecipeType getRecipeType() { + return recipeType; + } + + public String getRecipeId() { + return recipeId; + } + + protected enum RecipeType { + SHAPELESS, SHAPED, SMELTING; + } + +} diff --git a/src/main/java/fr/themode/minestom/recipe/RecipeManager.java b/src/main/java/fr/themode/minestom/recipe/RecipeManager.java new file mode 100644 index 000000000..bd9ecbb5d --- /dev/null +++ b/src/main/java/fr/themode/minestom/recipe/RecipeManager.java @@ -0,0 +1,81 @@ +package fr.themode.minestom.recipe; + +import fr.themode.minestom.net.packet.server.play.DeclareRecipesPacket; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.CopyOnWriteArraySet; + +public class RecipeManager { + + private Set recipes = new CopyOnWriteArraySet<>(); + + private DeclareRecipesPacket declareRecipesPacket = new DeclareRecipesPacket(); + + public void addRecipe(Recipe recipe) { + if (this.recipes.add(recipe)) { + // TODO add to all players + + refreshRecipesPacket(); + } + } + + public void removeRecipe(Recipe recipe) { + if (this.recipes.remove(recipe)) { + // TODO remove to all players + + refreshRecipesPacket(); + } + } + + public Set getRecipes() { + return recipes; + } + + public DeclareRecipesPacket getDeclareRecipesPacket() { + return declareRecipesPacket; + } + + private void refreshRecipesPacket() { + List recipesCache = new ArrayList<>(); + for (Recipe recipe : recipes) { + DeclareRecipesPacket.Recipe packetRecipe = new DeclareRecipesPacket.Recipe(); + + switch (recipe.recipeType) { + case SHAPELESS: + packetRecipe.recipeType = "crafting_shapeless"; + packetRecipe.group = recipe.getGroup(); + ShapelessRecipe shapelessRecipe = (ShapelessRecipe) recipe; + List ingredients = shapelessRecipe.getIngredients(); + packetRecipe.ingredients = ingredients.toArray(new DeclareRecipesPacket.Ingredient[ingredients.size()]); + packetRecipe.result = shapelessRecipe.getResult(); + break; + case SHAPED: + packetRecipe.recipeType = "crafting_shaped"; + packetRecipe.group = recipe.getGroup(); + ShapedRecipe shapedRecipe = (ShapedRecipe) recipe; + List ingredients2 = shapedRecipe.getIngredients(); + packetRecipe.ingredients = ingredients2.toArray(new DeclareRecipesPacket.Ingredient[ingredients2.size()]); + packetRecipe.result = shapedRecipe.getResult(); + break; + case SMELTING: + packetRecipe.recipeType = "smelting"; + packetRecipe.group = recipe.getGroup(); + SmeltingRecipe smeltingRecipe = (SmeltingRecipe) recipe; + packetRecipe.ingredient = smeltingRecipe.getIngredient(); + packetRecipe.result = smeltingRecipe.getResult(); + packetRecipe.experience = smeltingRecipe.getExperience(); + packetRecipe.cookingTime = smeltingRecipe.getCookingTime(); + break; + } + + packetRecipe.recipeId = recipe.recipeId; + + recipesCache.add(packetRecipe); + } + + declareRecipesPacket.recipes = recipesCache.toArray(new DeclareRecipesPacket.Recipe[recipesCache.size()]); + } + +} diff --git a/src/main/java/fr/themode/minestom/recipe/ShapedRecipe.java b/src/main/java/fr/themode/minestom/recipe/ShapedRecipe.java new file mode 100644 index 000000000..26c2118ca --- /dev/null +++ b/src/main/java/fr/themode/minestom/recipe/ShapedRecipe.java @@ -0,0 +1,42 @@ +package fr.themode.minestom.recipe; + +import fr.themode.minestom.item.ItemStack; +import fr.themode.minestom.net.packet.server.play.DeclareRecipesPacket; + +import java.util.ArrayList; +import java.util.List; + +public class ShapedRecipe extends Recipe { + + private int width, height; + + private List ingredients = new ArrayList<>(); + + private ItemStack result = ItemStack.AIR_ITEM; + + public ShapedRecipe(String recipeId, String group, int width, int height) { + super(RecipeType.SHAPED, recipeId); + setGroup(group); + this.width = width; + this.height = height; + } + + public void addIngredient(DeclareRecipesPacket.Ingredient ingredient) { + if (ingredients.size() + 1 > width * height) + throw new IndexOutOfBoundsException("You cannot add more ingredients than width*height"); + + ingredients.add(ingredient); + } + + public List getIngredients() { + return ingredients; + } + + public ItemStack getResult() { + return result; + } + + public void setResult(ItemStack result) { + this.result = result; + } +} diff --git a/src/main/java/fr/themode/minestom/recipe/ShapelessRecipe.java b/src/main/java/fr/themode/minestom/recipe/ShapelessRecipe.java new file mode 100644 index 000000000..98154499f --- /dev/null +++ b/src/main/java/fr/themode/minestom/recipe/ShapelessRecipe.java @@ -0,0 +1,35 @@ +package fr.themode.minestom.recipe; + +import fr.themode.minestom.item.ItemStack; +import fr.themode.minestom.net.packet.server.play.DeclareRecipesPacket; + +import java.util.ArrayList; +import java.util.List; + +public class ShapelessRecipe extends Recipe { + + private List ingredients = new ArrayList<>(); + + private ItemStack result = ItemStack.AIR_ITEM; + + public ShapelessRecipe(String recipeId, String group) { + super(RecipeType.SHAPELESS, recipeId); + setGroup(group); + } + + public void addIngredient(DeclareRecipesPacket.Ingredient ingredient) { + ingredients.add(ingredient); + } + + public List getIngredients() { + return ingredients; + } + + public ItemStack getResult() { + return result; + } + + public void setResult(ItemStack result) { + this.result = result; + } +} diff --git a/src/main/java/fr/themode/minestom/recipe/SmeltingRecipe.java b/src/main/java/fr/themode/minestom/recipe/SmeltingRecipe.java new file mode 100644 index 000000000..5cf226b3b --- /dev/null +++ b/src/main/java/fr/themode/minestom/recipe/SmeltingRecipe.java @@ -0,0 +1,52 @@ +package fr.themode.minestom.recipe; + +import fr.themode.minestom.item.ItemStack; +import fr.themode.minestom.net.packet.server.play.DeclareRecipesPacket; + +public class SmeltingRecipe extends Recipe { + + private DeclareRecipesPacket.Ingredient ingredient; + + private ItemStack result = ItemStack.AIR_ITEM; + + private float experience; + + private int cookingTime; + + public SmeltingRecipe(String recipeId, String group) { + super(RecipeType.SMELTING, recipeId); + setGroup(group); + } + + public DeclareRecipesPacket.Ingredient getIngredient() { + return ingredient; + } + + public void setIngredient(DeclareRecipesPacket.Ingredient ingredient) { + this.ingredient = ingredient; + } + + public ItemStack getResult() { + return result; + } + + public void setResult(ItemStack result) { + this.result = result; + } + + public float getExperience() { + return experience; + } + + public void setExperience(float experience) { + this.experience = experience; + } + + public int getCookingTime() { + return cookingTime; + } + + public void setCookingTime(int cookingTime) { + this.cookingTime = cookingTime; + } +}