Update item hover + rich message comments

This commit is contained in:
Felix Cravic 2020-07-29 20:13:17 +02:00
parent 24506ff209
commit da641fd54b
5 changed files with 100 additions and 43 deletions

View File

@ -3,7 +3,6 @@ package net.minestom.server.chat;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.entity.EntityType; import net.minestom.server.entity.EntityType;
import net.minestom.server.item.ItemFlag;
import net.minestom.server.item.ItemStack; import net.minestom.server.item.ItemStack;
/** /**
@ -78,10 +77,20 @@ public class ChatHoverEvent {
JsonObject tagJson = new JsonObject(); JsonObject tagJson = new JsonObject();
// General tags // General tags
tagJson.addProperty("Damage", itemStack.getDamage()); itemJson.addProperty("Damage", itemStack.getDamage());
tagJson.addProperty("Unbreakable", itemStack.isUnbreakable()); {
final boolean unbreakable = itemStack.isUnbreakable();
if (unbreakable) {
tagJson.addProperty("Unbreakable", itemStack.isUnbreakable());
}
}
// TODO: CanDestroy // TODO: CanDestroy
tagJson.addProperty("CustomModelData", itemStack.getCustomModelData()); {
final int customModelData = itemStack.getCustomModelData();
if (customModelData != 0) {
tagJson.addProperty("CustomModelData", itemStack.getCustomModelData());
}
}
// TODO: BlockTags // TODO: BlockTags
@ -102,17 +111,26 @@ public class ChatHoverEvent {
// TODO: Charged // TODO: Charged
// Display // Display
JsonObject displayJson = new JsonObject(); JsonObject displayJson = null;
// TODO: Color (Leather armour) if (itemStack.hasDisplayName() || itemStack.hasLore()) {
// This is done as this contains a json text component describing the item's name. displayJson = new JsonObject();
// We replace it in the last step, as adding it now would replace it with lenient JSON which MC doesn't want. // TODO: Color (Leather armour)
displayJson.addProperty("Name", "%item_name%"); if (itemStack.hasDisplayName()) {
// TODO: Lore // 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%");
}
if (itemStack.hasLore()) {
// TODO: Lore
}
}
// HideFlags // HideFlags
if (!itemStack.getItemFlags().isEmpty()) { if (!itemStack.getItemFlags().isEmpty()) {
int bitField = itemStack.getItemFlags().stream().mapToInt(ItemFlag::getBitFieldPart).sum(); final int hideFlag = itemStack.getHideFlag();
tagJson.addProperty("HideFlags", bitField); if (hideFlag != 0) {
tagJson.addProperty("HideFlags", hideFlag);
}
} }
// WrittenBooks // WrittenBooks
@ -141,7 +159,7 @@ public class ChatHoverEvent {
// Maps // Maps
// TODO: Alot check https://minecraft.gamepedia.com/Player.dat_format#Item_structure#Maps // TODO: Alot check https://minecraft.gamepedia.com/Player.dat_format#Item_structure#Maps
// Suspcious Stew // Suspicious Stew
// TODO: Effects // TODO: Effects
// Debug Sticks // Debug Sticks
@ -153,14 +171,18 @@ public class ChatHoverEvent {
// TODO: LodestonePos // TODO: LodestonePos
tagJson.add("display", displayJson); if (displayJson != null) {
tagJson.add("display", displayJson);
}
itemJson.add("tag", tagJson); itemJson.add("tag", tagJson);
final String item = itemJson.toString() String item = itemJson.toString();
.replaceAll("\"(\\w+)\":", "$1:") item = item.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. if (itemStack.hasDisplayName()) {
.replaceAll("\"%item_name%\"", '\'' + itemStack.getDisplayName().getJsonObject().toString() + '\''); // TODO: Since embedded JSON is wrapped using (')s we should be able to use Regex to ignore any keys wrapped by (')s.
item = item.replaceAll("\"%item_name%\"", '\'' + itemStack.getDisplayName().getJsonObject().toString() + '\'');
}
System.out.println(item); System.out.println(item);
// Use regex to remove the qoutes around the keys (MC wants this). // Use regex to remove the qoutes around the keys (MC wants this).

View File

@ -16,25 +16,33 @@ public class RichMessage {
private List<RichComponent> components = new ArrayList<>(); private List<RichComponent> components = new ArrayList<>();
private RichComponent currentComponent; private RichComponent currentComponent;
public static RichMessage of(ColoredText coloredText, FormatRetention formatRetention) { /**
* Create a RichMessage by adding the first rich component
*
* @param coloredText the text composing the first rich component
* @return the created rich message object
*/
public static RichMessage of(ColoredText coloredText) {
Check.notNull(coloredText, "ColoredText cannot be null"); Check.notNull(coloredText, "ColoredText cannot be null");
RichMessage richMessage = new RichMessage(); RichMessage richMessage = new RichMessage();
appendText(richMessage, coloredText, formatRetention); appendText(richMessage, coloredText, FormatRetention.ALL);
return richMessage; return richMessage;
} }
public static RichMessage of(ColoredText coloredText) {
return of(coloredText, FormatRetention.ALL);
}
private static void appendText(RichMessage richMessage, ColoredText coloredText, FormatRetention formatRetention) { private static void appendText(RichMessage richMessage, ColoredText coloredText, FormatRetention formatRetention) {
RichComponent component = new RichComponent(coloredText, formatRetention); RichComponent component = new RichComponent(coloredText, formatRetention);
richMessage.components.add(component); richMessage.components.add(component);
richMessage.currentComponent = component; richMessage.currentComponent = component;
} }
/**
* Set the click event of the current rich component
*
* @param clickEvent the click event to set
* @return the rich message
*/
public RichMessage setClickEvent(ChatClickEvent clickEvent) { public RichMessage setClickEvent(ChatClickEvent clickEvent) {
Check.notNull(clickEvent, "ChatClickEvent cannot be null"); Check.notNull(clickEvent, "ChatClickEvent cannot be null");
@ -42,6 +50,12 @@ public class RichMessage {
return this; return this;
} }
/**
* Set the hover event of the current rich component
*
* @param hoverEvent the hover event to set
* @return the rich message
*/
public RichMessage setHoverEvent(ChatHoverEvent hoverEvent) { public RichMessage setHoverEvent(ChatHoverEvent hoverEvent) {
Check.notNull(hoverEvent, "ChatHoverEvent cannot be null"); Check.notNull(hoverEvent, "ChatHoverEvent cannot be null");
@ -49,6 +63,13 @@ public class RichMessage {
return this; return this;
} }
/**
* Add a new rich component to the message
*
* @param coloredText the text composing the rich component
* @param formatRetention the format retention of the added component
* @return the rich message
*/
public RichMessage append(ColoredText coloredText, FormatRetention formatRetention) { public RichMessage append(ColoredText coloredText, FormatRetention formatRetention) {
Check.notNull(coloredText, "ColoredText cannot be null"); Check.notNull(coloredText, "ColoredText cannot be null");
@ -56,15 +77,32 @@ public class RichMessage {
return this; return this;
} }
/**
* Add a new rich component to the message,
* the format retention is set to {@link FormatRetention#ALL}
*
* @param coloredText the text composing the rich component
* @return the rich message
*/
public RichMessage append(ColoredText coloredText) { public RichMessage append(ColoredText coloredText) {
return append(coloredText, FormatRetention.ALL); return append(coloredText, FormatRetention.ALL);
} }
/**
* Get the string representation of this json message
*
* @return the string representation of this json message
*/
@Override @Override
public String toString() { public String toString() {
return getJsonObject().toString(); return getJsonObject().toString();
} }
/**
* Get the json object representing the whole rich message
*
* @return the json representation of this rich message
*/
private JsonObject getJsonObject() { private JsonObject getJsonObject() {
List<RichComponent> cacheComponents = new ArrayList<>(components); List<RichComponent> cacheComponents = new ArrayList<>(components);
@ -97,6 +135,12 @@ public class RichMessage {
return mainObject; return mainObject;
} }
/**
* Process the components to add click/hover event
*
* @param component the rich component to process
* @return a list of processed components
*/
private List<JsonObject> getComponentObject(RichComponent component) { private List<JsonObject> getComponentObject(RichComponent component) {
ColoredText coloredText = component.getText(); ColoredText coloredText = component.getText();
List<JsonObject> componentObjects = coloredText.getComponents(); List<JsonObject> componentObjects = coloredText.getComponents();
@ -109,12 +153,15 @@ public class RichMessage {
return componentObjects; return componentObjects;
} }
// Add hover/click event to all components
for (JsonObject componentObject : componentObjects) { for (JsonObject componentObject : componentObjects) {
// Add click event if any
if (clickEvent != null) { if (clickEvent != null) {
final JsonObject clickObject = final JsonObject clickObject =
getEventObject(clickEvent.getAction(), clickEvent.getValue()); getEventObject(clickEvent.getAction(), clickEvent.getValue());
componentObject.add("clickEvent", clickObject); componentObject.add("clickEvent", clickObject);
} }
// Add hover event if any
if (hoverEvent != null) { if (hoverEvent != null) {
final JsonObject hoverObject; final JsonObject hoverObject;
if (hoverEvent.isJson()) { if (hoverEvent.isJson()) {
@ -144,6 +191,9 @@ public class RichMessage {
ALL, CLICK_EVENT, HOVER_EVENT, NONE ALL, CLICK_EVENT, HOVER_EVENT, NONE
} }
/**
* Represent a colored text with a click and hover event (can be null)
*/
private static class RichComponent { private static class RichComponent {
private ColoredText text; private ColoredText text;

View File

@ -62,7 +62,7 @@ public abstract class EntityCreature extends LivingEntity {
final float speed = getAttributeValue(Attribute.MOVEMENT_SPEED); final float speed = getAttributeValue(Attribute.MOVEMENT_SPEED);
Position targetPosition = pathingEntity.getTargetPosition(); Position targetPosition = pathingEntity.getTargetPosition();
//targetPosition = new Position(-5.5f, 40f, -5.5f); //targetPosition = new Position(-5.5f, 40f, -5.5f);
//System.out.println("target: " + targetPosition); //System.out.println("target: " + targetPosition + " : " + (System.currentTimeMillis() - time));
//System.out.println("current: " + getPosition()); //System.out.println("current: " + getPosition());
moveTowards(targetPosition, speed); moveTowards(targetPosition, speed);
} }
@ -270,7 +270,7 @@ public abstract class EntityCreature extends LivingEntity {
public void jump(float height) { public void jump(float height) {
// FIXME magic value // FIXME magic value
final Vector velocity = new Vector(0, height * 5, 0); final Vector velocity = new Vector(0, height * 2.5f, 0);
setVelocity(velocity); setVelocity(velocity);
} }

View File

@ -86,7 +86,7 @@ public class PFPathingEntity implements IPathingEntity {
final float entityY = entity.getPosition().getY(); final float entityY = entity.getPosition().getY();
if (entityY < y) { if (entityY < y) {
//entity.jump(1); entity.jump(1);
} }
} }

View File

@ -1,10 +1,7 @@
package net.minestom.server.listener; package net.minestom.server.listener;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.attribute.AttributeOperation;
import net.minestom.server.chat.ChatClickEvent; import net.minestom.server.chat.ChatClickEvent;
import net.minestom.server.chat.ChatColor;
import net.minestom.server.chat.ChatHoverEvent; import net.minestom.server.chat.ChatHoverEvent;
import net.minestom.server.chat.ColoredText; import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.RichMessage; import net.minestom.server.chat.RichMessage;
@ -12,17 +9,12 @@ import net.minestom.server.command.CommandManager;
import net.minestom.server.entity.Player; import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerChatEvent; import net.minestom.server.event.player.PlayerChatEvent;
import net.minestom.server.event.player.PlayerCommandEvent; 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.ConnectionManager;
import net.minestom.server.network.PacketWriterUtils; import net.minestom.server.network.PacketWriterUtils;
import net.minestom.server.network.packet.client.play.ClientChatMessagePacket; import net.minestom.server.network.packet.client.play.ClientChatMessagePacket;
import net.minestom.server.network.packet.server.play.ChatMessagePacket; import net.minestom.server.network.packet.server.play.ChatMessagePacket;
import java.util.Collection; import java.util.Collection;
import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
public class ChatMessageListener { public class ChatMessageListener {
@ -86,15 +78,8 @@ public class ChatMessageListener {
final ColoredText usernameText = ColoredText.of(String.format("<%s>", username)); 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) final RichMessage richMessage = RichMessage.of(usernameText)
.setHoverEvent(ChatHoverEvent.showItem(itemStack)) .setHoverEvent(ChatHoverEvent.showText("Click to send a message to " + username))
.setClickEvent(ChatClickEvent.suggestCommand("/msg " + username + " ")) .setClickEvent(ChatClickEvent.suggestCommand("/msg " + username + " "))
.append(ColoredText.of(" " + chatEvent.getMessage())); .append(ColoredText.of(" " + chatEvent.getMessage()));