diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java index 4e222efdc..cb79005f7 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/item/BukkitItemManager.java @@ -100,6 +100,21 @@ public class BukkitItemManager extends AbstractItemManager { return instance; } + @Override + public Item s2c(Item item, Player player) { + return this.networkItemHandler.s2c(item, player).map(it -> { + System.out.println("有变化"); + System.out.println(item.getItem()); + System.out.println(it.getItem()); + return it; + }).orElse(item); + } + + @Override + public Item c2s(Item item) { + return this.networkItemHandler.c2s(item).orElse(item); + } + public Optional s2c(ItemStack itemStack, Player player) { try { Item wrapped = wrap(itemStack); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java index 144d3f61e..1f0efba2c 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/BukkitNetworkManager.java @@ -173,6 +173,8 @@ public class BukkitNetworkManager implements NetworkManager, Listener, PluginMes registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.TEAM_1_20_3 : PacketConsumers.TEAM_1_20, this.packetIds.clientboundSetPlayerTeamPacket()); registerS2CByteBufPacketConsumer(VersionHelper.isOrAbove1_20_3() ? PacketConsumers.SET_OBJECTIVE_1_20_3 : PacketConsumers.SET_OBJECTIVE_1_20, this.packetIds.clientboundSetObjectivePacket()); registerS2CByteBufPacketConsumer(PacketConsumers.SET_SCORE_1_20_3, VersionHelper.isOrAbove1_20_3() ? this.packetIds.clientboundSetScorePacket() : -1); + registerS2CByteBufPacketConsumer(PacketConsumers.ADD_RECIPE_BOOK, this.packetIds.clientboundRecipeBookAddPacket()); + registerS2CByteBufPacketConsumer(PacketConsumers.PLACE_GHOST_RECIPE, this.packetIds.clientboundPlaceGhostRecipePacket()); registerS2CByteBufPacketConsumer(PacketConsumers.REMOVE_ENTITY, this.packetIds.clientboundRemoveEntitiesPacket()); registerS2CByteBufPacketConsumer(PacketConsumers.ADD_ENTITY, this.packetIds.clientboundAddEntityPacket()); registerS2CByteBufPacketConsumer(PacketConsumers.SOUND, this.packetIds.clientboundSoundPacket()); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java index c13dae548..e494e2ccc 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketConsumers.java @@ -42,6 +42,9 @@ import net.momirealms.craftengine.core.item.CustomItem; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.item.behavior.ItemBehavior; import net.momirealms.craftengine.core.item.context.UseOnContext; +import net.momirealms.craftengine.core.item.recipe.network.RecipeBookDisplayEntry; +import net.momirealms.craftengine.core.item.recipe.network.RecipeBookEntry; +import net.momirealms.craftengine.core.item.recipe.network.display.RecipeDisplay; import net.momirealms.craftengine.core.pack.host.ResourcePackDownloadData; import net.momirealms.craftengine.core.pack.host.ResourcePackHost; import net.momirealms.craftengine.core.plugin.CraftEngine; @@ -2477,4 +2480,40 @@ public class PacketConsumers { CraftEngine.instance().logger().warn("Failed to handle ClientboundLoginFinishedPacket", e); } }; + + public static final BiConsumer ADD_RECIPE_BOOK = (user, event) -> { + try { + FriendlyByteBuf buf = event.getBuffer(); + List entries = buf.readCollection(ArrayList::new, byteBuf -> { + RecipeBookEntry entry = RecipeBookEntry.read(byteBuf); + entry.applyClientboundData((BukkitServerPlayer) user); + return entry; + }); + boolean replace = buf.readBoolean(); + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeCollection(entries, ((byteBuf, recipeBookEntry) -> recipeBookEntry.write(byteBuf))); + buf.writeBoolean(replace); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundRecipeBookAddPacket", e); + } + }; + + public static final BiConsumer PLACE_GHOST_RECIPE = (user, event) -> { + try { + if (!VersionHelper.isOrAbove1_21_2()) return; + FriendlyByteBuf buf = event.getBuffer(); + int containerId = buf.readContainerId(); + RecipeDisplay display = RecipeDisplay.read(buf); + display.applyClientboundData((BukkitServerPlayer) user); + event.setChanged(true); + buf.clear(); + buf.writeVarInt(event.packetID()); + buf.writeContainerId(containerId); + display.write(buf); + } catch (Exception e) { + CraftEngine.instance().logger().warn("Failed to handle ClientboundPlaceGhostRecipePacket", e); + } + }; } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java index 678e06f1a..8ad482b42 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/PacketIds.java @@ -54,6 +54,10 @@ public interface PacketIds { int clientboundBlockEventPacket(); + int clientboundRecipeBookAddPacket(); + + int clientboundPlaceGhostRecipePacket(); + int serverboundContainerClickPacket(); int serverboundSetCreativeModeSlotPacket(); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20.java index d9ff6e609..b04b1c0e3 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20.java @@ -149,4 +149,14 @@ public class PacketIds1_20 implements PacketIds { public int serverboundInteractPacket() { return PacketIdFinder.serverboundByClazz(NetworkReflections.clazz$ServerboundInteractPacket); } + + @Override + public int clientboundRecipeBookAddPacket() { + return PacketIdFinder.serverboundByClazz(NetworkReflections.clazz$ClientboundRecipeBookAddPacket); + } + + @Override + public int clientboundPlaceGhostRecipePacket() { + return PacketIdFinder.serverboundByClazz(NetworkReflections.clazz$ClientboundPlaceGhostRecipePacket); + } } diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java index 03d66538a..ea2558943 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/network/id/PacketIds1_20_5.java @@ -134,6 +134,16 @@ public class PacketIds1_20_5 implements PacketIds { return PacketIdFinder.clientboundByName("minecraft:block_event"); } + @Override + public int clientboundRecipeBookAddPacket() { + return PacketIdFinder.clientboundByName("minecraft:recipe_book_add"); + } + + @Override + public int clientboundPlaceGhostRecipePacket() { + return PacketIdFinder.clientboundByName("minecraft:place_ghost_recipe"); + } + @Override public int serverboundContainerClickPacket() { return PacketIdFinder.serverboundByName("minecraft:container_click"); diff --git a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java index 5f84d29ff..a1efe057f 100644 --- a/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java +++ b/bukkit/src/main/java/net/momirealms/craftengine/bukkit/plugin/reflection/minecraft/NetworkReflections.java @@ -1566,4 +1566,11 @@ public final class NetworkReflections { "network.protocol.game.ClientboundRecipeBookAddPacket", "network.protocol.game.ClientboundRecipeBookAddPacket" ), VersionHelper.isOrAbove1_21_2()); + + public static final Class clazz$ClientboundPlaceGhostRecipePacket = requireNonNull( + BukkitReflectionUtils.findReobfOrMojmapClass( + "network.protocol.game.ClientboundPlaceGhostRecipePacket", + "network.protocol.game.ClientboundPlaceGhostRecipePacket" + ) + ); } diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 1e60662f2..ceff97962 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -21,7 +21,7 @@ dependencies { implementation("net.momirealms:sparrow-nbt-codec:${rootProject.properties["sparrow_nbt_version"]}") implementation("net.momirealms:sparrow-nbt-legacy-codec:${rootProject.properties["sparrow_nbt_version"]}") // S3 - implementation("net.momirealms:craft-engine-s3:0.3") + implementation("net.momirealms:craft-engine-s3:0.4") // Util compileOnly("net.momirealms:sparrow-util:${rootProject.properties["sparrow_util_version"]}") // Adventure diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java index bc44c0b78..c2e0b0ec9 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/ItemManager.java @@ -97,4 +97,8 @@ public interface ItemManager extends Manageable, ModelGenerator { Item decode(FriendlyByteBuf byteBuf); void encode(FriendlyByteBuf byteBuf, Item item); + + Item s2c(Item item, Player player); + + Item c2s(Item item); } \ No newline at end of file diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeBookDisplayEntry.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeBookDisplayEntry.java index 20bfc0fca..c84dc5d3e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeBookDisplayEntry.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeBookDisplayEntry.java @@ -1,30 +1,51 @@ package net.momirealms.craftengine.core.item.recipe.network; +import com.mojang.datafixers.util.Either; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.recipe.network.display.RecipeDisplay; -import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.util.FriendlyByteBuf; +import net.momirealms.craftengine.core.util.Key; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.OptionalInt; -public record RecipeBookDisplayEntry(RecipeDisplayId displayId, RecipeDisplay display, OptionalInt group, int category, Optional> ingredients) { +public record RecipeBookDisplayEntry(RecipeDisplayId displayId, RecipeDisplay display, OptionalInt group, int category, Optional> ingredients) { public static RecipeBookDisplayEntry read(FriendlyByteBuf buffer) { RecipeDisplayId displayId = RecipeDisplayId.read(buffer); - RecipeDisplay display = buffer.readById(BuiltInRegistries.RECIPE_DISPLAY_TYPE).read(buffer); + RecipeDisplay display = RecipeDisplay.read(buffer); OptionalInt group = buffer.readOptionalVarInt(); int category = buffer.readVarInt(); // simplify the registry lookup since we don't care about the category - Optional> requirements = buffer.readOptional(buf -> buf.readCollection(ArrayList::new, FriendlyByteBuf::readVarInt)); // simplify the registry lookup since we don't care about the ingredient ids + Optional> requirements = buffer.readOptional(buf -> buf.readCollection(ArrayList::new, byteBuf -> new Ingredient(byteBuf.readHolderSet()))); // simplify the registry lookup since we don't care about the ingredient ids return new RecipeBookDisplayEntry(displayId, display, group, category, requirements); } + public void applyClientboundData(Player player) { + this.display.applyClientboundData(player); + } + public void write(FriendlyByteBuf buffer) { this.displayId.write(buffer); this.display.write(buffer); buffer.writeOptionalVarInt(this.group); buffer.writeVarInt(this.category); - buffer.writeOptional(this.ingredients, (buf, recipeIngredients) -> buf.writeCollection(recipeIngredients, FriendlyByteBuf::writeVarInt)); + buffer.writeOptional(this.ingredients, (buf, recipeIngredients) -> buf.writeCollection(recipeIngredients, (byteBuf, ingredient) -> byteBuf.writeHolderSet(ingredient.holderSet))); + } + + @Override + public @NotNull String toString() { + return "RecipeBookDisplayEntry{" + + "category=" + category + + ", displayId=" + displayId + + ", display=" + display + + ", group=" + group + + ", ingredients=" + ingredients + + '}'; + } + + public record Ingredient(Either, Key> holderSet) { } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeBookEntry.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeBookEntry.java index e8b96ca23..6ecee93d0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeBookEntry.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeBookEntry.java @@ -1,9 +1,14 @@ package net.momirealms.craftengine.core.item.recipe.network; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.util.FriendlyByteBuf; public record RecipeBookEntry(RecipeBookDisplayEntry entry, byte flags) { + public void applyClientboundData(Player player) { + this.entry.applyClientboundData(player); + } + public static RecipeBookEntry read(FriendlyByteBuf buffer) { RecipeBookDisplayEntry displayEntry = RecipeBookDisplayEntry.read(buffer); byte flags = buffer.readByte(); diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeDisplayId.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeDisplayId.java index f35ec4e23..264bd71e5 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeDisplayId.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/RecipeDisplayId.java @@ -1,6 +1,7 @@ package net.momirealms.craftengine.core.item.recipe.network; import net.momirealms.craftengine.core.util.FriendlyByteBuf; +import org.jetbrains.annotations.NotNull; public record RecipeDisplayId(int id) { @@ -11,4 +12,11 @@ public record RecipeDisplayId(int id) { public static RecipeDisplayId read(FriendlyByteBuf buffer) { return new RecipeDisplayId(buffer.readVarInt()); } + + @Override + public @NotNull String toString() { + return "RecipeDisplayId{" + + "id=" + id + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/FurnaceRecipeDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/FurnaceRecipeDisplay.java index 95995e8b2..64e18b68b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/FurnaceRecipeDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/FurnaceRecipeDisplay.java @@ -1,28 +1,50 @@ package net.momirealms.craftengine.core.item.recipe.network.display; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.recipe.network.display.slot.SlotDisplay; import net.momirealms.craftengine.core.util.FriendlyByteBuf; +import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; - -public record FurnaceRecipeDisplay(SlotDisplay ingredient, SlotDisplay result, SlotDisplay craftingStation, int duration, float experience) implements RecipeDisplay { +public record FurnaceRecipeDisplay(SlotDisplay ingredient, SlotDisplay fuel, SlotDisplay result, SlotDisplay craftingStation, int duration, float experience) implements RecipeDisplay { public static FurnaceRecipeDisplay read(FriendlyByteBuf buffer) { SlotDisplay ingredient = SlotDisplay.read(buffer); + SlotDisplay fuel = SlotDisplay.read(buffer); SlotDisplay result = SlotDisplay.read(buffer); SlotDisplay craftingStation = SlotDisplay.read(buffer); int duration = buffer.readVarInt(); float experience = buffer.readFloat(); - return new FurnaceRecipeDisplay(ingredient, result, craftingStation, duration, experience); + return new FurnaceRecipeDisplay(ingredient, fuel, result, craftingStation, duration, experience); + } + + @Override + public void applyClientboundData(Player player) { + this.ingredient.applyClientboundData(player); + this.fuel.applyClientboundData(player); + this.result.applyClientboundData(player); + this.craftingStation.applyClientboundData(player); } @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(2); this.ingredient.write(buf); + this.fuel.write(buf); this.result.write(buf); this.craftingStation.write(buf); buf.writeVarInt(this.duration); buf.writeFloat(this.experience); } + + @Override + public @NotNull String toString() { + return "FurnaceRecipeDisplay{" + + "craftingStation=" + craftingStation + + ", ingredient=" + ingredient + + ", fuel=" + fuel + + ", result=" + result + + ", duration=" + duration + + ", experience=" + experience + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/RecipeDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/RecipeDisplay.java index 30d7c23a5..d03ce8bd2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/RecipeDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/RecipeDisplay.java @@ -1,5 +1,7 @@ package net.momirealms.craftengine.core.item.recipe.network.display; +import net.momirealms.craftengine.core.entity.player.Player; +import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.util.FriendlyByteBuf; import java.util.function.Function; @@ -8,6 +10,12 @@ public interface RecipeDisplay { void write(FriendlyByteBuf buf); + void applyClientboundData(Player player); + + static RecipeDisplay read(final FriendlyByteBuf buf) { + return buf.readById(BuiltInRegistries.RECIPE_DISPLAY_TYPE).read(buf); + } + record Type(Function reader) { public RecipeDisplay read(final FriendlyByteBuf buf) { diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/RecipeDisplays.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/RecipeDisplays.java index 94d14b958..5ac45c1f0 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/RecipeDisplays.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/RecipeDisplays.java @@ -18,7 +18,7 @@ public final class RecipeDisplays { register(CRAFTING_SHAPELESS, new RecipeDisplay.Type(ShapelessCraftingRecipeDisplay::read)); register(CRAFTING_SHAPED, new RecipeDisplay.Type(ShapedCraftingRecipeDisplay::read)); register(FURNACE, new RecipeDisplay.Type(FurnaceRecipeDisplay::read)); - register(STONECUTTER, new RecipeDisplay.Type(SmithingRecipeDisplay::read)); + register(STONECUTTER, new RecipeDisplay.Type(StonecutterRecipeDisplay::read)); register(SMITHING, new RecipeDisplay.Type(SmithingRecipeDisplay::read)); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/ShapedCraftingRecipeDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/ShapedCraftingRecipeDisplay.java index 16a129674..82270d671 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/ShapedCraftingRecipeDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/ShapedCraftingRecipeDisplay.java @@ -1,9 +1,9 @@ package net.momirealms.craftengine.core.item.recipe.network.display; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.recipe.network.display.slot.SlotDisplay; -import net.momirealms.craftengine.core.item.recipe.network.display.slot.SlotDisplays; -import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.util.FriendlyByteBuf; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -19,12 +19,33 @@ public record ShapedCraftingRecipeDisplay(int width, int height, List slotDisplay.write(buf)); this.result.write(buf); this.craftingStation.write(buf); } + + @Override + public @NotNull String toString() { + return "ShapedCraftingRecipeDisplay{" + + "craftingStation=" + craftingStation + + ", width=" + width + + ", height=" + height + + ", ingredients=" + ingredients + + ", result=" + result + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/ShapelessCraftingRecipeDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/ShapelessCraftingRecipeDisplay.java index a344b1815..7d572239b 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/ShapelessCraftingRecipeDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/ShapelessCraftingRecipeDisplay.java @@ -1,7 +1,9 @@ package net.momirealms.craftengine.core.item.recipe.network.display; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.recipe.network.display.slot.SlotDisplay; import net.momirealms.craftengine.core.util.FriendlyByteBuf; +import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; @@ -15,10 +17,29 @@ public record ShapelessCraftingRecipeDisplay(List ingredients, Slot return new ShapelessCraftingRecipeDisplay(ingredients, result, craftingStation); } + @Override + public void applyClientboundData(Player player) { + for (SlotDisplay ingredient : ingredients) { + ingredient.applyClientboundData(player); + } + this.result.applyClientboundData(player); + this.craftingStation.applyClientboundData(player); + } + @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(0); buf.writeCollection(this.ingredients, (byteBuf, slotDisplay) -> slotDisplay.write(buf)); this.result.write(buf); this.craftingStation.write(buf); } + + @Override + public @NotNull String toString() { + return "ShapelessCraftingRecipeDisplay{" + + "craftingStation=" + craftingStation + + ", ingredients=" + ingredients + + ", result=" + result + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/SmithingRecipeDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/SmithingRecipeDisplay.java index 2fb29df2a..a5398cb4e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/SmithingRecipeDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/SmithingRecipeDisplay.java @@ -1,10 +1,9 @@ package net.momirealms.craftengine.core.item.recipe.network.display; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.recipe.network.display.slot.SlotDisplay; import net.momirealms.craftengine.core.util.FriendlyByteBuf; - -import java.util.ArrayList; -import java.util.List; +import org.jetbrains.annotations.NotNull; public record SmithingRecipeDisplay(SlotDisplay template, SlotDisplay base, SlotDisplay addition, SlotDisplay result, SlotDisplay craftingStation) implements RecipeDisplay { @@ -17,12 +16,33 @@ public record SmithingRecipeDisplay(SlotDisplay template, SlotDisplay base, Slot return new SmithingRecipeDisplay(template, base, addition, result, craftingStation); } + @Override + public void applyClientboundData(Player player) { + this.template.applyClientboundData(player); + this.base.applyClientboundData(player); + this.addition.applyClientboundData(player); + this.result.applyClientboundData(player); + this.craftingStation.applyClientboundData(player); + } + @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(4); this.template.write(buf); this.base.write(buf); this.addition.write(buf); this.result.write(buf); this.craftingStation.write(buf); } + + @Override + public @NotNull String toString() { + return "SmithingRecipeDisplay{" + + "addition=" + addition + + ", template=" + template + + ", base=" + base + + ", result=" + result + + ", craftingStation=" + craftingStation + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/StonecutterRecipeDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/StonecutterRecipeDisplay.java index 2fb29df2a..a7fa2201e 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/StonecutterRecipeDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/StonecutterRecipeDisplay.java @@ -1,28 +1,40 @@ package net.momirealms.craftengine.core.item.recipe.network.display; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.recipe.network.display.slot.SlotDisplay; import net.momirealms.craftengine.core.util.FriendlyByteBuf; +import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; -import java.util.List; +public record StonecutterRecipeDisplay(SlotDisplay input, SlotDisplay result, SlotDisplay craftingStation) implements RecipeDisplay { -public record SmithingRecipeDisplay(SlotDisplay template, SlotDisplay base, SlotDisplay addition, SlotDisplay result, SlotDisplay craftingStation) implements RecipeDisplay { - - public static SmithingRecipeDisplay read(FriendlyByteBuf buffer) { - SlotDisplay template = SlotDisplay.read(buffer); - SlotDisplay base = SlotDisplay.read(buffer); - SlotDisplay addition = SlotDisplay.read(buffer); + public static StonecutterRecipeDisplay read(FriendlyByteBuf buffer) { + SlotDisplay input = SlotDisplay.read(buffer); SlotDisplay result = SlotDisplay.read(buffer); SlotDisplay craftingStation = SlotDisplay.read(buffer); - return new SmithingRecipeDisplay(template, base, addition, result, craftingStation); + return new StonecutterRecipeDisplay(input, result, craftingStation); + } + + @Override + public void applyClientboundData(Player player) { + this.input.applyClientboundData(player); + this.result.applyClientboundData(player); + this.craftingStation.applyClientboundData(player); } @Override public void write(FriendlyByteBuf buf) { - this.template.write(buf); - this.base.write(buf); - this.addition.write(buf); + buf.writeVarInt(3); + this.input.write(buf); this.result.write(buf); this.craftingStation.write(buf); } + + @Override + public @NotNull String toString() { + return "StonecutterRecipeDisplay{" + + "craftingStation=" + craftingStation + + ", input=" + input + + ", result=" + result + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/AnyFuelDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/AnyFuelDisplay.java index ad1e3ea31..8621b1516 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/AnyFuelDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/AnyFuelDisplay.java @@ -11,5 +11,11 @@ public class AnyFuelDisplay implements SlotDisplay { @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(1); + } + + @Override + public String toString() { + return "AnyFuelDisplay{}"; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/CompositeSlotDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/CompositeSlotDisplay.java index 5b09ea544..62c6c2561 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/CompositeSlotDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/CompositeSlotDisplay.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.item.recipe.network.display.slot; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.util.FriendlyByteBuf; import java.util.ArrayList; @@ -17,12 +18,27 @@ public class CompositeSlotDisplay implements SlotDisplay { return new CompositeSlotDisplay(slots); } + @Override + public void applyClientboundData(Player player) { + for (SlotDisplay slotDisplay : this.slots) { + slotDisplay.applyClientboundData(player); + } + } + @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(7); buf.writeCollection(this.slots, (byteBuf, slotDisplay) -> slotDisplay.write(buf)); } public List slots() { return this.slots; } + + @Override + public String toString() { + return "CompositeSlotDisplay{" + + "slots=" + slots + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/EmptySlotDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/EmptySlotDisplay.java index 61580f8a2..e6b9fb74f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/EmptySlotDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/EmptySlotDisplay.java @@ -11,5 +11,11 @@ public class EmptySlotDisplay implements SlotDisplay { @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(0); + } + + @Override + public String toString() { + return "EmptySlotDisplay{}"; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/ItemSlotDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/ItemSlotDisplay.java index 37366ccb1..f18fc0718 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/ItemSlotDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/ItemSlotDisplay.java @@ -16,10 +16,18 @@ public class ItemSlotDisplay implements SlotDisplay { @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(2); buf.writeVarInt(this.item); } public int item() { return item; } + + @Override + public String toString() { + return "ItemSlotDisplay{" + + "item=" + item + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/ItemStackSlotDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/ItemStackSlotDisplay.java index a40250f71..43faeaec2 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/ItemStackSlotDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/ItemStackSlotDisplay.java @@ -1,28 +1,46 @@ package net.momirealms.craftengine.core.item.recipe.network.display.slot; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.item.Item; import net.momirealms.craftengine.core.plugin.CraftEngine; import net.momirealms.craftengine.core.util.FriendlyByteBuf; public class ItemStackSlotDisplay implements SlotDisplay { - private final Item item; + private Item item; - public ItemStackSlotDisplay(Item item) { + public ItemStackSlotDisplay(Item item) { this.item = item; } public static ItemStackSlotDisplay read(FriendlyByteBuf buf) { - Item itemStack = CraftEngine.instance().itemManager().decode(buf); + Item itemStack = CraftEngine.instance().itemManager().decode(buf); return new ItemStackSlotDisplay(itemStack); } - @SuppressWarnings("unchecked") @Override public void write(FriendlyByteBuf buf) { - CraftEngine.instance().itemManager().encode(buf, (Item) this.item); + buf.writeVarInt(3); + CraftEngine.instance().itemManager().encode(buf, this.item); + } + + @Override + public void applyClientboundData(Player player) { + System.out.println("gai ni ma"); + this.item = CraftEngine.instance().itemManager().s2c(this.item, player); } public Item item() { - return item; + return this.item; + } + + public void setItem(Item item) { + this.item = item; + } + + @Override + public String toString() { + return "ItemStackSlotDisplay{" + + "item=" + this.item.getLiteralObject() + + '}'; } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/SlotDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/SlotDisplay.java index da629bafa..1540ce2a1 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/SlotDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/SlotDisplay.java @@ -1,5 +1,6 @@ package net.momirealms.craftengine.core.item.recipe.network.display.slot; +import net.momirealms.craftengine.core.entity.player.Player; import net.momirealms.craftengine.core.registry.BuiltInRegistries; import net.momirealms.craftengine.core.util.FriendlyByteBuf; @@ -9,6 +10,9 @@ public interface SlotDisplay { void write(FriendlyByteBuf buf); + default void applyClientboundData(Player player) { + } + static SlotDisplay read(FriendlyByteBuf buf) { return buf.readById(BuiltInRegistries.SLOT_DISPLAY_TYPE).read(buf); } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/SmithingTrimDemoSlotDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/SmithingTrimDemoSlotDisplay.java index cfc72cd7c..d6503e271 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/SmithingTrimDemoSlotDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/SmithingTrimDemoSlotDisplay.java @@ -6,6 +6,7 @@ import net.momirealms.craftengine.core.util.AdventureHelper; import net.momirealms.craftengine.core.util.FriendlyByteBuf; import net.momirealms.craftengine.core.util.Key; import net.momirealms.craftengine.core.util.VersionHelper; +import org.jetbrains.annotations.NotNull; public class SmithingTrimDemoSlotDisplay implements SlotDisplay { private final SlotDisplay base; @@ -46,6 +47,7 @@ public class SmithingTrimDemoSlotDisplay implements SlotDisplay { @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(5); this.base.write(buf); this.material.write(buf); if (VersionHelper.isOrAbove1_21_5()) { @@ -59,6 +61,25 @@ public class SmithingTrimDemoSlotDisplay implements SlotDisplay { } } + @Override + public String toString() { + return "SmithingTrimDemoSlotDisplay{" + + "base=" + base + + ", material=" + material + + ", trimPattern=" + trimPattern + + ", either=" + either + + '}'; + } + public record TrimPattern(Key assetId, Component description, boolean decal) { + + @Override + public @NotNull String toString() { + return "TrimPattern{" + + "assetId=" + assetId + + ", description=" + description + + ", decal=" + decal + + '}'; + } } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/TagSlotDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/TagSlotDisplay.java index 26753bee7..7d169c864 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/TagSlotDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/TagSlotDisplay.java @@ -16,6 +16,14 @@ public class TagSlotDisplay implements SlotDisplay { @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(4); buf.writeKey(this.tag); } + + @Override + public String toString() { + return "TagSlotDisplay{" + + "tag=" + tag + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/WithRemainderSlotDisplay.java b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/WithRemainderSlotDisplay.java index a5eeb4086..5f2030b6d 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/WithRemainderSlotDisplay.java +++ b/core/src/main/java/net/momirealms/craftengine/core/item/recipe/network/display/slot/WithRemainderSlotDisplay.java @@ -19,7 +19,16 @@ public class WithRemainderSlotDisplay implements SlotDisplay { @Override public void write(FriendlyByteBuf buf) { + buf.writeVarInt(6); this.input.write(buf); this.remainder.write(buf); } + + @Override + public String toString() { + return "WithRemainderSlotDisplay{" + + "input=" + input + + ", remainder=" + remainder + + '}'; + } } diff --git a/core/src/main/java/net/momirealms/craftengine/core/util/FriendlyByteBuf.java b/core/src/main/java/net/momirealms/craftengine/core/util/FriendlyByteBuf.java index 1629fda95..c31d1317f 100644 --- a/core/src/main/java/net/momirealms/craftengine/core/util/FriendlyByteBuf.java +++ b/core/src/main/java/net/momirealms/craftengine/core/util/FriendlyByteBuf.java @@ -413,6 +413,33 @@ public class FriendlyByteBuf extends ByteBuf { }); } + public Either, Key> readHolderSet() { + int id = this.readVarInt(); + if (id == 0) { + return Either.right(readKey()); + } else { + List list = new ArrayList<>(); + for (int i = 0; i < id - 1; ++i) { + list.add(readVarInt()); + } + return Either.left(list); + } + } + + public void writeHolderSet(Either, Key> holderSet) { + holderSet.ifLeft( + ints -> { + writeVarInt(ints.size() + 1); + for (Integer anInt : ints) { + writeVarInt(anInt); + } + } + ).ifRight(key -> { + writeVarInt(0); + writeKey(key); + }); + } + public FriendlyByteBuf writeVarLong(long value) { while ((value & -128L) != 0L) { this.writeByte((int) (value & 127L) | 128); diff --git a/gradle.properties b/gradle.properties index 53460da67..841342929 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx1G # Project settings # Rule: [major update].[feature update].[bug fix] -project_version=0.0.59.6 +project_version=0.0.59.7 config_version=41 lang_version=21 project_group=net.momirealms