From 3531eb5e5273ab3934500f53b69c902d7c32a7c7 Mon Sep 17 00:00:00 2001 From: Drex Date: Fri, 26 Jan 2024 18:06:47 +0100 Subject: [PATCH 1/4] Update to 24w04a --- build.gradle | 2 +- gradle.properties | 18 +++++++++--------- gradle/wrapper/gradle-wrapper.properties | 2 +- src/main/java/eu/pb4/sgui/api/GuiHelpers.java | 2 +- .../PlayerInteractEntityC2SPacketAccessor.java | 14 ++++++++++++++ .../mixin/ServerPlayNetworkHandlerMixin.java | 3 +-- src/main/resources/sgui.mixins.json | 1 + 7 files changed, 28 insertions(+), 14 deletions(-) create mode 100644 src/main/java/eu/pb4/sgui/mixin/PlayerInteractEntityC2SPacketAccessor.java diff --git a/build.gradle b/build.gradle index 6ab57a5..e180757 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ plugins { - id 'fabric-loom' version '0.12-SNAPSHOT' + id 'fabric-loom' version '1.5-SNAPSHOT' id 'maven-publish' } diff --git a/gradle.properties b/gradle.properties index f84fdc3..abdd3d1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,19 +2,19 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties - # check these on https://fabricmc.net/versions.html -minecraft_version=1.20.4 -yarn_mappings=1.20.4+build.1 -loader_version=0.15.1 +# check these on https://fabricmc.net/versions.html +minecraft_version=24w04a +yarn_mappings=24w04a+build.3 +loader_version=0.15.6 #Fabric api -fabric_version=0.91.1+1.20.4 +fabric_version=0.95.1+1.20.5 # Mod Properties - mod_version = 1.4.1+1.20.4 - maven_group = eu.pb4 - archives_base_name = sgui +mod_version = 1.4.1+1.20.5 +maven_group = eu.pb4 +archives_base_name = sgui # Dependencies - # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api +# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e750102..a595206 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/eu/pb4/sgui/api/GuiHelpers.java b/src/main/java/eu/pb4/sgui/api/GuiHelpers.java index d9dd3e7..df4343a 100644 --- a/src/main/java/eu/pb4/sgui/api/GuiHelpers.java +++ b/src/main/java/eu/pb4/sgui/api/GuiHelpers.java @@ -11,8 +11,8 @@ import net.minecraft.text.Style; import net.minecraft.text.TextColor; import net.minecraft.util.Formatting; +import org.jetbrains.annotations.Nullable; -import javax.annotation.Nullable; import java.util.function.UnaryOperator; public final class GuiHelpers { diff --git a/src/main/java/eu/pb4/sgui/mixin/PlayerInteractEntityC2SPacketAccessor.java b/src/main/java/eu/pb4/sgui/mixin/PlayerInteractEntityC2SPacketAccessor.java new file mode 100644 index 0000000..be7515e --- /dev/null +++ b/src/main/java/eu/pb4/sgui/mixin/PlayerInteractEntityC2SPacketAccessor.java @@ -0,0 +1,14 @@ +package eu.pb4.sgui.mixin; + +import net.minecraft.network.PacketByteBuf; +import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(PlayerInteractEntityC2SPacket.class) +public interface PlayerInteractEntityC2SPacketAccessor { + + @Invoker + void invokeWrite(PacketByteBuf buf); + +} diff --git a/src/main/java/eu/pb4/sgui/mixin/ServerPlayNetworkHandlerMixin.java b/src/main/java/eu/pb4/sgui/mixin/ServerPlayNetworkHandlerMixin.java index 76a1af8..2f436e0 100644 --- a/src/main/java/eu/pb4/sgui/mixin/ServerPlayNetworkHandlerMixin.java +++ b/src/main/java/eu/pb4/sgui/mixin/ServerPlayNetworkHandlerMixin.java @@ -17,7 +17,6 @@ import net.minecraft.network.ClientConnection; import net.minecraft.network.PacketByteBuf; import net.minecraft.network.message.LastSeenMessageList; -import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.c2s.play.*; import net.minecraft.network.packet.s2c.play.*; import net.minecraft.screen.ScreenHandler; @@ -295,7 +294,7 @@ public ServerPlayNetworkHandlerMixin(MinecraftServer server, ClientConnection co if (this.player.currentScreenHandler instanceof HotbarScreenHandler screenHandler) { var gui = screenHandler.getGui(); var buf = new PacketByteBuf(Unpooled.buffer()); - packet.write(buf); + ((PlayerInteractEntityC2SPacketAccessor)packet).invokeWrite(buf); int entityId = buf.readVarInt(); var type = buf.readEnumConstant(HotbarGui.EntityInteraction.class); diff --git a/src/main/resources/sgui.mixins.json b/src/main/resources/sgui.mixins.json index 02b1466..75bec4f 100644 --- a/src/main/resources/sgui.mixins.json +++ b/src/main/resources/sgui.mixins.json @@ -4,6 +4,7 @@ "package": "eu.pb4.sgui.mixin", "compatibilityLevel": "JAVA_17", "mixins": [ + "PlayerInteractEntityC2SPacketAccessor", "ScreenHandlerMixin", "ServerPlayerEntityMixin", "ServerPlayNetworkHandlerMixin", From 42e4fb8657cc8fb45be9310f4729881eafaa8d89 Mon Sep 17 00:00:00 2001 From: Drex Date: Sat, 2 Mar 2024 19:50:30 +0100 Subject: [PATCH 2/4] Update to 24w09a --- gradle.properties | 8 +- .../elements/AnimatedGuiElementBuilder.java | 205 +++++------------- .../sgui/api/elements/BookElementBuilder.java | 122 ++++------- .../sgui/api/elements/GuiElementBuilder.java | 204 ++++------------- .../eu/pb4/sgui/api/gui/AnvilInputGui.java | 3 +- .../java/eu/pb4/sgui/api/gui/MerchantGui.java | 3 +- .../java/eu/pb4/sgui/api/gui/SignGui.java | 2 +- .../inventory/VirtualScreenHandler.java | 2 +- .../VirtualMerchantScreenHandler.java | 7 +- .../virtual/sign/VirtualSignBlockEntity.java | 4 +- .../eu/pb4/sgui/testmod/BookInputGui.java | 18 +- .../java/eu/pb4/sgui/testmod/SGuiTest.java | 12 +- .../java/eu/pb4/sgui/testmod/SnakeGui.java | 53 ++--- 13 files changed, 206 insertions(+), 437 deletions(-) diff --git a/gradle.properties b/gradle.properties index abdd3d1..9e8213d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,12 +3,12 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/versions.html -minecraft_version=24w04a -yarn_mappings=24w04a+build.3 -loader_version=0.15.6 +minecraft_version=24w09a +yarn_mappings=24w09a+build.8 +loader_version=0.15.7 #Fabric api -fabric_version=0.95.1+1.20.5 +fabric_version=0.96.6+1.20.5 # Mod Properties diff --git a/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java b/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java index 48d9317..aecf58e 100644 --- a/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java +++ b/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java @@ -2,20 +2,20 @@ import com.mojang.authlib.GameProfile; import com.mojang.authlib.minecraft.MinecraftProfileTextures; -import eu.pb4.sgui.api.GuiHelpers; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.CustomModelDataComponent; +import net.minecraft.component.type.LoreComponent; +import net.minecraft.component.type.ProfileComponent; +import net.minecraft.component.type.UnbreakableComponent; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtHelper; -import net.minecraft.nbt.NbtList; -import net.minecraft.nbt.NbtString; import net.minecraft.server.MinecraftServer; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; -import net.minecraft.util.Util; +import net.minecraft.util.Unit; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -32,16 +32,9 @@ */ @SuppressWarnings({"unused"}) public class AnimatedGuiElementBuilder implements GuiElementBuilderInterface { - protected final Map enchantments = new HashMap<>(); protected final List itemStacks = new ArrayList<>(); - protected Item item = Items.STONE; - protected NbtCompound tag; - protected int count = 1; - protected Text name = null; - protected List lore = new ArrayList<>(); - protected int damage = -1; + protected ItemStack itemStack = new ItemStack(Items.STONE); protected GuiElement.ClickCallback callback = GuiElement.EMPTY_CALLBACK; - protected byte hideFlags = 0; protected int interval = 1; protected boolean random = false; @@ -82,175 +75,130 @@ public AnimatedGuiElementBuilder setRandom(boolean value) { * @return this element builder */ public AnimatedGuiElementBuilder saveItemStack() { - this.itemStacks.add(asStack()); - - this.item = Items.STONE; - this.tag = null; - this.count = 1; - this.name = null; - this.lore = new ArrayList<>(); - this.damage = -1; - this.hideFlags = 0; - this.enchantments.clear(); - + this.itemStacks.add(this.itemStack.copy()); + this.itemStack = new ItemStack(Items.STONE); return this; } /** - * Sets the type of Item of the current element. + * Sets the type of Item of the element. * * @param item the item to use * @return this element builder */ public AnimatedGuiElementBuilder setItem(Item item) { - this.item = item; + this.itemStack = new ItemStack(item.getRegistryEntry(), this.itemStack.getCount(), this.itemStack.getComponentChanges()); return this; } /** - * Sets the name of the current element. + * Sets the name of the element. * * @param name the name to use * @return this element builder */ public AnimatedGuiElementBuilder setName(Text name) { - this.name = name.copy(); + this.itemStack.set(DataComponentTypes.CUSTOM_NAME, name.copy()); return this; } /** - * Sets the number of items in the current element. + * Sets the number of items in the element. * * @param count the number of items * @return this element builder */ public AnimatedGuiElementBuilder setCount(int count) { - this.count = count; + this.itemStack.setCount(count); return this; } /** - * Sets the lore lines of the current element. + * Sets the lore lines of the element. * * @param lore a list of all the lore lines * @return this element builder */ public AnimatedGuiElementBuilder setLore(List lore) { - this.lore = lore; + this.itemStack.set(DataComponentTypes.LORE, new LoreComponent(lore)); return this; } /** - * Adds a line of lore to the current element. + * Adds a line of lore to the element. * * @param lore the line to add * @return this element builder */ public AnimatedGuiElementBuilder addLoreLine(Text lore) { - this.lore.add(lore); + this.itemStack.apply(DataComponentTypes.LORE, LoreComponent.DEFAULT, lore, LoreComponent::of); return this; } /** - * Set the damage of the current element. This will only be + * Set the damage of the element. This will only be * visible if the item supports has durability. * * @param damage the amount of durability the item is missing * @return this element builder */ public AnimatedGuiElementBuilder setDamage(int damage) { - this.damage = damage; + this.itemStack.set(DataComponentTypes.DAMAGE, damage); return this; } /** - * Hides all {@link net.minecraft.item.ItemStack.TooltipSection}s from the current element display + * Hides all Tooltips added through this builder from the element display * * @return this element builder */ public AnimatedGuiElementBuilder hideFlags() { - this.hideFlags = 127; - return this; - } - - /** - * Hides a {@link net.minecraft.item.ItemStack.TooltipSection} - * from the current elements display. - * - * @param section the section to hide - * @return this element builder - */ - public AnimatedGuiElementBuilder hideFlag(ItemStack.TooltipSection section) { - this.hideFlags = (byte) (this.hideFlags | section.getFlag()); + // TODO 1.20.5 + this.itemStack.set(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE); return this; } /** - * Set the {@link net.minecraft.item.ItemStack.TooltipSection}s to - * hide from the current elements display, by the flags. - * - * @param value the flags to hide - * @return this element builder - * @see AnimatedGuiElementBuilder#hideFlag(ItemStack.TooltipSection) - */ - public AnimatedGuiElementBuilder hideFlags(byte value) { - this.hideFlags = value; - return this; - } - - /** - * Give the current element the specified enchantment. + * Give the element the specified enchantment. * * @param enchantment the enchantment to apply * @param level the level of the specified enchantment * @return this element builder */ public AnimatedGuiElementBuilder enchant(Enchantment enchantment, int level) { - this.enchantments.put(enchantment, level); + this.itemStack.addEnchantment(enchantment, level); return this; } /** - * Sets the current element to have an enchantment glint. + * Sets the element to have an enchantment glint. * * @return this element builder */ public AnimatedGuiElementBuilder glow() { - this.enchantments.put(Enchantments.LUCK_OF_THE_SEA, 1); - return hideFlag(ItemStack.TooltipSection.ENCHANTMENTS); + this.itemStack.set(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, true); + return this; } /** - * Sets the custom model data of the current element. + * Sets the custom model data of the element. * * @param value the value used for custom model data * @return this element builder */ public AnimatedGuiElementBuilder setCustomModelData(int value) { - this.getOrCreateNbt().putInt("CustomModelData", value); + this.itemStack.set(DataComponentTypes.CUSTOM_MODEL_DATA, new CustomModelDataComponent(value)); return this; } /** - * Sets the current element to be unbreakable, also hides the durability bar. + * Sets the element to be unbreakable, also hides the durability bar. * * @return this element builder */ public AnimatedGuiElementBuilder unbreakable() { - this.getOrCreateNbt().putBoolean("Unbreakable", true); - return hideFlag(ItemStack.TooltipSection.UNBREAKABLE); - } - - /** - * Sets the skull owner tag of a player head. - * This method uses raw values required by client to display the skin - * Ideal for textures generated with 3rd party websites like mineskin.org - * - * @param value texture value used by client - * @return this element builder - */ - public AnimatedGuiElementBuilder setSkullOwner(String value) { - return this.setSkullOwner(value, null, null); + this.itemStack.set(DataComponentTypes.UNBREAKABLE, new UnbreakableComponent(true)); + return this; } /** @@ -272,13 +220,25 @@ public AnimatedGuiElementBuilder setSkullOwner(GameProfile profile, @Nullable Mi if (tmp != null) { profile = tmp.profile(); } - } this.getOrCreateNbt().put("SkullOwner", NbtHelper.writeGameProfile(new NbtCompound(), profile)); - } else { - this.getOrCreateNbt().putString("SkullOwner", profile.getName()); + } + } + this.itemStack.set(DataComponentTypes.PROFILE, new ProfileComponent(profile)); return this; } + /** + * Sets the skull owner tag of a player head. + * This method uses raw values required by client to display the skin + * Ideal for textures generated with 3rd party websites like mineskin.org + * + * @param value texture value used by client + * @return this element builder + */ + public AnimatedGuiElementBuilder setSkullOwner(String value) { + return this.setSkullOwner(value, null, null); + } + /** * Sets the skull owner tag of a player head. * This method uses raw values required by client to display the skin @@ -290,23 +250,9 @@ public AnimatedGuiElementBuilder setSkullOwner(GameProfile profile, @Nullable Mi * @return this element builder */ public AnimatedGuiElementBuilder setSkullOwner(String value, @Nullable String signature, @Nullable UUID uuid) { - NbtCompound skullOwner = new NbtCompound(); - NbtCompound properties = new NbtCompound(); - NbtCompound valueData = new NbtCompound(); - NbtList textures = new NbtList(); - - valueData.putString("Value", value); - if (signature != null) { - valueData.putString("Signature", signature); - } - - textures.add(valueData); - properties.put("textures", textures); - - skullOwner.put("Id", NbtHelper.fromUuid(uuid != null ? uuid : Util.NIL_UUID)); - skullOwner.put("Properties", properties); - this.getOrCreateNbt().put("SkullOwner", skullOwner); - + PropertyMap map = new PropertyMap(); + map.put("textures", new Property("textures", value, signature)); + this.itemStack.set(DataComponentTypes.PROFILE, new ProfileComponent("???", Optional.ofNullable(uuid), map)); return this; } @@ -331,48 +277,7 @@ public AnimatedGuiElementBuilder setCallback(GuiElementInterface.ItemClickCallba * @see AnimatedGuiElementBuilder#build() */ public ItemStack asStack() { - ItemStack itemStack = new ItemStack(this.item, this.count); - - if (this.tag != null) { - itemStack.getOrCreateNbt().copyFrom(this.tag); - } - - if (this.name != null) { - var name = this.name.copy().styled(GuiHelpers.STYLE_CLEARER); - - itemStack.setCustomName(name); - } - - if (this.item.isDamageable() && this.damage != -1) { - itemStack.setDamage(damage); - } - - for (Map.Entry entry : this.enchantments.entrySet()) { - itemStack.addEnchantment(entry.getKey(), entry.getValue()); - } - - if (this.lore.size() > 0) { - NbtCompound display = itemStack.getOrCreateSubNbt("display"); - NbtList loreItems = new NbtList(); - for (Text l : this.lore) { - l = l.copy().styled(GuiHelpers.STYLE_CLEARER); - loreItems.add(NbtString.of(Text.Serialization.toJsonString(l))); - } - display.put("Lore", loreItems); - } - - if (this.hideFlags != 0) { - itemStack.getOrCreateNbt().putByte("HideFlags", this.hideFlags); - } - - return itemStack; - } - - public NbtCompound getOrCreateNbt() { - if (this.tag == null) { - this.tag = new NbtCompound(); - } - return this.tag; + return this.itemStack.copy(); } public AnimatedGuiElement build() { diff --git a/src/main/java/eu/pb4/sgui/api/elements/BookElementBuilder.java b/src/main/java/eu/pb4/sgui/api/elements/BookElementBuilder.java index d8e02b3..df8d331 100644 --- a/src/main/java/eu/pb4/sgui/api/elements/BookElementBuilder.java +++ b/src/main/java/eu/pb4/sgui/api/elements/BookElementBuilder.java @@ -1,5 +1,7 @@ package eu.pb4.sgui.api.elements; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.WrittenBookContentComponent; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -7,8 +9,13 @@ import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtString; import net.minecraft.registry.tag.ItemTags; +import net.minecraft.text.RawFilteredPair; import net.minecraft.text.Text; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + /** * Book Element Builder *
@@ -21,6 +28,8 @@ @SuppressWarnings({"unused"}) public class BookElementBuilder extends GuiElementBuilder { + private static final WrittenBookContentComponent DEFAULT_WRITTEN_COMPONENT = new WrittenBookContentComponent(RawFilteredPair.of(""), "", 0, Collections.emptyList(), false); + /** * Constructs a new BookElementBuilder with the default settings. */ @@ -38,6 +47,10 @@ public BookElementBuilder(int count) { super(Items.WRITTEN_BOOK, count); } + private BookElementBuilder(ItemStack stack) { + super(stack); + } + /** * Adds a new page to the book.
* Note that only signed books support formatting @@ -47,11 +60,15 @@ public BookElementBuilder(int count) { * @see BookElementBuilder#setPage(int, Text...) */ public BookElementBuilder addPage(Text... lines) { - var text = Text.literal(""); - for (Text line : lines) { - text.append(line).append("\n"); - } - this.getOrCreatePages().add(NbtString.of(Text.Serialization.toJsonString(text))); + this.itemStack.apply(DataComponentTypes.WRITTEN_BOOK_CONTENT, DEFAULT_WRITTEN_COMPONENT, original -> { + List> updatedPages = new LinkedList<>(original.pages()); + var text = Text.empty(); + for (Text line : lines) { + text.append(line).append("\n"); + } + updatedPages.add(RawFilteredPair.of(text)); + return new WrittenBookContentComponent(original.title(), original.author(), original.generation(), updatedPages, original.resolved()); + }); return this; } @@ -66,11 +83,16 @@ public BookElementBuilder addPage(Text... lines) { * @see BookElementBuilder#addPage(Text...) */ public BookElementBuilder setPage(int index, Text... lines) { - var text = Text.literal(""); - for (Text line : lines) { - text.append(line).append("\n"); - } - this.getOrCreatePages().set(index, NbtString.of(Text.Serialization.toJsonString(text))); + this.itemStack.apply(DataComponentTypes.WRITTEN_BOOK_CONTENT, DEFAULT_WRITTEN_COMPONENT, original -> { + List> updatedPages = new LinkedList<>(original.pages()); + var text = Text.empty(); + for (Text line : lines) { + text.append(line).append("\n"); + } + updatedPages.set(index, RawFilteredPair.of(text)); + return new WrittenBookContentComponent(original.title(), original.author(), original.generation(), updatedPages, original.resolved()); + }); + return this; } @@ -82,7 +104,9 @@ public BookElementBuilder setPage(int index, Text... lines) { * @return this book builder */ public BookElementBuilder setAuthor(String author) { - this.getOrCreateNbt().put("author", NbtString.of(author)); + this.itemStack.apply(DataComponentTypes.WRITTEN_BOOK_CONTENT, DEFAULT_WRITTEN_COMPONENT, original -> { + return new WrittenBookContentComponent(original.title(), author, original.generation(), original.pages(), original.resolved()); + }); this.signed(); return this; } @@ -95,7 +119,9 @@ public BookElementBuilder setAuthor(String author) { * @return this book builder */ public BookElementBuilder setTitle(String title) { - this.getOrCreateNbt().put("title", NbtString.of(title)); + this.itemStack.apply(DataComponentTypes.WRITTEN_BOOK_CONTENT, DEFAULT_WRITTEN_COMPONENT, original -> { + return new WrittenBookContentComponent(RawFilteredPair.of(title), original.author(), original.generation(), original.pages(), original.resolved()); + }); this.signed(); return this; } @@ -125,19 +151,11 @@ public BookElementBuilder unSigned() { return this; } - protected NbtList getOrCreatePages() { - if (!this.getOrCreateNbt().contains("pages")) { - this.getOrCreateNbt().put("pages", new NbtList()); - } - return this.getOrCreateNbt().getList("pages", NbtElement.STRING_TYPE); - } - @Override public GuiElementBuilder setItem(Item item) { if (!(item.getRegistryEntry().isIn(ItemTags.LECTERN_BOOKS))) { throw new IllegalArgumentException("Item must be a type of book"); } - return super.setItem(item); } @@ -150,29 +168,10 @@ public GuiElementBuilder setItem(Item item) { */ @Override public ItemStack asStack() { - if (this.item == Items.WRITTEN_BOOK) { - if (!this.getOrCreateNbt().contains("author")) { - this.getOrCreateNbt().put("author", NbtString.of("")); - } - if (!this.getOrCreateNbt().contains("title")) { - this.getOrCreateNbt().put("title", NbtString.of("")); - } - } else if (this.item == Items.WRITABLE_BOOK){ - NbtList pages = this.getOrCreatePages(); - for (int i = 0; i < pages.size(); i++) { - try { - pages.set(i, NbtString.of(Text.Serialization.fromLenientJson(pages.getString(i)).getString())); - } catch (Exception e) { - pages.set(i, NbtString.of("Invalid page data!")); - } - } - this.getOrCreateNbt().put("pages", pages); - - this.getOrCreateNbt().remove("author"); - this.getOrCreateNbt().remove("title"); + if (!itemStack.contains(DataComponentTypes.WRITTEN_BOOK_CONTENT)) { + itemStack.set(DataComponentTypes.WRITTEN_BOOK_CONTENT, DEFAULT_WRITTEN_COMPONENT); } - - return super.asStack(); + return this.itemStack.copy(); } /** @@ -193,25 +192,7 @@ public static BookElementBuilder from(ItemStack book) { if (!book.getItem().getRegistryEntry().isIn(ItemTags.LECTERN_BOOKS)) { throw new IllegalArgumentException("Item must be a type of book"); } - - BookElementBuilder builder = new BookElementBuilder(book.getCount()); - - if (book.getOrCreateNbt().contains("title")) { - builder.setTitle(book.getOrCreateNbt().getString("title")); - } - - if (book.getOrCreateNbt().contains("author")) { - builder.setTitle(book.getOrCreateNbt().getString("author")); - } - - if (book.getOrCreateNbt().contains("pages")) { - NbtList pages = book.getOrCreateNbt().getList("pages", NbtElement.STRING_TYPE); - for (NbtElement page : pages) { - builder.addPage(Text.Serialization.fromLenientJson(page.asString())); - } - } - - return builder; + return new BookElementBuilder(book); } /** @@ -222,19 +203,16 @@ public static BookElementBuilder from(ItemStack book) { * @return the contents of the page or empty if page does not exist * @throws IllegalArgumentException if the item is not a book */ + @Deprecated public static Text getPageContents(ItemStack book, int index) { if (!book.getItem().getRegistryEntry().isIn(ItemTags.LECTERN_BOOKS)) { throw new IllegalArgumentException("Item must be a type of book"); } - - if (book.getOrCreateNbt().contains("pages")) { - NbtList pages = book.getOrCreateNbt().getList("pages", NbtElement.STRING_TYPE); - if(index < pages.size()) { - return Text.Serialization.fromJson(pages.get(index).asString()); - } + WrittenBookContentComponent component = book.getOrDefault(DataComponentTypes.WRITTEN_BOOK_CONTENT, DEFAULT_WRITTEN_COMPONENT); + if (index < component.pages().size()) { + return component.pages().get(index).raw(); } - - return Text.literal(""); + return Text.empty(); } /** @@ -245,11 +223,7 @@ public static Text getPageContents(ItemStack book, int index) { * @return the contents of the page or empty if page does not exist */ public static Text getPageContents(BookElementBuilder book, int index) { - NbtList pages = book.getOrCreatePages(); - if(index < pages.size()) { - return Text.Serialization.fromJson(pages.get(index).asString()); - } - return Text.literal(""); + return getPageContents(book.itemStack, index); } } diff --git a/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java b/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java index 04392b6..c9f9656 100644 --- a/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java +++ b/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java @@ -2,25 +2,23 @@ import com.mojang.authlib.GameProfile; import com.mojang.authlib.minecraft.MinecraftProfileTextures; -import eu.pb4.sgui.api.GuiHelpers; +import com.mojang.authlib.properties.Property; +import com.mojang.authlib.properties.PropertyMap; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.CustomModelDataComponent; +import net.minecraft.component.type.LoreComponent; +import net.minecraft.component.type.ProfileComponent; +import net.minecraft.component.type.UnbreakableComponent; import net.minecraft.enchantment.Enchantment; -import net.minecraft.enchantment.Enchantments; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.nbt.*; -import net.minecraft.registry.Registries; import net.minecraft.server.MinecraftServer; -import net.minecraft.text.MutableText; import net.minecraft.text.Text; -import net.minecraft.text.TextColor; -import net.minecraft.util.Formatting; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; +import net.minecraft.util.Unit; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.stream.Collectors; /** * Gui Element Builder @@ -32,15 +30,8 @@ */ @SuppressWarnings({"unused"}) public class GuiElementBuilder implements GuiElementBuilderInterface { - protected final Map enchantments = new HashMap<>(); - protected Item item = Items.STONE; - protected NbtCompound tag; - protected int count = 1; - protected Text name = null; - protected List lore = new ArrayList<>(); - protected int damage = -1; + protected ItemStack itemStack = new ItemStack(Items.STONE); protected GuiElement.ClickCallback callback = GuiElementInterface.EMPTY_CALLBACK; - protected byte hideFlags = 0; /** * Constructs a GuiElementBuilder with the default options @@ -54,7 +45,7 @@ public GuiElementBuilder() { * @param item the item to use */ public GuiElementBuilder(Item item) { - this.item = item; + this.itemStack = new ItemStack(item); } /** @@ -65,8 +56,16 @@ public GuiElementBuilder(Item item) { * @param count the number of items */ public GuiElementBuilder(Item item, int count) { - this.item = item; - this.count = count; + this.itemStack = new ItemStack(item, count); + } + + /** + * Constructs a GuiElementBuilder with the specified ItemStack + * + * @param stack the item stack to use + */ + public GuiElementBuilder(ItemStack stack) { + this.itemStack = stack.copy(); } /** @@ -76,46 +75,12 @@ public GuiElementBuilder(Item item, int count) { * @return the constructed builder */ public static GuiElementBuilder from(ItemStack stack) { - GuiElementBuilder builder = new GuiElementBuilder(stack.getItem(), stack.getCount()); - if (!stack.hasNbt()) { - return builder; - } - NbtCompound tag = stack.getNbt().copy(); - - if (stack.hasCustomName()) { - builder.setName(stack.getName()); - tag.getCompound("display").remove("Name"); - } - - if (tag.contains("display") && tag.getCompound("display").contains("Lore")) { - builder.setLore(GuiElementBuilder.getLore(stack)); - tag.getCompound("display").remove("Lore"); - } - - if (stack.isDamaged()) { - builder.setDamage(stack.getDamage()); - tag.remove("Damage"); - } - - if (stack.hasEnchantments()) { - for (NbtElement enc : stack.getEnchantments()) { - Registries.ENCHANTMENT.getOrEmpty(Identifier.tryParse(((NbtCompound) enc).getString("id"))).ifPresent(enchantment -> builder.enchant(enchantment, ((NbtCompound) enc).getInt("lvl"))); - } - tag.remove("Enchantments"); - } - - if (stack.getOrCreateNbt().contains("HideFlags")) { - builder.hideFlags(stack.getOrCreateNbt().getByte("HideFlags")); - tag.remove("HideFlags"); - } - - builder.tag = tag; - - return builder; + return new GuiElementBuilder(stack); } + @Deprecated public static List getLore(ItemStack stack) { - return stack.getOrCreateSubNbt("display").getList("Lore", NbtElement.STRING_TYPE).stream().map(tag -> Text.Serialization.fromJson(tag.asString())).collect(Collectors.toList()); + return stack.getOrDefault(DataComponentTypes.LORE, LoreComponent.DEFAULT).lines(); } /** @@ -125,7 +90,7 @@ public static List getLore(ItemStack stack) { * @return this element builder */ public GuiElementBuilder setItem(Item item) { - this.item = item; + this.itemStack = new ItemStack(item.getRegistryEntry(), this.itemStack.getCount(), this.itemStack.getComponentChanges()); return this; } @@ -136,7 +101,7 @@ public GuiElementBuilder setItem(Item item) { * @return this element builder */ public GuiElementBuilder setName(Text name) { - this.name = name.copy(); + this.itemStack.set(DataComponentTypes.CUSTOM_NAME, name.copy()); return this; } @@ -147,7 +112,7 @@ public GuiElementBuilder setName(Text name) { * @return this element builder */ public GuiElementBuilder setCount(int count) { - this.count = count; + this.itemStack.setCount(count); return this; } @@ -158,7 +123,7 @@ public GuiElementBuilder setCount(int count) { * @return this element builder */ public GuiElementBuilder setLore(List lore) { - this.lore = lore; + this.itemStack.set(DataComponentTypes.LORE, new LoreComponent(lore)); return this; } @@ -169,7 +134,7 @@ public GuiElementBuilder setLore(List lore) { * @return this element builder */ public GuiElementBuilder addLoreLine(Text lore) { - this.lore.add(lore); + this.itemStack.apply(DataComponentTypes.LORE, LoreComponent.DEFAULT, lore, LoreComponent::of); return this; } @@ -181,42 +146,18 @@ public GuiElementBuilder addLoreLine(Text lore) { * @return this element builder */ public GuiElementBuilder setDamage(int damage) { - this.damage = damage; + this.itemStack.set(DataComponentTypes.DAMAGE, damage); return this; } /** - * Hides all {@link net.minecraft.item.ItemStack.TooltipSection}s from the element display + * Hides all Tooltips added through this builder from the element display * * @return this element builder */ public GuiElementBuilder hideFlags() { - this.hideFlags = (byte) 0xFF; - return this; - } - - /** - * Hides a {@link net.minecraft.item.ItemStack.TooltipSection} - * from the elements display. - * - * @param section the section to hide - * @return this element builder - */ - public GuiElementBuilder hideFlag(ItemStack.TooltipSection section) { - this.hideFlags = (byte) (this.hideFlags | section.getFlag()); - return this; - } - - /** - * Set the {@link net.minecraft.item.ItemStack.TooltipSection}s to - * hide from the elements display, by the flags. - * - * @param value the flags to hide - * @return this element builder - * @see GuiElementBuilder#hideFlag(ItemStack.TooltipSection) - */ - public GuiElementBuilder hideFlags(byte value) { - this.hideFlags = value; + // TODO 1.20.5 + this.itemStack.set(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE); return this; } @@ -228,7 +169,7 @@ public GuiElementBuilder hideFlags(byte value) { * @return this element builder */ public GuiElementBuilder enchant(Enchantment enchantment, int level) { - this.enchantments.put(enchantment, level); + this.itemStack.addEnchantment(enchantment, level); return this; } @@ -238,8 +179,8 @@ public GuiElementBuilder enchant(Enchantment enchantment, int level) { * @return this element builder */ public GuiElementBuilder glow() { - this.enchantments.put(Enchantments.LUCK_OF_THE_SEA, 1); - return hideFlag(ItemStack.TooltipSection.ENCHANTMENTS); + this.itemStack.set(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, true); + return this; } /** @@ -249,7 +190,7 @@ public GuiElementBuilder glow() { * @return this element builder */ public GuiElementBuilder setCustomModelData(int value) { - this.getOrCreateNbt().putInt("CustomModelData", value); + this.itemStack.set(DataComponentTypes.CUSTOM_MODEL_DATA, new CustomModelDataComponent(value)); return this; } @@ -259,8 +200,8 @@ public GuiElementBuilder setCustomModelData(int value) { * @return this element builder */ public GuiElementBuilder unbreakable() { - this.getOrCreateNbt().putBoolean("Unbreakable", true); - return hideFlag(ItemStack.TooltipSection.UNBREAKABLE); + this.itemStack.set(DataComponentTypes.UNBREAKABLE, new UnbreakableComponent(true)); + return this; } /** @@ -284,10 +225,8 @@ public GuiElementBuilder setSkullOwner(GameProfile profile, @Nullable MinecraftS } } - this.getOrCreateNbt().put("SkullOwner", NbtHelper.writeGameProfile(new NbtCompound(), profile)); - } else { - this.getOrCreateNbt().putString("SkullOwner", profile.getName()); } + this.itemStack.set(DataComponentTypes.PROFILE, new ProfileComponent(profile)); return this; } @@ -314,23 +253,9 @@ public GuiElementBuilder setSkullOwner(String value) { * @return this element builder */ public GuiElementBuilder setSkullOwner(String value, @Nullable String signature, @Nullable UUID uuid) { - NbtCompound skullOwner = new NbtCompound(); - NbtCompound properties = new NbtCompound(); - NbtCompound valueData = new NbtCompound(); - NbtList textures = new NbtList(); - - valueData.putString("Value", value); - if (signature != null) { - valueData.putString("Signature", signature); - } - - textures.add(valueData); - properties.put("textures", textures); - - skullOwner.put("Id", NbtHelper.fromUuid(uuid != null ? uuid : Util.NIL_UUID)); - skullOwner.put("Properties", properties); - this.getOrCreateNbt().put("SkullOwner", skullOwner); - + PropertyMap map = new PropertyMap(); + map.put("textures", new Property("textures", value, signature)); + this.itemStack.set(DataComponentTypes.PROFILE, new ProfileComponent("???", Optional.ofNullable(uuid), map)); return this; } @@ -355,52 +280,11 @@ public GuiElementBuilder setCallback(GuiElementInterface.ItemClickCallback callb * @see GuiElementBuilder#build() */ public ItemStack asStack() { - ItemStack itemStack = new ItemStack(this.item, this.count); - - if (this.tag != null) { - itemStack.getOrCreateNbt().copyFrom(this.tag); - } - - if (this.name != null) { - var name = this.name.copy().styled(GuiHelpers.STYLE_CLEARER); - - itemStack.setCustomName(name); - } - - if (this.item.isDamageable() && this.damage != -1) { - itemStack.setDamage(damage); - } - - for (Map.Entry entry : this.enchantments.entrySet()) { - itemStack.addEnchantment(entry.getKey(), entry.getValue()); - } - - if (this.lore.size() > 0) { - NbtCompound display = itemStack.getOrCreateSubNbt("display"); - NbtList loreItems = new NbtList(); - for (Text l : this.lore) { - l = l.copy().styled(GuiHelpers.STYLE_CLEARER); - loreItems.add(NbtString.of(Text.Serialization.toJsonString(l))); - } - display.put("Lore", loreItems); - } - - if (this.hideFlags != 0) { - itemStack.getOrCreateNbt().putByte("HideFlags", this.hideFlags); - } - - return itemStack; - } - - public NbtCompound getOrCreateNbt() { - if (this.tag == null) { - this.tag = new NbtCompound(); - } - return this.tag; + return itemStack.copy(); } @Override public GuiElement build() { - return new GuiElement(asStack(), this.callback); + return new GuiElement(this.itemStack, this.callback); } } diff --git a/src/main/java/eu/pb4/sgui/api/gui/AnvilInputGui.java b/src/main/java/eu/pb4/sgui/api/gui/AnvilInputGui.java index 7061fc4..d9394d5 100644 --- a/src/main/java/eu/pb4/sgui/api/gui/AnvilInputGui.java +++ b/src/main/java/eu/pb4/sgui/api/gui/AnvilInputGui.java @@ -2,6 +2,7 @@ import eu.pb4.sgui.api.GuiHelpers; import eu.pb4.sgui.api.elements.GuiElementInterface; +import net.minecraft.component.DataComponentTypes; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.screen.ScreenHandlerType; @@ -44,7 +45,7 @@ public AnvilInputGui(ServerPlayerEntity player, boolean manipulatePlayerSlots) { */ public void setDefaultInputValue(String input) { ItemStack itemStack = Items.PAPER.getDefaultStack(); - itemStack.setCustomName(Text.literal(input)); + itemStack.set(DataComponentTypes.CUSTOM_NAME, Text.literal(input)); this.inputText = input; this.defaultText = input; this.setSlot(0, itemStack, ((index, type1, action, gui) -> { diff --git a/src/main/java/eu/pb4/sgui/api/gui/MerchantGui.java b/src/main/java/eu/pb4/sgui/api/gui/MerchantGui.java index 79cc71c..8757d37 100644 --- a/src/main/java/eu/pb4/sgui/api/gui/MerchantGui.java +++ b/src/main/java/eu/pb4/sgui/api/gui/MerchantGui.java @@ -13,6 +13,7 @@ import net.minecraft.village.MerchantInventory; import net.minecraft.village.TradeOffer; import net.minecraft.village.TradeOfferList; +import net.minecraft.village.TradedItem; import org.jetbrains.annotations.Nullable; import java.util.Arrays; @@ -64,7 +65,7 @@ public static boolean areTradeOffersEqualIgnoreUses(@Nullable TradeOffer x, @Nul && x.getSpecialPrice() == y.getSpecialPrice() && ItemStack.areEqual(x.getSellItem(), y.getSellItem()) && ItemStack.areEqual(x.getOriginalFirstBuyItem(), y.getOriginalFirstBuyItem()) - && ItemStack.areEqual(x.getSecondBuyItem(), y.getSecondBuyItem()); + && ItemStack.areEqual(x.getSecondBuyItem().map(TradedItem::itemStack).orElse(ItemStack.EMPTY), y.getSecondBuyItem().map(TradedItem::itemStack).orElse(ItemStack.EMPTY)); } diff --git a/src/main/java/eu/pb4/sgui/api/gui/SignGui.java b/src/main/java/eu/pb4/sgui/api/gui/SignGui.java index 6241f80..30c06a9 100644 --- a/src/main/java/eu/pb4/sgui/api/gui/SignGui.java +++ b/src/main/java/eu/pb4/sgui/api/gui/SignGui.java @@ -57,7 +57,7 @@ public class SignGui implements GuiInterface { */ public SignGui(ServerPlayerEntity player) { this.player = player; - this.signEntity = new VirtualSignBlockEntity(new BlockPos(player.getBlockPos().getX(), Math.min(player.getWorld().getTopY() - 1, player.getBlockPos().getY() + 5), player.getBlockPos().getZ()), Blocks.OAK_SIGN.getDefaultState()); + this.signEntity = new VirtualSignBlockEntity(player.getWorld(), new BlockPos(player.getBlockPos().getX(), Math.min(player.getWorld().getTopY() - 1, player.getBlockPos().getY() + 5), player.getBlockPos().getZ()), Blocks.OAK_SIGN.getDefaultState()); } /** diff --git a/src/main/java/eu/pb4/sgui/virtual/inventory/VirtualScreenHandler.java b/src/main/java/eu/pb4/sgui/virtual/inventory/VirtualScreenHandler.java index bc29da0..71b7a59 100644 --- a/src/main/java/eu/pb4/sgui/virtual/inventory/VirtualScreenHandler.java +++ b/src/main/java/eu/pb4/sgui/virtual/inventory/VirtualScreenHandler.java @@ -158,7 +158,7 @@ protected boolean insertItem(ItemStack stack, int startIndex, int endIndex, bool itemStack = slot2.getStack(); - if (!(slot2 instanceof VirtualSlot) && stack != itemStack && !itemStack.isEmpty() && ItemStack.canCombine(stack, itemStack) && slot2.canInsert(stack)) { + if (!(slot2 instanceof VirtualSlot) && stack != itemStack && !itemStack.isEmpty() && ItemStack.areItemsAndComponentsEqual(stack, itemStack) && slot2.canInsert(stack)) { int j = itemStack.getCount() + stack.getCount(); int max = Math.min(slot2.getMaxItemCount(), stack.getMaxCount()); if (j <= max) { diff --git a/src/main/java/eu/pb4/sgui/virtual/merchant/VirtualMerchantScreenHandler.java b/src/main/java/eu/pb4/sgui/virtual/merchant/VirtualMerchantScreenHandler.java index fcf63a9..538e652 100644 --- a/src/main/java/eu/pb4/sgui/virtual/merchant/VirtualMerchantScreenHandler.java +++ b/src/main/java/eu/pb4/sgui/virtual/merchant/VirtualMerchantScreenHandler.java @@ -9,6 +9,7 @@ import net.minecraft.screen.slot.Slot; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.village.MerchantInventory; +import net.minecraft.village.TradedItem; public class VirtualMerchantScreenHandler extends VirtualScreenHandler { @@ -124,9 +125,9 @@ public void selectNewTrade(int tradeIndex) { } if (this.merchantInventory.getStack(0).isEmpty() && this.merchantInventory.getStack(1).isEmpty()) { - ItemStack itemStack3 = this.merchant.getOffers().get(tradeIndex).getAdjustedFirstBuyItem(); + ItemStack itemStack3 = this.merchant.getOffers().get(tradeIndex).getDisplayedFirstBuyItem(); this.autofill(0, itemStack3); - ItemStack itemStack4 = this.merchant.getOffers().get(tradeIndex).getSecondBuyItem(); + ItemStack itemStack4 = this.merchant.getOffers().get(tradeIndex).getSecondBuyItem().map(TradedItem::itemStack).orElse(ItemStack.EMPTY); this.autofill(1, itemStack4); } @@ -137,7 +138,7 @@ private void autofill(int slot, ItemStack stack) { if (!stack.isEmpty()) { for(int i = 3; i < 39; ++i) { ItemStack itemStack = this.slots.get(i).getStack(); - if (!itemStack.isEmpty() && ItemStack.canCombine(stack, itemStack)) { + if (!itemStack.isEmpty() && ItemStack.areItemsAndComponentsEqual(stack, itemStack)) { ItemStack itemStack2 = this.merchantInventory.getStack(slot); int j = itemStack2.isEmpty() ? 0 : itemStack2.getCount(); int k = Math.min(stack.getMaxCount() - j, itemStack.getCount()); diff --git a/src/main/java/eu/pb4/sgui/virtual/sign/VirtualSignBlockEntity.java b/src/main/java/eu/pb4/sgui/virtual/sign/VirtualSignBlockEntity.java index eac5264..df9344c 100644 --- a/src/main/java/eu/pb4/sgui/virtual/sign/VirtualSignBlockEntity.java +++ b/src/main/java/eu/pb4/sgui/virtual/sign/VirtualSignBlockEntity.java @@ -5,14 +5,16 @@ import net.minecraft.block.entity.SignBlockEntity; import net.minecraft.block.entity.SignText; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; /** * SignBlockEntity which doesn't invoke {@link SignBlockEntity#updateListeners()} */ public class VirtualSignBlockEntity extends SignBlockEntity { - public VirtualSignBlockEntity(BlockPos pos, BlockState state) { + public VirtualSignBlockEntity(World world, BlockPos pos, BlockState state) { super(pos, state); + this.setWorld(world); } public boolean setText(SignText text, boolean front) { diff --git a/src/testmod/java/eu/pb4/sgui/testmod/BookInputGui.java b/src/testmod/java/eu/pb4/sgui/testmod/BookInputGui.java index 7cc861d..e8a5b2c 100644 --- a/src/testmod/java/eu/pb4/sgui/testmod/BookInputGui.java +++ b/src/testmod/java/eu/pb4/sgui/testmod/BookInputGui.java @@ -2,6 +2,8 @@ import eu.pb4.sgui.api.gui.GuiInterface; import eu.pb4.sgui.virtual.FakeScreenHandler; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.WritableBookContentComponent; import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -13,6 +15,7 @@ import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import net.minecraft.screen.ScreenHandlerType; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.RawFilteredPair; import net.minecraft.text.Text; import net.minecraft.util.Hand; import org.jetbrains.annotations.ApiStatus; @@ -67,13 +70,8 @@ public BookInputGui(ServerPlayerEntity player, ItemStack book) { this.player = player; this.pages = new ArrayList<>(); if (book != null && book.getItem() instanceof WritableBookItem) { - if (book.hasNbt() && book.getNbt().contains("pages", NbtElement.LIST_TYPE)) { - NbtList nbtList = book.getNbt().getList("pages", NbtElement.STRING_TYPE); - - for (int i = 0; i < nbtList.size(); ++i) { - String string = nbtList.getString(i); - this.pages.add(string); - } + for (RawFilteredPair page : book.get(DataComponentTypes.WRITABLE_BOOK_CONTENT).pages()) { + this.pages.add(page.raw()); } } } @@ -96,11 +94,7 @@ public boolean open() { this.player.currentScreenHandler = this.screenHandler; ItemStack stack = Items.WRITABLE_BOOK.getDefaultStack(); - NbtList list = new NbtList(); - for (String string : this.pages) { - list.add(NbtString.of(string)); - } - stack.getOrCreateNbt().put("pages", list); + stack.set(DataComponentTypes.WRITABLE_BOOK_CONTENT, new WritableBookContentComponent(pages.stream().map(RawFilteredPair::of).toList())); this.player.networkHandler.sendPacket(new ScreenHandlerSlotUpdateS2CPacket(-2, 0, PlayerInventory.OFF_HAND_SLOT, stack)); this.player.networkHandler.sendPacket(new OpenWrittenBookS2CPacket(Hand.OFF_HAND)); diff --git a/src/testmod/java/eu/pb4/sgui/testmod/SGuiTest.java b/src/testmod/java/eu/pb4/sgui/testmod/SGuiTest.java index 6393547..0b0de1c 100644 --- a/src/testmod/java/eu/pb4/sgui/testmod/SGuiTest.java +++ b/src/testmod/java/eu/pb4/sgui/testmod/SGuiTest.java @@ -12,6 +12,7 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.minecraft.block.Blocks; +import net.minecraft.component.DataComponentTypes; import net.minecraft.enchantment.Enchantments; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; @@ -30,6 +31,7 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.random.Random; import net.minecraft.village.TradeOffer; +import net.minecraft.village.TradedItem; import org.apache.commons.lang3.mutable.MutableInt; import org.apache.commons.lang3.mutable.MutableObject; import org.jetbrains.annotations.Nullable; @@ -212,8 +214,9 @@ private static int test3(CommandContext objectCommandContex @Override public void onTick() { this.tick++; + int pages = getBook().get(DataComponentTypes.WRITTEN_BOOK_CONTENT).pages().size(); if (this.tick % 20 == 0) { - if (this.page >= WrittenBookItem.getPageCount(getBook()) - 1) { + if (this.page >= pages - 1) { this.setPage(0); } else { this.setPage(getPage() + 1); @@ -359,7 +362,8 @@ public boolean onTrade(TradeOffer offer) { @Override public void onSuggestSell(TradeOffer offer) { if (offer != null && offer.getSellItem() != null) { - offer.getSellItem().setCustomName(((MutableText) player.getName()).append(Text.literal("'s ")).append(offer.getSellItem().getName())); + + offer.getSellItem().set(DataComponentTypes.CUSTOM_NAME, ((MutableText) player.getName()).append(Text.literal("'s ")).append(offer.getSellItem().getName())); this.sendUpdate(); } } @@ -368,7 +372,7 @@ public void onSuggestSell(TradeOffer offer) { gui.setTitle(Text.literal("Trades wow!")); gui.setIsLeveled(true); gui.addTrade(new TradeOffer( - Items.STONE.getDefaultStack(), + new TradedItem(Items.STONE), new GuiElementBuilder(Items.DIAMOND_AXE) .glow() .setCount(1) @@ -381,7 +385,7 @@ public void onSuggestSell(TradeOffer offer) { gui.open(); gui.addTrade(new TradeOffer( - Items.EMERALD.getDefaultStack(), + new TradedItem(Items.EMERALD), new GuiElementBuilder(Items.STONE) .setCount(16) .asStack(), diff --git a/src/testmod/java/eu/pb4/sgui/testmod/SnakeGui.java b/src/testmod/java/eu/pb4/sgui/testmod/SnakeGui.java index d8c731f..e6c98da 100644 --- a/src/testmod/java/eu/pb4/sgui/testmod/SnakeGui.java +++ b/src/testmod/java/eu/pb4/sgui/testmod/SnakeGui.java @@ -4,41 +4,44 @@ import eu.pb4.sgui.api.elements.GuiElementBuilder; import eu.pb4.sgui.api.gui.layered.Layer; import eu.pb4.sgui.api.gui.layered.LayeredGui; +import net.minecraft.block.entity.BannerPatterns; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.BannerPatternsComponent; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.nbt.StringNbtReader; import net.minecraft.screen.ScreenHandlerType; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; +import net.minecraft.util.DyeColor; +import net.minecraft.util.Unit; import java.util.ArrayList; import java.util.List; import java.util.Random; public class SnakeGui extends LayeredGui { - static ItemStack create(String nbt) { - ItemStack stack = Items.GRAY_BANNER.getDefaultStack(); - try { - stack.setNbt(StringNbtReader.parse(nbt)); - stack.addHideFlag(ItemStack.TooltipSection.ADDITIONAL); - } catch (Exception e) {} + static ItemStack create(BannerPatternsComponent component) { + ItemStack stack = Items.GRAY_BANNER.getDefaultStack(); + stack.set(DataComponentTypes.BANNER_PATTERNS, component); + stack.set(DataComponentTypes.HIDE_ADDITIONAL_TOOLTIP, Unit.INSTANCE); return stack; } - static ItemStack[] NUMBERS = new ItemStack[] { - create("{BlockEntityTag:{Patterns:[{Pattern:bs,Color:0},{Pattern:ls,Color:0},{Pattern:ts,Color:0},{Pattern:rs,Color:0},{Pattern:dls,Color:0},{Pattern:bo,Color:7}]}}"), - create("{BlockEntityTag:{Patterns:[{Pattern:cs,Color:0},{Pattern:tl,Color:0},{Pattern:cbo,Color:7},{Pattern:bs,Color:0},{Pattern:bo,Color:7}]}}"), - create("{BlockEntityTag:{Patterns:[{Pattern:ts,Color:0},{Pattern:mr,Color:7},{Pattern:bs,Color:0},{Pattern:dls,Color:0},{Pattern:bo,Color:7}]}}"), - create("{BlockEntityTag:{Patterns:[{Pattern:bs,Color:0},{Pattern:ms,Color:0},{Pattern:ts,Color:0},{Pattern:cbo,Color:7},{Pattern:rs,Color:0},{Pattern:bo,Color:7}]}}"), - create("{BlockEntityTag:{Patterns:[{Pattern:ls,Color:0},{Pattern:hhb,Color:7},{Pattern:rs,Color:0},{Pattern:ms,Color:0},{Pattern:bo,Color:7}]}}"), - create("{BlockEntityTag:{Patterns:[{Pattern:bs,Color:0},{Pattern:mr,Color:7},{Pattern:ts,Color:0},{Pattern:drs,Color:0},{Pattern:bo,Color:7}]}}"), - create("{BlockEntityTag:{Patterns:[{Pattern:bs,Color:0},{Pattern:rs,Color:0},{Pattern:hh,Color:7},{Pattern:ms,Color:0},{Pattern:ts,Color:0},{Pattern:ls,Color:0},{Pattern:bo,Color:7}]}}"), - create("{BlockEntityTag:{Patterns:[{Pattern:dls,Color:0},{Pattern:ts,Color:0},{Pattern:bo,Color:7}]}}"), - create("{BlockEntityTag:{Patterns:[{Pattern:dls,Color:0},{Pattern:ts,Color:0},{Pattern:bo,Color:7}]}}"), - create("{BlockEntityTag:{Patterns:[{Pattern:ls,Color:0},{Pattern:hhb,Color:7},{Pattern:ms,Color:0},{Pattern:ts,Color:0},{Pattern:rs,Color:0},{Pattern:bs,Color:0},{Pattern:bo,Color:7}]}}") - }; + static final ItemStack[] NUMBERS = new ItemStack[]{ + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_BOTTOM, DyeColor.WHITE).add(BannerPatterns.STRIPE_LEFT, DyeColor.WHITE).add(BannerPatterns.STRIPE_TOP, DyeColor.WHITE).add(BannerPatterns.STRIPE_RIGHT, DyeColor.WHITE).add(BannerPatterns.STRIPE_DOWNLEFT, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_CENTER, DyeColor.WHITE).add(BannerPatterns.SQUARE_TOP_LEFT, DyeColor.WHITE).add(BannerPatterns.CURLY_BORDER, DyeColor.GRAY).add(BannerPatterns.STRIPE_BOTTOM, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_TOP, DyeColor.WHITE).add(BannerPatterns.RHOMBUS, DyeColor.GRAY).add(BannerPatterns.STRIPE_BOTTOM, DyeColor.WHITE).add(BannerPatterns.STRIPE_DOWNLEFT, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_BOTTOM, DyeColor.WHITE).add(BannerPatterns.STRIPE_MIDDLE, DyeColor.WHITE).add(BannerPatterns.STRIPE_TOP, DyeColor.WHITE).add(BannerPatterns.CURLY_BORDER, DyeColor.GRAY).add(BannerPatterns.STRIPE_RIGHT, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_LEFT, DyeColor.WHITE).add(BannerPatterns.HALF_HORIZONTAL_BOTTOM, DyeColor.GRAY).add(BannerPatterns.STRIPE_RIGHT, DyeColor.WHITE).add(BannerPatterns.STRIPE_MIDDLE, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_BOTTOM, DyeColor.WHITE).add(BannerPatterns.RHOMBUS, DyeColor.GRAY).add(BannerPatterns.STRIPE_TOP, DyeColor.WHITE).add(BannerPatterns.STRIPE_DOWNRIGHT, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_BOTTOM, DyeColor.WHITE).add(BannerPatterns.STRIPE_RIGHT, DyeColor.WHITE).add(BannerPatterns.HALF_HORIZONTAL, DyeColor.GRAY).add(BannerPatterns.STRIPE_MIDDLE, DyeColor.WHITE).add(BannerPatterns.STRIPE_TOP, DyeColor.WHITE).add(BannerPatterns.STRIPE_LEFT, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_DOWNLEFT, DyeColor.WHITE).add(BannerPatterns.STRIPE_TOP, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_DOWNLEFT, DyeColor.WHITE).add(BannerPatterns.STRIPE_TOP, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + create(new BannerPatternsComponent.Builder().add(BannerPatterns.STRIPE_LEFT, DyeColor.WHITE).add(BannerPatterns.HALF_HORIZONTAL_BOTTOM, DyeColor.GRAY).add(BannerPatterns.STRIPE_MIDDLE, DyeColor.WHITE).add(BannerPatterns.STRIPE_TOP, DyeColor.WHITE).add(BannerPatterns.STRIPE_RIGHT, DyeColor.WHITE).add(BannerPatterns.STRIPE_BOTTOM, DyeColor.WHITE).add(BannerPatterns.BORDER, DyeColor.GRAY).build()), + }; final Layer gameplayLayer; final Layer scoreLayer; @@ -67,16 +70,16 @@ public SnakeGui(ServerPlayerEntity player) { this.controller = controller; controller.setSlot(1, new GuiElementBuilder(Items.MAGMA_CREAM).setName(Text.literal("^")) - .setCallback((x, y, z) -> changeDirection(Direction.UP))); + .setCallback((x, y, z) -> changeDirection(Direction.UP))); controller.setSlot(3, new GuiElementBuilder(Items.MAGMA_CREAM).setName(Text.literal("<")) - .setCallback((x, y, z) -> changeDirection(Direction.LEFT))); + .setCallback((x, y, z) -> changeDirection(Direction.LEFT))); controller.setSlot(5, new GuiElementBuilder(Items.MAGMA_CREAM).setName(Text.literal(">")) - .setCallback((x, y, z) -> changeDirection(Direction.RIGHT))); + .setCallback((x, y, z) -> changeDirection(Direction.RIGHT))); controller.setSlot(7, new GuiElementBuilder(Items.MAGMA_CREAM).setName(Text.literal("v")) - .setCallback((x, y, z) -> changeDirection(Direction.DOWN))); + .setCallback((x, y, z) -> changeDirection(Direction.DOWN))); controller.setSlot(4, new GuiElementBuilder(Items.WHITE_STAINED_GLASS_PANE).setName(Text.empty())); @@ -93,14 +96,14 @@ public SnakeGui(ServerPlayerEntity player) { Pos applePos = new Pos(this.random.nextInt(9), this.random.nextInt(6)); if (applePos.equals(this.snakeHead)) { - applePos = new Pos(3,6); + applePos = new Pos(3, 6); } this.apples.add(applePos); this.scoreLayer = new Layer(1, 5); this.addLayer(this.scoreLayer, 2, 9).setZIndex(1); - Layer backdrop = new Layer(4 ,9); + Layer backdrop = new Layer(4, 9); GuiElementBuilder builder = new GuiElementBuilder(Items.GRAY_STAINED_GLASS_PANE).setName(Text.empty()); @@ -207,7 +210,7 @@ public void onTick() { for (int x = 0; x < 5; x++) { int score = (this.points / (int) Math.pow(10, x)) % 10; ItemStack stack1 = NUMBERS[score].copy(); - stack1.setCustomName(scoreText); + stack1.set(DataComponentTypes.CUSTOM_NAME, scoreText); this.scoreLayer.setSlot(4 - x, stack1); } From 22b1826ad889ab87342d70bc92efc4eb6a2398b6 Mon Sep 17 00:00:00 2001 From: Drex Date: Wed, 27 Mar 2024 20:12:51 +0100 Subject: [PATCH 3/4] Update to 24w10a --- gradle.properties | 6 +++--- .../eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java | 2 +- .../java/eu/pb4/sgui/api/elements/GuiElementBuilder.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle.properties b/gradle.properties index 9e8213d..266a6e9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,12 +3,12 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/versions.html -minecraft_version=24w09a -yarn_mappings=24w09a+build.8 +minecraft_version=24w10a +yarn_mappings=24w10a+build.7 loader_version=0.15.7 #Fabric api -fabric_version=0.96.6+1.20.5 +fabric_version=0.96.8+1.20.5 # Mod Properties diff --git a/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java b/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java index aecf58e..d1d88dd 100644 --- a/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java +++ b/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java @@ -252,7 +252,7 @@ public AnimatedGuiElementBuilder setSkullOwner(String value) { public AnimatedGuiElementBuilder setSkullOwner(String value, @Nullable String signature, @Nullable UUID uuid) { PropertyMap map = new PropertyMap(); map.put("textures", new Property("textures", value, signature)); - this.itemStack.set(DataComponentTypes.PROFILE, new ProfileComponent("???", Optional.ofNullable(uuid), map)); + this.itemStack.set(DataComponentTypes.PROFILE, new ProfileComponent(Optional.empty(), Optional.ofNullable(uuid), map)); return this; } diff --git a/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java b/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java index c9f9656..b9c662b 100644 --- a/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java +++ b/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java @@ -255,7 +255,7 @@ public GuiElementBuilder setSkullOwner(String value) { public GuiElementBuilder setSkullOwner(String value, @Nullable String signature, @Nullable UUID uuid) { PropertyMap map = new PropertyMap(); map.put("textures", new Property("textures", value, signature)); - this.itemStack.set(DataComponentTypes.PROFILE, new ProfileComponent("???", Optional.ofNullable(uuid), map)); + this.itemStack.set(DataComponentTypes.PROFILE, new ProfileComponent(Optional.empty(), Optional.ofNullable(uuid), map)); return this; } From 87fd236f3047014618051320d935299dbf1adfe0 Mon Sep 17 00:00:00 2001 From: Drex Date: Wed, 27 Mar 2024 20:14:50 +0100 Subject: [PATCH 4/4] Update to 24w13a --- gradle.properties | 6 +++--- .../eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java | 2 +- .../java/eu/pb4/sgui/api/elements/GuiElementBuilder.java | 2 +- .../eu/pb4/sgui/mixin/ServerPlayNetworkHandlerMixin.java | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gradle.properties b/gradle.properties index 266a6e9..60b9ca2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,12 +3,12 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/versions.html -minecraft_version=24w10a -yarn_mappings=24w10a+build.7 +minecraft_version=24w13a +yarn_mappings=24w13a+build.2 loader_version=0.15.7 #Fabric api -fabric_version=0.96.8+1.20.5 +fabric_version=0.96.12+1.20.5 # Mod Properties diff --git a/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java b/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java index d1d88dd..3049b54 100644 --- a/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java +++ b/src/main/java/eu/pb4/sgui/api/elements/AnimatedGuiElementBuilder.java @@ -131,7 +131,7 @@ public AnimatedGuiElementBuilder setLore(List lore) { * @return this element builder */ public AnimatedGuiElementBuilder addLoreLine(Text lore) { - this.itemStack.apply(DataComponentTypes.LORE, LoreComponent.DEFAULT, lore, LoreComponent::of); + this.itemStack.apply(DataComponentTypes.LORE, LoreComponent.DEFAULT, lore, LoreComponent::with); return this; } diff --git a/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java b/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java index b9c662b..9a29ce3 100644 --- a/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java +++ b/src/main/java/eu/pb4/sgui/api/elements/GuiElementBuilder.java @@ -134,7 +134,7 @@ public GuiElementBuilder setLore(List lore) { * @return this element builder */ public GuiElementBuilder addLoreLine(Text lore) { - this.itemStack.apply(DataComponentTypes.LORE, LoreComponent.DEFAULT, lore, LoreComponent::of); + this.itemStack.apply(DataComponentTypes.LORE, LoreComponent.DEFAULT, lore, LoreComponent::with); return this; } diff --git a/src/main/java/eu/pb4/sgui/mixin/ServerPlayNetworkHandlerMixin.java b/src/main/java/eu/pb4/sgui/mixin/ServerPlayNetworkHandlerMixin.java index 2f436e0..3549dc4 100644 --- a/src/main/java/eu/pb4/sgui/mixin/ServerPlayNetworkHandlerMixin.java +++ b/src/main/java/eu/pb4/sgui/mixin/ServerPlayNetworkHandlerMixin.java @@ -336,7 +336,7 @@ public ServerPlayNetworkHandlerMixin(MinecraftServer server, ClientConnection co } @Inject(method = "method_44356", at = @At("HEAD"), cancellable = true) - private void sgui$onCommand(CommandExecutionC2SPacket packet, Optional optional, CallbackInfo ci) { + private void sgui$onCommand(CommandExecutionC2SPacket packet, CallbackInfo ci) { if (this.player.currentScreenHandler instanceof BookScreenHandler handler) { try { if (handler.getGui().onCommand("/" + packet.command())) {