diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/ChatComponent.java b/src/main/java/de/bixilon/minosoft/game/datatypes/ChatComponent.java deleted file mode 100644 index 4d91abef1..000000000 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/ChatComponent.java +++ /dev/null @@ -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 . - * - * 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(); - } -} diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/Slot.java b/src/main/java/de/bixilon/minosoft/game/datatypes/Slot.java index b62ea5d2e..d535cccd9 100644 --- a/src/main/java/de/bixilon/minosoft/game/datatypes/Slot.java +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/Slot.java @@ -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 display name per Item } diff --git a/src/main/java/de/bixilon/minosoft/game/datatypes/TextComponent.java b/src/main/java/de/bixilon/minosoft/game/datatypes/TextComponent.java new file mode 100644 index 000000000..fd8c4d61a --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/game/datatypes/TextComponent.java @@ -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 . + * + * 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; + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/objects/ServerListPing.java b/src/main/java/de/bixilon/minosoft/objects/ServerListPing.java index be1aa78b5..ca823ea65 100644 --- a/src/main/java/de/bixilon/minosoft/objects/ServerListPing.java +++ b/src/main/java/de/bixilon/minosoft/objects/ServerListPing.java @@ -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() { diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/login/PacketLoginDisconnect.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/login/PacketLoginDisconnect.java index a263856f8..a86448845 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/login/PacketLoginDisconnect.java +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/login/PacketLoginDisconnect.java @@ -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; } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChatMessage.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChatMessage.java index aa8d85340..2a431dffb 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChatMessage.java +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketChatMessage.java @@ -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; } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketDisconnect.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketDisconnect.java index 14d318a03..489ec2f1b 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketDisconnect.java +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/play/PacketDisconnect.java @@ -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; } diff --git a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/status/PacketStatusResponse.java b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/status/PacketStatusResponse.java index a90c14d31..55ace2573 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/status/PacketStatusResponse.java +++ b/src/main/java/de/bixilon/minosoft/protocol/packets/clientbound/status/PacketStatusResponse.java @@ -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 diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java index 2dcc172bb..6d72022ca 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/InByteBuffer.java @@ -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() { diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/OutByteBuffer.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/OutByteBuffer.java index 9883f59b7..c297bbb3e 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/OutByteBuffer.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/OutByteBuffer.java @@ -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()); } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java index 20accf063..ccc8a3a3a 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java +++ b/src/main/java/de/bixilon/minosoft/protocol/protocol/PacketHandler.java @@ -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); }