TextComponent: Support for colored and other messages (still hover events, ... ToDo)

This commit is contained in:
bixilon 2020-06-08 22:48:18 +02:00
parent 33d227390c
commit dcc5857c70
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
11 changed files with 212 additions and 85 deletions

View File

@ -1,62 +0,0 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.game.datatypes;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class ChatComponent {
JSONObject json;
//ToDo
public ChatComponent(String raw) {
try {
this.json = new JSONObject(raw);
} catch (JSONException e) {
// not a text component, is a legacy string
this.json = new JSONObject();
this.json.put("text", raw);
}
}
public ChatComponent(JSONObject json) {
this.json = json;
}
//ToDo
public String getRawMessage() {
if (json.has("text") && json.getString("text").length() != 0) {
return json.getString("text");
}
StringBuilder buffer = new StringBuilder();
if (json.has("extra")) {
JSONArray arr = json.getJSONArray("extra");
for (int i = 0; i < arr.length(); i++) {
buffer.append(arr.getJSONObject(i).getString("text"));
}
return buffer.toString();
}
return "";
}
public JSONObject getRaw() {
return this.json;
}
public String getColoredMessage() {
//ToDo
return getRawMessage();
}
}

View File

@ -46,7 +46,7 @@ public class Slot {
public String getDisplayName() {
if (nbt != null && nbt.containsKey("display") && nbt.getCompoundTag("display").containsKey("Name")) { // check if object has nbt data, and a custom display name
return new ChatComponent(nbt.getCompoundTag("display").getStringTag("Name").getValue()).getColoredMessage();
return new TextComponent(nbt.getCompoundTag("display").getStringTag("Name").getValue()).getColoredMessage();
}
return "<ToDo>"; //ToDo display name per Item
}

View File

@ -0,0 +1,189 @@
/*
* Codename Minosoft
* Copyright (C) 2020 Moritz Zwerger
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.game.datatypes;
import de.bixilon.minosoft.game.datatypes.particle.Particles;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class TextComponent {
JSONObject json;
public TextComponent(String raw) {
try {
this.json = new JSONObject(raw);
} catch (JSONException e) {
// not a text component, is a legacy string
this.json = new JSONObject();
this.json.put("text", raw);
}
}
public TextComponent(JSONObject json) {
this.json = json;
}
//ToDo
public String getRawMessage() {
if (json.has("text") && json.getString("text").length() != 0) {
return json.getString("text");
}
StringBuilder buffer = new StringBuilder();
if (json.has("extra")) {
JSONArray arr = json.getJSONArray("extra");
for (int i = 0; i < arr.length(); i++) {
JSONObject object;
try {
object = arr.getJSONObject(i);
} catch (JSONException e) {
// reset text
buffer.append(arr.getString(i));
continue;
}
buffer.append(object.getString("text"));
}
buffer.append(ChatAttributes.RESET);
return buffer.toString();
}
return "";
}
public JSONObject getRaw() {
return this.json;
}
public String getColoredMessage() {
if (json.has("text") && json.getString("text").length() != 0) {
return json.getString("text");
}
StringBuilder buffer = new StringBuilder();
if (json.has("extra")) {
JSONArray arr = json.getJSONArray("extra");
for (int i = 0; i < arr.length(); i++) {
JSONObject object;
try {
object = arr.getJSONObject(i);
} catch (JSONException e) {
// reset text
buffer.append(ChatAttributes.RESET);
buffer.append(arr.getString(i));
continue;
}
if (object.has("bold") && object.getBoolean("bold")) {
buffer.append(ChatAttributes.BOLD);
}
if (object.has("color")) {
buffer.append(ChatAttributes.byName(object.getString("color")));
}
if (object.has("italic") && object.getBoolean("italic")) {
buffer.append(ChatAttributes.ITALIC);
}
if (object.has("underlined") && object.getBoolean("underlined")) {
buffer.append(ChatAttributes.UNDERLINED);
}
if (object.has("strikethrough") && object.getBoolean("strikethrough")) {
buffer.append(ChatAttributes.STRIKETHROUGH);
}
if (object.has("obfuscated") && object.getBoolean("obfuscated")) {
buffer.append(ChatAttributes.OBFUSCATED);
}
buffer.append(object.getString("text"));
}
buffer.append(ChatAttributes.RESET);
return buffer.toString();
}
return "";
}
public enum ChatAttributes {
BLACK("\033[38;2;0;0;0m", "0"),
DARK_BLUE("\033[38;2;0;0;170m", "1"),
DARK_GREEN("\033[38;2;0;170;0m", "2"),
DARK_AQUA("\033[38;2;0;170;170m", "3"),
DARK_RED("\033[38;2;170;0;0m", "4"),
DARK_PURPLE("\033[38;2;170;0;170m", "5"),
GOLD("\033[38;2;255;170;0m", "6"),
GRAY("\033[38;2;170;170;170m", "7"),
DARK_GRAY("\033[38;2;85;85;85m", "8"),
BLUE("\033[38;2;85;85;255m", "9"),
GREEN("\033[38;2;85;255;85m", "a"),
AQUA("\033[38;2;85;255;255m", "b"),
RED("\033[38;2;255;255;85m", "c"),
PURPLE("\033[38;2;255;85;85m", "d", "light_purple"),
YELLOW("\033[38;2;255;255;85m", "e"),
WHITE("\033[38;2;255;255;255m", "f"),
RESET("\u001b[0m", "r"),
BOLD("\u001b[1m", "l"),
STRIKETHROUGH("\u001b[9m", "m"),
UNDERLINED("\u001b[4m", "n"),
ITALIC("\u001b[3m", "o"),
OBFUSCATED("\u001b[47;1m", "k"); //ToDo
final String consolePrefix;
final String minecraftPrefix;
final String name;
ChatAttributes(String consolePrefix, String minecraftPrefix, String name) {
this.consolePrefix = consolePrefix;
this.minecraftPrefix = minecraftPrefix;
this.name = name;
}
ChatAttributes(String consolePrefix, String minecraftPrefix) {
this.consolePrefix = consolePrefix;
this.minecraftPrefix = minecraftPrefix;
this.name = null;
}
public String getConsolePrefix() {
return consolePrefix;
}
public String getMinecraftPrefix() {
return minecraftPrefix;
}
public String getName() {
if (name == null) {
return name();
}
return name;
}
@Override
public String toString() {
return getConsolePrefix();
}
public static ChatAttributes byName(String name) {
for (ChatAttributes c : values()) {
if ((c.getName() != null && c.getName().toLowerCase().equals(name.toLowerCase())) || c.name().toLowerCase().equals(name.toLowerCase())) {
return c;
}
}
return null;
}
public static ChatAttributes byMinecraftPrefix(String prefix) {
for (ChatAttributes c : values()) {
if (c.getMinecraftPrefix().equals(prefix)) {
return c;
}
}
return null;
}
}
}

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.objects;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import org.json.JSONObject;
public class ServerListPing {
@ -42,9 +43,8 @@ public class ServerListPing {
return raw.getString("favicon");
}
public String getMotd() {
//ToDo TextComponent handling
return raw.getString("description");
public TextComponent getMotd() {
return new TextComponent(raw.getString("description"));
}
public JSONObject getRaw() {

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.login;
import de.bixilon.minosoft.game.datatypes.ChatComponent;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
@ -21,7 +21,7 @@ import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
public class PacketLoginDisconnect implements ClientboundPacket {
ChatComponent reason;
TextComponent reason;
@Override
public void read(InPacketBuffer buffer, ProtocolVersion v) {
@ -30,7 +30,7 @@ public class PacketLoginDisconnect implements ClientboundPacket {
@Override
public void log() {
Log.protocol(String.format("Receiving login disconnect packet (%s)", reason.getRawMessage()));
Log.protocol(String.format("Receiving login disconnect packet (%s)", reason.getColoredMessage()));
}
@Override
@ -38,7 +38,7 @@ public class PacketLoginDisconnect implements ClientboundPacket {
h.handle(this);
}
public ChatComponent getReason() {
public TextComponent getReason() {
return reason;
}
}

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.ChatComponent;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
@ -21,7 +21,7 @@ import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
public class PacketChatMessage implements ClientboundPacket {
ChatComponent c;
TextComponent c;
@Override
@ -35,10 +35,10 @@ public class PacketChatMessage implements ClientboundPacket {
@Override
public void log() {
Log.game(String.format("[CHAT] %s", c.getRawMessage()));
Log.game(String.format("[CHAT] %s", c.getColoredMessage()));
}
public ChatComponent getChatComponent() {
public TextComponent getChatComponent() {
return c;
}

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.ChatComponent;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InPacketBuffer;
@ -21,7 +21,7 @@ import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import de.bixilon.minosoft.protocol.protocol.ProtocolVersion;
public class PacketDisconnect implements ClientboundPacket {
ChatComponent reason;
TextComponent reason;
@Override
@ -35,10 +35,10 @@ public class PacketDisconnect implements ClientboundPacket {
@Override
public void log() {
Log.game(String.format("Disconnected: %s", reason.getRawMessage()));
Log.game(String.format("Disconnected: %s", reason.getColoredMessage()));
}
public ChatComponent getReason() {
public TextComponent getReason() {
return reason;
}

View File

@ -31,7 +31,7 @@ public class PacketStatusResponse implements ClientboundPacket {
@Override
public void log() {
Log.protocol(String.format("Receiving status response packet (%s)", response.getRaw().toString()));
Log.protocol(String.format("Receiving status response packet (%s)", response.getMotd().getColoredMessage()));
}
@Override

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.protocol.protocol;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.game.datatypes.ChatComponent;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.Direction;
import de.bixilon.minosoft.game.datatypes.Slot;
import de.bixilon.minosoft.game.datatypes.entities.Pose;
@ -188,8 +188,8 @@ public class InByteBuffer {
return "dataLen: " + bytes.length + "; pos: " + pos;
}
public ChatComponent readChatComponent() {
return new ChatComponent(readString());
public TextComponent readChatComponent() {
return new TextComponent(readString());
}
public int getPosition() {

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.protocol.protocol;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.game.datatypes.ChatComponent;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import org.json.JSONObject;
import java.nio.ByteBuffer;
@ -156,7 +156,7 @@ public class OutByteBuffer {
writeLong((((long) pos.getX() & 0x3FFFFFF) << 38) | (((long) pos.getZ() & 0x3FFFFFF) << 12) | ((long) pos.getY() & 0xFFF));
}
public void writeChatComponent(ChatComponent c) {
public void writeChatComponent(TextComponent c) {
writeJson(c.getRaw());
}
}

View File

@ -75,7 +75,7 @@ public class PacketHandler {
}
public void handle(PacketLoginDisconnect pkg) {
Log.info(String.format("Disconnecting from server(%s)", pkg.getReason().toString()));
Log.info(String.format("Disconnecting from server(%s)", pkg.getReason().getColoredMessage()));
connection.setConnectionState(ConnectionState.DISCONNECTING);
}