Allow for custom chat message serializer using JsonMessage

This commit is contained in:
themode 2020-10-06 03:43:57 +02:00
parent 67c93e73ab
commit 37d3c9c6bc
5 changed files with 71 additions and 56 deletions

View File

@ -10,17 +10,14 @@ import java.util.regex.Pattern;
/**
* Represent a text with one or multiple colors
* <p>
* Used when the message can contain colors but not events like in {@link RichMessage}
*/
public class ColoredText {
public class ColoredText extends JsonMessage {
// the raw text
private String message;
// true if the compiled string is up-to-date, false otherwise
private boolean updated;
// the compiled json string of this colored text (can be outdated)
private String compiledJson;
private ColoredText(String message) {
this.message = message;
refreshUpdate();
@ -97,21 +94,6 @@ public class ColoredText {
return message;
}
/**
* Compile this text and cache it for further execution
*
* @return the raw json string of this colored text
*/
@Override
public String toString() {
if (!updated) {
this.compiledJson = getJsonObject().toString();
this.updated = true;
}
return compiledJson;
}
/**
* Get the Json representation of this colored text
* <p>
@ -119,6 +101,7 @@ public class ColoredText {
*
* @return the Json representation of the text
*/
@Override
public JsonObject getJsonObject() {
final List<JsonObject> components = getComponents();
@ -169,7 +152,7 @@ public class ColoredText {
if ((p == null || (p != '/')) && c == '{' && !inFormat) {
formatEnd = formatEnd > 0 ? formatEnd + 1 : formatEnd;
String rawMessage = message.substring(formatEnd, i);
final String rawMessage = message.substring(formatEnd, i);
if (!rawMessage.isEmpty()) {
objects.add(getMessagePart(MessageType.RAW, rawMessage, currentColor, specialComponentContainer));
}
@ -179,7 +162,7 @@ public class ColoredText {
continue;
} else if ((p == null || (p != '/')) && c == '}' && inFormat) {
// Represent the custom format between the brackets
String formatString = message.substring(formatStart + 1, i);
final String formatString = message.substring(formatStart + 1, i);
if (formatString.isEmpty())
continue;
@ -223,6 +206,8 @@ public class ColoredText {
final String translatableCode = formatString.substring(1);
final boolean hasArgs = translatableCode.contains(",");
if (!hasArgs) {
// Without argument
// ex: {@translatable.key}
objects.add(getMessagePart(MessageType.TRANSLATABLE, translatableCode, currentColor, specialComponentContainer));
} else {
// Arguments parsing
@ -245,6 +230,7 @@ public class ColoredText {
}
// Keybind component
if (formatString.startsWith("&")) {
// ex: {&key.drop}
final String keybindCode = formatString.substring(1);
objects.add(getMessagePart(MessageType.KEYBIND, keybindCode, currentColor, specialComponentContainer));
continue;
@ -301,14 +287,13 @@ public class ColoredText {
return value ? "true" : "false";
}
private void refreshUpdate() {
this.updated = false;
}
private enum MessageType {
RAW, KEYBIND, TRANSLATABLE
}
/**
* Used to keep a "color" state in the text
*/
private static class SpecialComponentContainer {
boolean bold = false;

View File

@ -0,0 +1,49 @@
package net.minestom.server.chat;
import com.google.gson.JsonObject;
/**
* Represent a json message which can be send to a player
* <p>
* Examples are {@link ColoredText} and {@link RichMessage}
*
* @see <a href="https://wiki.vg/Chat">Chat Format</a>
*/
public abstract class JsonMessage {
// true if the compiled string is up-to-date, false otherwise
private boolean updated;
// the compiled json string of this colored text (can be outdated)
private String compiledJson;
/**
* Get the json representation of this message
* <p>
* Sent directly to the client
*
* @return the json representation of the message
*/
public abstract JsonObject getJsonObject();
/**
* Signal that the final json string changed and that it will need to be updated
*/
protected void refreshUpdate() {
this.updated = false;
}
/**
* Get the string json representation
*
* @return the string json representation
*/
@Override
public String toString() {
if (!updated) {
this.compiledJson = getJsonObject().toString();
this.updated = true;
}
return compiledJson;
}
}

View File

@ -10,8 +10,10 @@ import java.util.List;
/**
* Represent multiple {@link ColoredText} batched together with the possibility to add
* click and hover events
* <p>
* Used when the message can contain both colored text and event (otherwise, use {@link ColoredText)})
*/
public class RichMessage {
public class RichMessage extends JsonMessage {
private List<RichComponent> components = new ArrayList<>();
private RichComponent currentComponent;
@ -101,22 +103,8 @@ public class RichMessage {
return append(coloredText, FormatRetention.ALL);
}
/**
* Get the string representation of this json message
*
* @return the string representation of this json message
*/
@Override
public String toString() {
return getJsonObject().toString();
}
/**
* Get the json object representing the whole rich message
*
* @return the json representation of this rich message
*/
private JsonObject getJsonObject() {
public JsonObject getJsonObject() {
List<RichComponent> cacheComponents = new ArrayList<>(components);
// No component, return empty json object

View File

@ -4,6 +4,7 @@ import net.minestom.server.MinecraftServer;
import net.minestom.server.attribute.Attribute;
import net.minestom.server.chat.ChatParser;
import net.minestom.server.chat.ColoredText;
import net.minestom.server.chat.JsonMessage;
import net.minestom.server.chat.RichMessage;
import net.minestom.server.collision.BoundingBox;
import net.minestom.server.command.CommandManager;
@ -661,19 +662,11 @@ public class Player extends LivingEntity implements CommandSender {
/**
* Send a message to the player
*
* @param coloredText the text to send
* @param message the message to send,
* you can use {@link ColoredText} and/or {@link RichMessage} to create it easily
*/
public void sendMessage(ColoredText coloredText) {
sendJsonMessage(coloredText.toString());
}
/**
* Send a rich message to the player
*
* @param richMessage the rich text to send
*/
public void sendMessage(RichMessage richMessage) {
sendJsonMessage(richMessage.toString());
public void sendMessage(JsonMessage message) {
sendJsonMessage(message.toString());
}
/**

View File

@ -168,7 +168,7 @@ public abstract class Chunk implements Viewable, DataContainer {
* @param x the block X
* @param y the block Y
* @param z the block Z
* @param data the new data
* @param data the new data, can be null
*/
public abstract void setBlockData(int x, int y, int z, Data data);