From 78f4bc0a13313a95f7e2c490365dca5b0affc241 Mon Sep 17 00:00:00 2001 From: Articdive <13535885+Articdive@users.noreply.github.com> Date: Wed, 29 Jul 2020 11:17:59 +0200 Subject: [PATCH] Started work on item hovering. --- .../minestom/server/chat/ChatHoverEvent.java | 129 +++++++++++++++--- .../net/minestom/server/item/ItemFlag.java | 21 ++- .../server/listener/ChatMessageListener.java | 22 ++- 3 files changed, 147 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/minestom/server/chat/ChatHoverEvent.java b/src/main/java/net/minestom/server/chat/ChatHoverEvent.java index 4ee89e1b3..09eaf6fe6 100644 --- a/src/main/java/net/minestom/server/chat/ChatHoverEvent.java +++ b/src/main/java/net/minestom/server/chat/ChatHoverEvent.java @@ -3,6 +3,7 @@ package net.minestom.server.chat; import com.google.gson.JsonObject; import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityType; +import net.minestom.server.item.ItemFlag; import net.minestom.server.item.ItemStack; /** @@ -26,6 +27,22 @@ public class ChatHoverEvent { this.isJson = true; } + protected String getAction() { + return action; + } + + protected String getValue() { + return value; + } + + protected JsonObject getValueObject() { + return valueObject; + } + + protected boolean isJson() { + return isJson; + } + /** * Show a {@link ColoredText} when hovered * @@ -53,7 +70,101 @@ public class ChatHoverEvent { * @return the chat hover event */ public static ChatHoverEvent showItem(ItemStack itemStack) { - return new ChatHoverEvent("show_item", "{id:35,Damage:5,Count:2,tag:{display:{Name:Testing}}}"); + JsonObject itemJson = new JsonObject(); + // Basic Item structure + itemJson.addProperty("id", itemStack.getMaterial().getName()); + itemJson.addProperty("Count", itemStack.getAmount()); + + JsonObject tagJson = new JsonObject(); + + // General tags + tagJson.addProperty("Damage", itemStack.getDamage()); + tagJson.addProperty("Unbreakable", itemStack.isUnbreakable()); + // TODO: CanDestroy + tagJson.addProperty("CustomModelData", itemStack.getCustomModelData()); + + // TODO: BlockTags + + // Enchantments + // TODO: Enchantments + // TODO: StoredEnchantments + // TODO: RepairCost + + // TODO: Attribute modifiers + + // Potion Effects + // TODO: CustomPotionEffects + // TODO: Potion + // TODO: CustomPotionColor + + // Crossbows + // TODO: ChargedProjectiles + // TODO: Charged + + // Display + JsonObject displayJson = new JsonObject(); + // TODO: Color (Leather armour) + // This is done as this contains a json text component describing the item's name. + // We replace it in the last step, as adding it now would replace it with lenient JSON which MC doesn't want. + displayJson.addProperty("Name", "%item_name%"); + // TODO: Lore + + // HideFlags + if (!itemStack.getItemFlags().isEmpty()) { + int bitField = itemStack.getItemFlags().stream().mapToInt(ItemFlag::getBitFieldPart).sum(); + tagJson.addProperty("HideFlags", bitField); + } + + // WrittenBooks + // TODO: Resolved + // TODO: Generation + // TODO: Author + // TODO: Title + // TODO: Pages + + // Book and Quills + // TODO: Pages + + // Player Heads + // TODO: Alot check https://minecraft.gamepedia.com/Player.dat_format#Item_structure#Player_Heads + + // Fireworks + // TODO: Alot check https://minecraft.gamepedia.com/Player.dat_format#Item_structure#Fireworks + + // Armorstands and Spawn Eggs + // TODO: EntityTag + + // Buckets of Fish + // TODO: BucketVariantTag + // TODO: ENtityTag + + // Maps + // TODO: Alot check https://minecraft.gamepedia.com/Player.dat_format#Item_structure#Maps + + // Suspcious Stew + // TODO: Effects + + // Debug Sticks + // TODO: DebugProperty + + // Compasses + // TODO: LodestoneTracked + // TODO: LodestoneDimension + // TODO: LodestonePos + + + tagJson.add("display", displayJson); + itemJson.add("tag", tagJson); + + + final String item = itemJson.toString() + .replaceAll("\"(\\w+)\":", "$1:") + // TODO: Since embedded JSON is wrapped using (')s we should be able to use Regex to ignore any keys wrapped by (')s. + .replaceAll("\"%item_name%\"", '\'' + itemStack.getDisplayName().getJsonObject().toString() + '\''); + + System.out.println(item); + // Use regex to remove the qoutes around the keys (MC wants this). + return new ChatHoverEvent("show_item", item); } /** @@ -73,20 +184,4 @@ public class ChatHoverEvent { object.addProperty("type", type); return new ChatHoverEvent("show_entity", object); } - - protected String getAction() { - return action; - } - - protected String getValue() { - return value; - } - - protected JsonObject getValueObject() { - return valueObject; - } - - protected boolean isJson() { - return isJson; - } } diff --git a/src/main/java/net/minestom/server/item/ItemFlag.java b/src/main/java/net/minestom/server/item/ItemFlag.java index 0fdfbf090..e118fe634 100644 --- a/src/main/java/net/minestom/server/item/ItemFlag.java +++ b/src/main/java/net/minestom/server/item/ItemFlag.java @@ -1,10 +1,19 @@ package net.minestom.server.item; public enum ItemFlag { - HIDE_ENCHANTS, - HIDE_ATTRIBUTES, - HIDE_UNBREAKABLE, - HIDE_DESTROYS, - HIDE_PLACED_ON, - HIDE_POTION_EFFECTS, + HIDE_ENCHANTS(1), + HIDE_ATTRIBUTES(2), + HIDE_UNBREAKABLE(4), + HIDE_DESTROYS(8), + HIDE_PLACED_ON(16), + HIDE_POTION_EFFECTS(32); + + private final int bitFieldPart; + ItemFlag(int bit) { + this.bitFieldPart = bit; + } + + public int getBitFieldPart() { + return bitFieldPart; + } } diff --git a/src/main/java/net/minestom/server/listener/ChatMessageListener.java b/src/main/java/net/minestom/server/listener/ChatMessageListener.java index fae62305e..8f35c17e2 100644 --- a/src/main/java/net/minestom/server/listener/ChatMessageListener.java +++ b/src/main/java/net/minestom/server/listener/ChatMessageListener.java @@ -1,17 +1,28 @@ package net.minestom.server.listener; import net.minestom.server.MinecraftServer; -import net.minestom.server.chat.*; +import net.minestom.server.attribute.Attribute; +import net.minestom.server.attribute.AttributeOperation; +import net.minestom.server.chat.ChatClickEvent; +import net.minestom.server.chat.ChatColor; +import net.minestom.server.chat.ChatHoverEvent; +import net.minestom.server.chat.ColoredText; +import net.minestom.server.chat.RichMessage; import net.minestom.server.command.CommandManager; import net.minestom.server.entity.Player; import net.minestom.server.event.player.PlayerChatEvent; import net.minestom.server.event.player.PlayerCommandEvent; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.minestom.server.item.attribute.AttributeSlot; +import net.minestom.server.item.attribute.ItemAttribute; import net.minestom.server.network.ConnectionManager; import net.minestom.server.network.PacketWriterUtils; import net.minestom.server.network.packet.client.play.ClientChatMessagePacket; import net.minestom.server.network.packet.server.play.ChatMessagePacket; import java.util.Collection; +import java.util.UUID; import java.util.function.Function; public class ChatMessageListener { @@ -75,8 +86,15 @@ public class ChatMessageListener { final ColoredText usernameText = ColoredText.of(String.format("<%s>", username)); + ItemStack itemStack = new ItemStack(Material.DIAMOND_SWORD, (byte) 1); + itemStack.addAttribute( + new ItemAttribute(UUID.randomUUID(), Attribute.ATTACK_DAMAGE.getKey(), + Attribute.ATTACK_DAMAGE, AttributeOperation.ADDITION, 16.0, AttributeSlot.MAINHAND) + ); + itemStack.setDisplayName(ColoredText.of(ChatColor.BRIGHT_GREEN + "Weird" + ChatColor.YELLOW + "Fence")); + final RichMessage richMessage = RichMessage.of(usernameText) - .setHoverEvent(ChatHoverEvent.showText(ColoredText.of(ChatColor.GRAY + "Its " + username))) + .setHoverEvent(ChatHoverEvent.showItem(itemStack)) .setClickEvent(ChatClickEvent.suggestCommand("/msg " + username + " ")) .append(ColoredText.of(" " + chatEvent.getMessage()));