way improved TextComponent (Chat) api: recode, nesting support, rgb support, performance improvements, etc

This commit is contained in:
Bixilon 2020-10-07 17:44:47 +02:00
parent 3084481f35
commit d4515f860f
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
52 changed files with 873 additions and 657 deletions

View File

@ -138,7 +138,7 @@ public class ChatEvent extends EventListener {
if (event.isCancelled()) {
return;
}
if (event.getMessage().getRawMessage().contains("Bixilon")) {
if (event.getMessage().getMessage().contains("Bixilon")) {
MinosoftExampleMod.getInstance().getLogger().game("Bixilon is awful, suppressing this potential bad chat message!");
event.setCancelled(true);
}

View File

@ -1,54 +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;
public enum ChatColors {
BLACK,
DARK_BLUE,
DARK_GREEN,
DARK_AQUA,
DARK_RED,
DARK_PURPLE,
GOLD,
GRAY,
DARK_GRAY,
BLUE,
GREEN,
AQUA,
RED,
PURPLE,
YELLOW,
WHITE,
OBFUSCATED,
BOLD,
STRIKETHROUGH,
UNDERLINED,
ITALIC,
RESET;
public static ChatColors byId(int id) {
if (id < 0 || id >= values().length) {
return null;
}
return values()[id];
}
public String getPrefix() {
return String.format("%x", getColor());
}
public int getColor() {
return ordinal();
}
}

View File

@ -20,6 +20,7 @@ import de.bixilon.minosoft.game.datatypes.inventory.InventorySlots;
import de.bixilon.minosoft.game.datatypes.inventory.Slot;
import de.bixilon.minosoft.game.datatypes.player.PlayerListItem;
import de.bixilon.minosoft.game.datatypes.scoreboard.ScoreboardManager;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.game.datatypes.world.World;
import de.bixilon.minosoft.util.mojang.api.MojangAccount;
@ -46,8 +47,8 @@ public class Player {
OtherPlayer player;
boolean spawnConfirmed = false;
TextComponent tabHeader;
TextComponent tabFooter;
BaseComponent tabHeader;
BaseComponent tabFooter;
public Player(MojangAccount account) {
this.account = account;
@ -203,19 +204,19 @@ public class Player {
return null;
}
public TextComponent getTabHeader() {
public BaseComponent getTabHeader() {
return tabHeader;
}
public void setTabHeader(TextComponent tabHeader) {
public void setTabHeader(BaseComponent tabHeader) {
this.tabHeader = tabHeader;
}
public TextComponent getTabFooter() {
public BaseComponent getTabFooter() {
return tabFooter;
}
public void setTabFooter(TextComponent tabFooter) {
public void setTabFooter(BaseComponent tabFooter) {
this.tabFooter = tabFooter;
}

View File

@ -1,321 +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 com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import java.util.ArrayList;
public class TextComponent {
final JsonObject json;
String rawMessage;
String coloredMessage;
public TextComponent(String raw) {
JsonObject json;
if (raw == null) {
this.json = new JsonObject();
return;
}
try {
json = JsonParser.parseString(raw).getAsJsonObject();
} catch (Exception e) {
// not a text component, is a legacy string
json = new JsonObject();
JsonArray extra = new JsonArray();
String[] paragraphSplit = raw.split("§");
StringBuilder message = new StringBuilder();
ArrayList<ChatAttributes> attributesList = new ArrayList<>();
ChatAttributes color = ChatAttributes.WHITE;
boolean first = true;
for (String paragraph : paragraphSplit) {
if (paragraph.length() >= 1) {
if (first) {
// skip first, just append.
message.append(paragraph);
first = false;
continue;
}
// only 1 code without message, append to list
ChatColors colorCheck = null;
try {
colorCheck = ChatColors.byId(Integer.parseInt(paragraph.substring(0, 1), 16));
} catch (NumberFormatException ignored) {
}
if (colorCheck == null) {
//this is not a color, append attribute to list
//save and clear
switch (paragraph.substring(0, 1)) {
case "k" -> attributesList.add(ChatAttributes.OBFUSCATED);
case "l" -> attributesList.add(ChatAttributes.BOLD);
case "m" -> attributesList.add(ChatAttributes.STRIKETHROUGH);
case "n" -> attributesList.add(ChatAttributes.UNDERLINED);
case "o" -> attributesList.add(ChatAttributes.ITALIC);
case "r" -> {
extra.add(getExtraByAttributes(message.toString(), color, attributesList));
attributesList.clear();
color = ChatAttributes.WHITE;
message = new StringBuilder();
}
}
} else {
// save current
if (!message.toString().isEmpty()) {
extra.add(getExtraByAttributes(message.toString(), color, attributesList));
message = new StringBuilder();
}
color = ChatAttributes.byColor(colorCheck);
}
message.append(paragraph.substring(1));
} else {
if (first) {
// skip first
first = false;
}
}
}
// save
extra.add(getExtraByAttributes(message.toString(), color, attributesList));
json.add("extra", extra);
}
this.json = json;
}
static JsonObject getExtraByAttributes(String message, ChatAttributes color, ArrayList<ChatAttributes> formatting) {
JsonObject ret = new JsonObject();
ret.addProperty("text", message);
if (color != null) {
ret.addProperty("color", color.name());
}
formatting.forEach((attribute) -> {
if (attribute == ChatAttributes.BOLD && !ret.has("bold")) {
ret.addProperty("bold", true);
} else if (attribute == ChatAttributes.ITALIC && !ret.has("italic")) {
ret.addProperty("italic", true);
} else if (attribute == ChatAttributes.UNDERLINED && !ret.has("underlined")) {
ret.addProperty("underlined", true);
} else if (attribute == ChatAttributes.STRIKETHROUGH && !ret.has("strikethrough")) {
ret.addProperty("strikethrough", true);
} else if (attribute == ChatAttributes.OBFUSCATED && !ret.has("obfuscated")) {
ret.addProperty("obfuscated", true);
}
});
return ret;
}
public TextComponent(JsonObject json) {
this.json = json;
}
public String getRawMessage() {
if (rawMessage == null) {
if (json.has("text") && json.get("text").getAsString().length() != 0) {
rawMessage = json.get("text").getAsString();
} else {
StringBuilder buffer = new StringBuilder();
if (json.has("extra")) {
JsonArray arr = json.getAsJsonArray("extra");
for (int i = 0; i < arr.size(); i++) {
JsonObject object;
try {
object = arr.get(i).getAsJsonObject();
} catch (JsonParseException e) {
// reset text
buffer.append(arr.get(i).getAsString());
continue;
}
buffer.append(object.get("text").getAsString());
}
rawMessage = buffer.toString();
} else if (json.has("with")) {
JsonArray arr = json.getAsJsonArray("with");
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i).isJsonPrimitive()) {
buffer.append(" ");
buffer.append(arr.get(i).getAsString());
continue;
}
JsonObject object = arr.get(i).getAsJsonObject();
buffer.append(object.get("text").getAsString());
buffer.append(" ");
}
} else {
rawMessage = "";
}
rawMessage = buffer.toString();
}
}
return rawMessage;
}
public JsonObject getRaw() {
return this.json;
}
@Override
public String toString() {
return getColoredMessage();
}
public String getColoredMessage() {
if (coloredMessage == null) {
if (json.has("text") && json.get("text").getAsString().length() != 0) {
coloredMessage = json.get("text").getAsString();
} else {
StringBuilder buffer = new StringBuilder();
if (json.has("extra")) {
JsonArray arr = json.getAsJsonArray("extra");
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i).isJsonPrimitive()) {
buffer.append(ChatAttributes.RESET);
buffer.append(" ");
buffer.append(arr.get(i).getAsString());
continue;
}
JsonObject object = arr.get(i).getAsJsonObject();
if (object.has("bold") && object.get("bold").getAsBoolean()) {
buffer.append(ChatAttributes.BOLD);
}
if (object.has("color")) {
buffer.append(ChatAttributes.byName(object.get("color").getAsString()));
}
if (object.has("italic") && object.get("italic").getAsBoolean()) {
buffer.append(ChatAttributes.ITALIC);
}
if (object.has("underlined") && object.get("underlined").getAsBoolean()) {
buffer.append(ChatAttributes.UNDERLINED);
}
if (object.has("strikethrough") && object.get("strikethrough").getAsBoolean()) {
buffer.append(ChatAttributes.STRIKETHROUGH);
}
if (object.has("obfuscated") && object.get("obfuscated").getAsBoolean()) {
buffer.append(ChatAttributes.OBFUSCATED);
}
buffer.append(object.get("text").getAsString());
}
buffer.append(ChatAttributes.RESET);
}
if (json.has("with")) {
JsonArray arr = json.getAsJsonArray("with");
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i).isJsonPrimitive()) {
buffer.append(ChatAttributes.RESET);
buffer.append(" ");
buffer.append(arr.get(i).getAsString());
continue;
}
JsonObject object = arr.get(i).getAsJsonObject();
buffer.append(object.get("text").getAsString());
buffer.append(" ");
}
buffer.append(ChatAttributes.RESET);
}
coloredMessage = buffer.toString();
}
}
return coloredMessage;
}
public String getLegacyText() {
//ToDo
return null;
}
public enum ChatAttributes {
BLACK("\033[38;2;0;0;0m", ChatColors.BLACK),
DARK_BLUE("\033[38;2;0;0;170m", ChatColors.DARK_BLUE),
DARK_GREEN("\033[38;2;0;170;0m", ChatColors.DARK_GREEN),
DARK_AQUA("\033[38;2;0;170;170m", ChatColors.DARK_AQUA),
DARK_RED("\033[38;2;170;0;0m", ChatColors.DARK_RED),
DARK_PURPLE("\033[38;2;170;0;170m", ChatColors.DARK_PURPLE),
GOLD("\033[38;2;255;170;0m", ChatColors.GOLD),
GRAY("\033[38;2;170;170;170m", ChatColors.GRAY),
DARK_GRAY("\033[38;2;85;85;85m", ChatColors.DARK_GRAY),
BLUE("\033[38;2;85;85;255m", ChatColors.DARK_BLUE),
GREEN("\033[38;2;85;255;85m", ChatColors.GREEN),
AQUA("\033[38;2;85;255;255m", ChatColors.AQUA),
RED("\033[38;2;255;85;85m", ChatColors.RED),
LIGHT_PURPLE("\033[38;2;255;85;255m", ChatColors.PURPLE),
YELLOW("\033[38;2;255;255;85m", ChatColors.YELLOW),
WHITE("\033[38;2;255;255;255m", ChatColors.WHITE),
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 ChatColors color;
final String prefix;
ChatAttributes(String consolePrefix, ChatColors color) {
this.consolePrefix = consolePrefix;
this.color = color;
this.prefix = null;
}
ChatAttributes(String consolePrefix, String prefix, String name) {
this.consolePrefix = consolePrefix;
this.prefix = prefix;
this.color = null;
}
ChatAttributes(String consolePrefix, String prefix) {
this.consolePrefix = consolePrefix;
this.prefix = prefix;
this.color = null;
}
public static ChatAttributes byName(String name) {
return valueOf(name.toUpperCase());
}
public static ChatAttributes byColor(ChatColors color) {
for (ChatAttributes attribute : values()) {
if (attribute.getColor() == color) {
return attribute;
}
}
return null;
}
public ChatColors getColor() {
return color;
}
public String getPrefix() {
if (prefix == null) {
return color.getPrefix();
}
return prefix;
}
@Override
public String toString() {
return getConsolePrefix();
}
public String getConsolePrefix() {
return consolePrefix;
}
}
}

View File

@ -12,7 +12,9 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
import de.bixilon.minosoft.game.datatypes.Colors;
import de.bixilon.minosoft.game.datatypes.text.ChatColors;
import de.bixilon.minosoft.game.datatypes.text.RGBColor;
public class CatMetaData extends AnimalMetaData {
@ -28,12 +30,12 @@ public class CatMetaData extends AnimalMetaData {
return CatTypes.byId(sets.getInt(super.getLastDataIndex() + 1, defaultValue));
}
public Colors getCollarColor() {
final int defaultValue = Colors.RED.ordinal();
public RGBColor getCollarColor() {
final int defaultValue = ChatColors.getColorId(ChatColors.getColorByName("red"));
if (protocolId < 477) { // ToDo
return Colors.byId(defaultValue);
return ChatColors.getColorById(defaultValue);
}
return Colors.byId(sets.getInt(super.getLastDataIndex() + 2, defaultValue));
return ChatColors.getColorById(sets.getInt(super.getLastDataIndex() + 2, defaultValue));
}
@Override

View File

@ -12,7 +12,7 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import javax.annotation.Nullable;
@ -32,8 +32,8 @@ public class CommandBlockMinecartMetaData extends EntityMetaData {
}
@Nullable
public TextComponent getLastOutput() {
final TextComponent defaultValue = null;
public BaseComponent getLastOutput() {
final BaseComponent defaultValue = null;
if (protocolId < 110) { //ToDo
return defaultValue;
}

View File

@ -18,6 +18,7 @@ import de.bixilon.minosoft.game.datatypes.entities.VillagerData;
import de.bixilon.minosoft.game.datatypes.inventory.Slot;
import de.bixilon.minosoft.game.datatypes.objectLoader.blocks.Block;
import de.bixilon.minosoft.game.datatypes.objectLoader.particle.data.ParticleData;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.util.BitByte;
@ -132,12 +133,12 @@ public class EntityMetaData {
}
@Nullable
public TextComponent getNameTag() {
public BaseComponent getNameTag() {
if (protocolId <= 110) { //ToDo
return null;
}
if (protocolId <= 335) { //ToDo
return new TextComponent(sets.getString(2, null));
return BaseComponent.fromString(sets.getString(2, null));
}
return sets.getTextComponent(2, null);
}
@ -322,8 +323,8 @@ public class EntityMetaData {
return (Slot) get(index, defaultValue);
}
public TextComponent getTextComponent(int index, TextComponent defaultValue) {
return (TextComponent) get(index, defaultValue);
public BaseComponent getTextComponent(int index, BaseComponent defaultValue) {
return (BaseComponent) get(index, defaultValue);
}
public String getString(int index, String defaultValue) {

View File

@ -12,8 +12,8 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.player.Hands;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import javax.annotation.Nullable;
@ -70,12 +70,12 @@ public class LivingMetaData extends EntityMetaData {
@Nullable
@Override
public TextComponent getNameTag() {
public BaseComponent getNameTag() {
if (protocolId < 7) { //ToDo
return new TextComponent(sets.getString(10, null));
return BaseComponent.fromString(sets.getString(10, null));
}
if (protocolId < 57) { //ToDo
return new TextComponent(sets.getString(2, null));
return BaseComponent.fromString(sets.getString(2, null));
}
return super.getNameTag();
}

View File

@ -12,7 +12,9 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
import de.bixilon.minosoft.game.datatypes.Colors;
import de.bixilon.minosoft.game.datatypes.text.ChatColors;
import de.bixilon.minosoft.game.datatypes.text.RGBColor;
import javax.annotation.Nullable;
@ -31,12 +33,15 @@ public class LlamaMetaData extends ChestedHorseMetaData {
}
@Nullable
public Colors getCarpetColor() {
final int defaultValue = -1;
public RGBColor getCarpetColor() {
final RGBColor defaultValue = null;
if (protocolId < 315) { // ToDo
return Colors.byId(defaultValue);
return defaultValue;
}
return Colors.byId(sets.getInt(super.getLastDataIndex() + 2, defaultValue));
if (!sets.containsKey(super.getLastDataIndex() + 2)) {
return defaultValue;
}
return ChatColors.getColorById(sets.getInt(super.getLastDataIndex() + 2, 0));
}
public LlamaVariants getVariant() {

View File

@ -12,7 +12,9 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
import de.bixilon.minosoft.game.datatypes.Colors;
import de.bixilon.minosoft.game.datatypes.text.ChatColors;
import de.bixilon.minosoft.game.datatypes.text.RGBColor;
public class SheepMetaData extends AnimalMetaData {
@ -20,12 +22,12 @@ public class SheepMetaData extends AnimalMetaData {
super(sets, protocolId);
}
public Colors getColor() {
final int defaultValue = Colors.WHITE.ordinal();
public RGBColor getColor() {
final int defaultValue = ChatColors.getColorId(ChatColors.getColorByName("white"));
if (protocolId < 57) {
return Colors.byId(sets.getInt(16, defaultValue) & 0xF);
return ChatColors.getColorById(sets.getInt(16, defaultValue) & 0xF);
}
return Colors.byId(sets.getInt(super.getLastDataIndex() + 1, defaultValue) & 0xF);
return ChatColors.getColorById(sets.getInt(super.getLastDataIndex() + 1, defaultValue) & 0xF);
}
public boolean isSheared() {

View File

@ -12,8 +12,9 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
import de.bixilon.minosoft.game.datatypes.Colors;
import de.bixilon.minosoft.game.datatypes.Directions;
import de.bixilon.minosoft.game.datatypes.text.ChatColors;
import de.bixilon.minosoft.game.datatypes.text.RGBColor;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import javax.annotation.Nullable;
@ -49,12 +50,12 @@ public class ShulkerMetaData extends GolemMetaData {
return sets.getByte(super.getLastDataIndex(), defaultValue);
}
public Colors getColor() {
final int defaultValue = Colors.PURPLE.ordinal();
public RGBColor getColor() {
final int defaultValue = ChatColors.getColorId(ChatColors.getColorByName("purple"));
if (protocolId < 110) { //ToDo
return Colors.byId(defaultValue);
return ChatColors.getColorById(defaultValue);
}
return Colors.byId(sets.getByte(super.getLastDataIndex(), defaultValue));
return ChatColors.getColorById(sets.getByte(super.getLastDataIndex(), defaultValue));
}
@Override

View File

@ -12,7 +12,9 @@
*/
package de.bixilon.minosoft.game.datatypes.entities.meta;
import de.bixilon.minosoft.game.datatypes.Colors;
import de.bixilon.minosoft.game.datatypes.text.ChatColors;
import de.bixilon.minosoft.game.datatypes.text.RGBColor;
public class WolfMetaData extends TameableMetaData {
@ -64,12 +66,12 @@ public class WolfMetaData extends TameableMetaData {
return sets.getBoolean(super.getLastDataIndex() + 1, defaultValue);
}
public Colors getColor() {
final int defaultValue = Colors.RED.ordinal();
public RGBColor getColor() {
final int defaultValue = ChatColors.getColorId(ChatColors.getColorByName("red"));
if (protocolId < 57) {
return Colors.byId(sets.getByte(20, defaultValue));
return ChatColors.getColorById(sets.getByte(20, defaultValue));
}
return Colors.byId(sets.getInt(super.getLastDataIndex() + 2, defaultValue));
return ChatColors.getColorById(sets.getByte(super.getLastDataIndex() + 2, defaultValue));
}
public int getAngerTime() {

View File

@ -13,15 +13,15 @@
package de.bixilon.minosoft.game.datatypes.inventory;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
public class InventoryProperties {
final int windowId;
final InventoryTypes type;
final TextComponent title;
final BaseComponent title;
final byte slotCount;
public InventoryProperties(int windowId, InventoryTypes type, TextComponent title, byte slotCount) {
public InventoryProperties(int windowId, InventoryTypes type, BaseComponent title, byte slotCount) {
this.windowId = windowId;
this.type = type;
this.title = title;
@ -36,7 +36,7 @@ public class InventoryProperties {
return type;
}
public TextComponent getTitle() {
public BaseComponent getTitle() {
return title;
}

View File

@ -13,10 +13,10 @@
package de.bixilon.minosoft.game.datatypes.inventory;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.objectLoader.CustomMapping;
import de.bixilon.minosoft.game.datatypes.objectLoader.enchantments.Enchantment;
import de.bixilon.minosoft.game.datatypes.objectLoader.items.Item;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.util.BitByte;
import de.bixilon.minosoft.util.nbt.tag.*;
@ -31,11 +31,11 @@ public class Slot {
short itemMetadata;
int repairCost;
int durability;
TextComponent customDisplayName;
BaseComponent customDisplayName;
boolean unbreakable;
String skullOwner;
byte hideFlags;
ArrayList<TextComponent> lore = new ArrayList<>();
ArrayList<BaseComponent> lore = new ArrayList<>();
public Slot(CustomMapping mapping, Item item, int itemCount, CompoundTag nbt) {
this.item = item;
@ -53,11 +53,11 @@ public class Slot {
if (nbt.containsKey("display")) {
CompoundTag display = nbt.getCompoundTag("display");
if (display.containsKey("Name")) {
this.customDisplayName = new TextComponent(display.getStringTag("Name").getValue());
this.customDisplayName = BaseComponent.fromString(display.getStringTag("Name").getValue());
}
if (display.containsKey("Lore")) {
for (StringTag lore : display.getListTag("Lore").<StringTag>getValue()) {
this.lore.add(new TextComponent(lore.getValue()));
this.lore.add(BaseComponent.fromString(lore.getValue()));
}
}
}
@ -109,7 +109,7 @@ public class Slot {
display.writeTag("Name", new StringTag(customDisplayName.getLegacyText()));
}
if (lore.size() > 0) {
display.writeTag("Lore", new ListTag(TagTypes.STRING, lore.stream().map(TextComponent::getLegacyText).map(StringTag::new).toArray(StringTag[]::new)));
display.writeTag("Lore", new ListTag(TagTypes.STRING, lore.stream().map(BaseComponent::getLegacyText).map(StringTag::new).toArray(StringTag[]::new)));
}
if (display.size() > 0) {
nbt.writeTag("display", display);
@ -185,19 +185,19 @@ public class Slot {
}
public String getDisplayName() {
TextComponent customName = getCustomDisplayName();
BaseComponent customName = getCustomDisplayName();
if (customName != null) {
return customName.getColoredMessage();
return customName.getANSIColoredMessage();
}
return (item == null ? "AIR" : item.toString()); // ToDo display name per Item (from language file)
}
@Nullable
public TextComponent getCustomDisplayName() {
public BaseComponent getCustomDisplayName() {
return customDisplayName;
}
public void setCustomDisplayName(TextComponent customDisplayName) {
public void setCustomDisplayName(BaseComponent customDisplayName) {
this.customDisplayName = customDisplayName;
}
@ -271,7 +271,7 @@ public class Slot {
this.skullOwner = skullOwner;
}
public ArrayList<TextComponent> getLore() {
public ArrayList<BaseComponent> getLore() {
return lore;
}

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.game.datatypes.player;
import de.bixilon.minosoft.game.datatypes.GameModes;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import java.util.HashMap;
import java.util.UUID;
@ -28,7 +28,7 @@ public class PlayerListItem {
int ping;
//optional fields
GameModes gameMode;
TextComponent displayName;
BaseComponent displayName;
HashMap<PlayerProperties, PlayerProperty> properties;
/**
@ -44,7 +44,7 @@ public class PlayerListItem {
this.legacy = true;
}
public PlayerListItem(UUID uuid, String name, int ping, GameModes gameMode, TextComponent displayName, HashMap<PlayerProperties, PlayerProperty> properties) {
public PlayerListItem(UUID uuid, String name, int ping, GameModes gameMode, BaseComponent displayName, HashMap<PlayerProperties, PlayerProperty> properties) {
this.uuid = uuid;
this.name = name;
this.ping = ping;
@ -78,15 +78,15 @@ public class PlayerListItem {
this.gameMode = gameMode;
}
public TextComponent getDisplayName() {
return (hasDisplayName() ? displayName : new TextComponent(name));
public BaseComponent getDisplayName() {
return (hasDisplayName() ? displayName : BaseComponent.fromString(name));
}
public boolean hasDisplayName() {
return displayName != null;
}
public void setDisplayName(TextComponent displayName) {
public void setDisplayName(BaseComponent displayName) {
this.displayName = displayName;
}

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.game.datatypes.player;
import de.bixilon.minosoft.game.datatypes.GameModes;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketPlayerListItem;
import java.util.HashMap;
@ -29,7 +29,7 @@ public class PlayerListItemBulk {
final int ping;
//optional fields
final GameModes gameMode;
final TextComponent displayName;
final BaseComponent displayName;
final HashMap<PlayerProperties, PlayerProperty> properties;
final PacketPlayerListItem.PlayerListItemActions action;
@ -44,7 +44,7 @@ public class PlayerListItemBulk {
this.legacy = true;
}
public PlayerListItemBulk(UUID uuid, String name, int ping, GameModes gameMode, TextComponent displayName, HashMap<PlayerProperties, PlayerProperty> properties, PacketPlayerListItem.PlayerListItemActions action) {
public PlayerListItemBulk(UUID uuid, String name, int ping, GameModes gameMode, BaseComponent displayName, HashMap<PlayerProperties, PlayerProperty> properties, PacketPlayerListItem.PlayerListItemActions action) {
this.uuid = uuid;
this.name = name;
this.ping = ping;
@ -71,8 +71,8 @@ public class PlayerListItemBulk {
return gameMode;
}
public TextComponent getDisplayName() {
return (hasDisplayName() ? displayName : new TextComponent(name));
public BaseComponent getDisplayName() {
return (hasDisplayName() ? displayName : BaseComponent.fromString(name));
}
public boolean hasDisplayName() {

View File

@ -13,13 +13,13 @@
package de.bixilon.minosoft.game.datatypes.player.advancements;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.inventory.Slot;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.util.BitByte;
public class AdvancementDisplay {
final TextComponent title;
final TextComponent description;
final BaseComponent title;
final BaseComponent description;
final Slot icon;
final AdvancementFrameTypes frameType;
final int flags;
@ -27,7 +27,7 @@ public class AdvancementDisplay {
final float x;
final float y;
public AdvancementDisplay(TextComponent title, TextComponent description, Slot icon, AdvancementFrameTypes frameType, int flags, String backgroundTexture, float x, float y) {
public AdvancementDisplay(BaseComponent title, BaseComponent description, Slot icon, AdvancementFrameTypes frameType, int flags, String backgroundTexture, float x, float y) {
this.title = title;
this.description = description;
this.icon = icon;
@ -38,7 +38,7 @@ public class AdvancementDisplay {
this.y = y;
}
public AdvancementDisplay(TextComponent title, TextComponent description, Slot icon, AdvancementFrameTypes frameType, int flags, float x, float y) {
public AdvancementDisplay(BaseComponent title, BaseComponent description, Slot icon, AdvancementFrameTypes frameType, int flags, float x, float y) {
this.title = title;
this.description = description;
this.icon = icon;
@ -49,11 +49,11 @@ public class AdvancementDisplay {
this.y = y;
}
public TextComponent getTitle() {
public BaseComponent getTitle() {
return title;
}
public TextComponent getDescription() {
public BaseComponent getDescription() {
return description;
}

View File

@ -13,16 +13,16 @@
package de.bixilon.minosoft.game.datatypes.scoreboard;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import java.util.HashMap;
public class ScoreboardObjective {
final String objectiveName;
final HashMap<String, ScoreboardScore> scores = new HashMap<>();
TextComponent objectiveValue;
BaseComponent objectiveValue;
public ScoreboardObjective(String objectiveName, TextComponent objectiveValue) {
public ScoreboardObjective(String objectiveName, BaseComponent objectiveValue) {
this.objectiveName = objectiveName;
this.objectiveValue = objectiveValue;
}
@ -31,7 +31,7 @@ public class ScoreboardObjective {
return objectiveName;
}
public TextComponent getObjectiveValue() {
public BaseComponent getObjectiveValue() {
return objectiveValue;
}
@ -57,7 +57,7 @@ public class ScoreboardObjective {
return scores.get(itemName);
}
public void setValue(TextComponent value) {
public void setValue(BaseComponent value) {
objectiveValue = value;
}
}

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.game.datatypes.scoreboard;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import java.util.ArrayList;
import java.util.Arrays;
@ -22,13 +22,13 @@ import java.util.List;
public class Team {
final String name;
final ArrayList<String> players;
TextComponent displayName;
TextComponent prefix;
TextComponent suffix;
BaseComponent displayName;
BaseComponent prefix;
BaseComponent suffix;
boolean friendlyFire;
boolean seeFriendlyInvisibles;
public Team(String name, TextComponent displayName, TextComponent prefix, TextComponent suffix, boolean friendlyFire, boolean seeFriendlyInvisibles, String[] players) {
public Team(String name, BaseComponent displayName, BaseComponent prefix, BaseComponent suffix, boolean friendlyFire, boolean seeFriendlyInvisibles, String[] players) {
this.name = name;
this.displayName = displayName;
this.prefix = prefix;
@ -38,7 +38,7 @@ public class Team {
this.players = new ArrayList<>(Arrays.asList(players));
}
public void updateInformation(TextComponent displayName, TextComponent prefix, TextComponent suffix, boolean friendlyFire, boolean seeFriendlyInvisibles) {
public void updateInformation(BaseComponent displayName, BaseComponent prefix, BaseComponent suffix, boolean friendlyFire, boolean seeFriendlyInvisibles) {
this.displayName = displayName;
this.prefix = prefix;
this.suffix = suffix;
@ -50,15 +50,15 @@ public class Team {
return name;
}
public TextComponent getDisplayName() {
public BaseComponent getDisplayName() {
return displayName;
}
public TextComponent getPrefix() {
public BaseComponent getPrefix() {
return prefix;
}
public TextComponent getSuffix() {
public BaseComponent getSuffix() {
return suffix;
}

View File

@ -11,27 +11,28 @@
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
*/
package de.bixilon.minosoft.game.datatypes;
package de.bixilon.minosoft.game.datatypes.text;
public enum Colors {
WHITE,
ORANGE,
MAGENTA,
LIGHT_BLUE,
YELLOW,
LIME,
PINK,
GRAY,
SILVER,
CYAN,
PURPLE,
BLUE,
BROWN,
GREEN,
RED,
BLACK;
import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
public static Colors byId(int id) {
return values()[id];
public interface BaseComponent {
static BaseComponent fromString(String raw) {
if (raw == null) {
return new TextComponent();
}
try {
return new TextComponent(JsonParser.parseString(raw).getAsJsonObject());
} catch (JsonParseException | IllegalStateException ignored) {
}
return new TextComponent(raw);
}
String toString();
String getANSIColoredMessage();
String getLegacyText();
String getMessage();
}

View File

@ -0,0 +1,81 @@
/*
* 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.text;
import com.google.common.collect.HashBiMap;
public final class ChatColors {
private static final HashBiMap<Integer, RGBColor> colors = HashBiMap.create();
static {
colors.put(0, new RGBColor(0, 0, 0));
colors.put(1, new RGBColor(0, 0, 170));
colors.put(2, new RGBColor(0, 170, 0));
colors.put(3, new RGBColor(0, 170, 170));
colors.put(4, new RGBColor(170, 0, 0));
colors.put(5, new RGBColor(170, 0, 170));
colors.put(6, new RGBColor(255, 170, 0));
colors.put(7, new RGBColor(170, 170, 170));
colors.put(8, new RGBColor(85, 85, 85));
colors.put(9, new RGBColor(85, 85, 255));
colors.put(10, new RGBColor(85, 255, 85));
colors.put(11, new RGBColor(85, 255, 255));
colors.put(12, new RGBColor(255, 85, 85));
colors.put(13, new RGBColor(255, 85, 255));
colors.put(14, new RGBColor(255, 255, 85));
colors.put(15, new RGBColor(255, 255, 255));
}
public static String getANSIColorByFormattingChar(char c) {
return getANSIColorByRGBColor(getColorByFormattingChar(c));
}
public static String getANSIColorByRGBColor(RGBColor color) {
return String.format("\033[38;2;%d;%d;%dm", color.getRed(), color.getGreen(), color.getBlue());
}
public static RGBColor getColorByFormattingChar(char c) {
return colors.get(Character.digit(c, 16));
}
public static RGBColor getColorById(int id) {
return colors.get(id);
}
public static int getColorId(RGBColor color) {
return colors.inverse().get(color);
}
public static RGBColor getColorByName(String name) {
return colors.get(switch (name.toLowerCase()) {
case "black" -> 0;
case "dark_blue" -> 1;
case "dark_green" -> 2;
case "dark_aqua" -> 3;
case "dark_red" -> 4;
case "dark_purple" -> 5;
case "gold" -> 6;
case "gray", "grey" -> 7;
case "dark_gray", "dark_grey" -> 8;
case "blue" -> 9;
case "green" -> 10;
case "aqua" -> 11;
case "red" -> 12;
case "light_purple" -> 13;
case "yellow" -> 14;
case "white" -> 15;
default -> throw new IllegalStateException("Unexpected value: " + name);
});
}
}

View File

@ -0,0 +1,77 @@
/*
* 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.text;
import com.google.common.collect.HashBiMap;
import java.util.Arrays;
public enum ChatFormattingCodes {
OBFUSCATED('k', "\u001b[5m"),
BOLD('l', "\u001b[1m"),
STRIKETHROUGH('m', "\u001b[9m"),
UNDERLINED('n', "\u001b[4m"),
ITALIC('o', "\u001b[3m"),
RESET('r', "\u001b[0m", ChatFormattingCodePosition.POST);
private final static HashBiMap<Character, ChatFormattingCodes> formattingCodes = HashBiMap.create();
static {
Arrays.stream(values()).forEach(chatFormattingCodes -> formattingCodes.put(chatFormattingCodes.getChar(), chatFormattingCodes));
}
final char c;
final String ansi;
final ChatFormattingCodePosition position;
ChatFormattingCodes(char c, String ansi) {
this.c = c;
this.ansi = ansi;
this.position = ChatFormattingCodePosition.PRE;
}
ChatFormattingCodes(char c, String ansi, ChatFormattingCodePosition position) {
this.c = c;
this.ansi = ansi;
this.position = position;
}
public static ChatFormattingCodes getChatFormattingCodeByChar(char c) {
return formattingCodes.get(c);
}
public char getChar() {
return c;
}
public ChatFormattingCodePosition getPosition() {
return position;
}
@Override
public String toString() {
return getANSI();
}
public String getANSI() {
return ansi;
}
public enum ChatFormattingCodePosition {
PRE,
POST
}
}

View File

@ -0,0 +1,171 @@
/*
* 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.text;
import java.util.HashSet;
import java.util.Objects;
public class ChatPart implements BaseComponent {
private final String text;
private RGBColor color;
private HashSet<ChatFormattingCodes> formatting;
public ChatPart(String text, RGBColor color, HashSet<ChatFormattingCodes> formatting) {
this.text = text;
this.color = color;
this.formatting = formatting;
}
public ChatPart(String text, RGBColor color) {
this.text = text;
this.color = color;
}
public ChatPart(String text) {
this.text = text;
}
public ChatPart setObfuscated(boolean obfuscated) {
if (obfuscated) {
formatting.add(ChatFormattingCodes.OBFUSCATED);
} else {
formatting.remove(ChatFormattingCodes.OBFUSCATED);
}
return this;
}
public ChatPart setBold(boolean bold) {
if (bold) {
formatting.add(ChatFormattingCodes.BOLD);
} else {
formatting.remove(ChatFormattingCodes.BOLD);
}
return this;
}
public ChatPart setStrikethrough(boolean strikethrough) {
if (strikethrough) {
formatting.add(ChatFormattingCodes.STRIKETHROUGH);
} else {
formatting.remove(ChatFormattingCodes.STRIKETHROUGH);
}
return this;
}
public ChatPart setUnderlined(boolean underlined) {
if (underlined) {
formatting.add(ChatFormattingCodes.UNDERLINED);
} else {
formatting.remove(ChatFormattingCodes.UNDERLINED);
}
return this;
}
public ChatPart setItalic(boolean italic) {
if (italic) {
formatting.add(ChatFormattingCodes.ITALIC);
} else {
formatting.remove(ChatFormattingCodes.ITALIC);
}
return this;
}
public ChatPart setReset(boolean reset) {
if (reset) {
formatting.add(ChatFormattingCodes.RESET);
} else {
formatting.remove(ChatFormattingCodes.RESET);
}
return this;
}
public RGBColor getColor() {
return color;
}
public ChatPart setColor(RGBColor color) {
this.color = color;
return this;
}
public HashSet<ChatFormattingCodes> getFormatting() {
return formatting;
}
public ChatPart setFormatting(HashSet<ChatFormattingCodes> formatting) {
this.formatting = formatting;
return this;
}
@Override
public boolean equals(Object obj) {
if (super.equals(obj)) {
return true;
}
if (hashCode() != obj.hashCode()) {
return false;
}
ChatPart their = (ChatPart) obj;
return text.equals(their.getMessage()) && color.equals(their.getColor()) && formatting.equals(their.getFormatting());
}
@Override
public int hashCode() {
return Objects.hash(text, color, formatting);
}
@Override
public String getANSIColoredMessage() {
StringBuilder builder = new StringBuilder();
if (color != null) {
builder.append(ChatColors.getANSIColorByRGBColor(color));
}
if (formatting != null) {
formatting.forEach((chatFormattingCodes -> {
if (chatFormattingCodes.getPosition() == ChatFormattingCodes.ChatFormattingCodePosition.PRE) {
builder.append(chatFormattingCodes.getANSI());
}
}));
}
builder.append(text);
if (formatting != null) {
formatting.forEach((chatFormattingCodes -> {
if (chatFormattingCodes.getPosition() == ChatFormattingCodes.ChatFormattingCodePosition.POST) {
builder.append(chatFormattingCodes.getANSI());
}
}));
}
builder.append(ChatFormattingCodes.RESET);
return builder.toString();
}
@Override
public String getLegacyText() {
return getMessage(); //ToDo
}
@Override
public String getMessage() {
return text;
}
@Override
public String toString() {
return getANSIColoredMessage();
}
}

View File

@ -0,0 +1,67 @@
/*
* 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.text;
public final class RGBColor {
private final int color;
public RGBColor(int color) {
this.color = color;
}
public RGBColor(int red, int green, int blue) {
this.color = blue | (green << 8) | (red << 16);
}
public RGBColor(String colorString) {
if (colorString.startsWith("#")) {
colorString = colorString.substring(1);
}
color = Integer.parseInt(colorString, 16);
}
public int getColor() {
return color;
}
public int getRed() {
return (color >> 16) & 0xFF;
}
public int getGreen() {
return (color >> 8) & 0xFF;
}
public int getBlue() {
return color & 0xFF;
}
@Override
public boolean equals(Object obj) {
if (super.equals(obj)) {
return true;
}
return hashCode() == obj.hashCode();
}
@Override
public int hashCode() {
return color;
}
@Override
public String toString() {
return String.format("#%06X", (0xFFFFFF & color));
}
}

View File

@ -0,0 +1,190 @@
/*
* 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.text;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import javax.annotation.Nullable;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.HashSet;
public class TextComponent implements BaseComponent {
private final ArrayList<BaseComponent> parts = new ArrayList<>();
public TextComponent() {
}
public TextComponent(String text) {
// legacy String
StringBuilder currentText = new StringBuilder();
RGBColor color = null;
HashSet<ChatFormattingCodes> formattingCodes = new HashSet<>();
StringCharacterIterator iterator = new StringCharacterIterator(text);
while (iterator.current() != CharacterIterator.DONE) {
char c = iterator.current();
iterator.next();
if (c != '§') {
currentText.append(c);
continue;
}
// check next char
char nextFormattingChar = iterator.current();
iterator.next();
RGBColor nextColor = ChatColors.getColorByFormattingChar(nextFormattingChar);
if (nextColor != null && nextColor != color) {
// color change, add text part
if (currentText.length() > 0) {
parts.add(new ChatPart(currentText.toString(), color, formattingCodes));
currentText = new StringBuilder();
}
color = nextColor;
formattingCodes = new HashSet<>();
continue;
}
ChatFormattingCodes nextFormattingCode = ChatFormattingCodes.getChatFormattingCodeByChar(nextFormattingChar);
if (nextFormattingCode != null) {
if (currentText.length() > 0) {
parts.add(new ChatPart(currentText.toString(), color, formattingCodes));
currentText = new StringBuilder();
color = null;
formattingCodes = new HashSet<>();
}
formattingCodes.add(nextFormattingCode);
if (nextFormattingCode == ChatFormattingCodes.RESET) {
// special rule here
if (currentText.length() > 0) {
// color change, add text part
parts.add(new ChatPart(currentText.toString(), color, formattingCodes));
currentText = new StringBuilder();
}
color = null;
formattingCodes = new HashSet<>();
}
}
}
if (currentText.length() > 0) {
parts.add(new ChatPart(currentText.toString(), color, formattingCodes));
}
}
public TextComponent(JsonObject json) {
this(null, json);
}
public TextComponent(@Nullable ChatPart parent, JsonObject json) {
ChatPart thisChatPart = null;
if (json.has("text")) {
String text = json.get("text").getAsString();
if (text.contains("§")) {
// legacy text component
parts.add(new TextComponent(text));
return;
}
RGBColor color;
if (parent != null && parent.getColor() != null) {
color = parent.getColor();
} else {
color = null;
}
if (json.has("color")) {
String colorString = json.get("color").getAsString();
if (colorString.startsWith("#")) {
// RGB
color = new RGBColor(colorString);
} else {
color = ChatColors.getColorByName(colorString);
}
}
HashSet<ChatFormattingCodes> formattingCodes;
if (parent != null && parent.getFormatting() != null) {
formattingCodes = (HashSet<ChatFormattingCodes>) parent.getFormatting().clone();
} else {
formattingCodes = new HashSet<>();
}
if (json.has("bold")) {
if (json.get("bold").getAsBoolean()) {
formattingCodes.add(ChatFormattingCodes.BOLD);
} else {
formattingCodes.remove(ChatFormattingCodes.BOLD);
}
}
if (json.has("italic")) {
if (json.get("italic").getAsBoolean()) {
formattingCodes.add(ChatFormattingCodes.ITALIC);
} else {
formattingCodes.remove(ChatFormattingCodes.ITALIC);
}
}
if (json.has("underlined")) {
if (json.get("underlined").getAsBoolean()) {
formattingCodes.add(ChatFormattingCodes.UNDERLINED);
} else {
formattingCodes.remove(ChatFormattingCodes.UNDERLINED);
}
}
if (json.has("strikethrough")) {
if (json.get("strikethrough").getAsBoolean()) {
formattingCodes.add(ChatFormattingCodes.STRIKETHROUGH);
} else {
formattingCodes.remove(ChatFormattingCodes.STRIKETHROUGH);
}
}
if (json.has("obfuscated")) {
if (json.get("obfuscated").getAsBoolean()) {
formattingCodes.add(ChatFormattingCodes.OBFUSCATED);
} else {
formattingCodes.remove(ChatFormattingCodes.OBFUSCATED);
}
}
thisChatPart = new ChatPart(text, color, formattingCodes);
}
if (json.has("extra")) {
JsonArray extras = json.getAsJsonArray("extra");
ChatPart finalThisChatPart = thisChatPart;
extras.forEach((extra -> parts.add(new TextComponent(finalThisChatPart, extra.getAsJsonObject()))));
}
if (thisChatPart != null) {
parts.add(thisChatPart);
}
}
@Override
public String toString() {
return getANSIColoredMessage();
}
public String getANSIColoredMessage() {
StringBuilder builder = new StringBuilder();
parts.forEach((chatPart -> builder.append(chatPart.getANSIColoredMessage())));
builder.append(ChatFormattingCodes.RESET);
return builder.toString();
}
public String getLegacyText() {
return getMessage(); //ToDo
}
public String getMessage() {
StringBuilder builder = new StringBuilder();
parts.forEach((chatPart -> builder.append(chatPart.getMessage())));
return builder.toString();
}
}

View File

@ -169,7 +169,7 @@ public class ServerListCell extends ListCell<Server> implements Initializable {
}
serverBrand.setText(ping.getServerModInfo().getBrand());
serverBrand.setTooltip(new Tooltip(ping.getServerModInfo().getInfo()));
motd.setText(ping.getMotd().getRawMessage());
motd.setText(ping.getMotd().getMessage());
if (ping.getFavicon() != null) {
icon.setImage(ping.getFavicon());
if (!ping.getBase64EncodedFavicon().equals(server.getBase64Favicon())) {
@ -392,7 +392,7 @@ public class ServerListCell extends ListCell<Server> implements Initializable {
Label serverVersionLabel = new Label(serverVersionString);
Label serverBrandLabel = new Label(lastPing.getServerBrand());
Label playersOnlineMaxLabel = new Label(String.format("%d/%d", lastPing.getPlayerOnline(), lastPing.getMaxPlayers()));
Label motdLabel = new Label(lastPing.getMotd().getRawMessage());
Label motdLabel = new Label(lastPing.getMotd().getMessage());
Label moddedBrandLabel = new Label(lastPing.getServerModInfo().getBrand());
grid.add(new Label("Real server address:"), 0, ++column);

View File

@ -14,7 +14,9 @@
package de.bixilon.minosoft.logging;
import de.bixilon.minosoft.Config;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.ChatColors;
import de.bixilon.minosoft.game.datatypes.text.ChatFormattingCodes;
import de.bixilon.minosoft.game.datatypes.text.RGBColor;
import java.text.SimpleDateFormat;
import java.util.concurrent.LinkedBlockingQueue;
@ -51,14 +53,14 @@ public class Log {
* @param message Raw message to log
*/
public static void game(String message) {
log(LogLevels.GAME, message, TextComponent.ChatAttributes.GREEN);
log(LogLevels.GAME, message, ChatColors.getColorByName("green"));
}
public static void log(LogLevels level, String message, TextComponent.ChatAttributes color) {
public static void log(LogLevels level, String message, RGBColor color) {
log(level, "", message, color);
}
public static void log(LogLevels level, String prefix, String message, TextComponent.ChatAttributes color) {
public static void log(LogLevels level, String prefix, String message, RGBColor color) {
if (level.ordinal() > Log.level.ordinal()) {
// log level too low
return;
@ -73,12 +75,13 @@ public class Log {
builder.append("] ");
builder.append(prefix);
if (color != null && Config.colorLog) {
builder.append(color);
builder.append(ChatColors.getANSIColorByRGBColor(color));
builder.append(message);
builder.append(TextComponent.ChatAttributes.RESET);
builder.append(ChatFormattingCodes.RESET.getANSI());
} else {
builder.append(message);
}
builder.append(ChatFormattingCodes.RESET.getANSI());
queue.add(builder.toString());
}
@ -88,7 +91,7 @@ public class Log {
* @param message Raw message to log
*/
public static void fatal(String message) {
log(LogLevels.FATAL, message, TextComponent.ChatAttributes.DARK_RED);
log(LogLevels.FATAL, message, ChatColors.getColorByName("dark_red"));
}
/**
@ -97,7 +100,7 @@ public class Log {
* @param message Raw message to log
*/
public static void warn(String message) {
log(LogLevels.WARNING, message, TextComponent.ChatAttributes.RED);
log(LogLevels.WARNING, message, ChatColors.getColorByName("red"));
}
/**
@ -106,7 +109,7 @@ public class Log {
* @param message Raw message to log
*/
public static void debug(String message) {
log(LogLevels.DEBUG, message, TextComponent.ChatAttributes.GRAY);
log(LogLevels.DEBUG, message, ChatColors.getColorByName("gray"));
}
/**
@ -115,7 +118,7 @@ public class Log {
* @param message Raw message to log
*/
public static void verbose(String message) {
log(LogLevels.VERBOSE, message, TextComponent.ChatAttributes.YELLOW);
log(LogLevels.VERBOSE, message, ChatColors.getColorByName("yellow"));
}
/**
@ -124,7 +127,7 @@ public class Log {
* @param message Raw message to log
*/
public static void protocol(String message) {
log(LogLevels.PROTOCOL, message, TextComponent.ChatAttributes.BLUE);
log(LogLevels.PROTOCOL, message, ChatColors.getColorByName("blue"));
}
/**
@ -133,7 +136,7 @@ public class Log {
* @param message Raw message to log
*/
public static void mojang(String message) {
log(LogLevels.MOJANG, message, TextComponent.ChatAttributes.AQUA);
log(LogLevels.MOJANG, message, ChatColors.getColorByName("aqua"));
}
public static LogLevels getLevel() {
@ -154,6 +157,6 @@ public class Log {
* @param message Raw message to log
*/
public static void info(String message) {
log(LogLevels.INFO, message, TextComponent.ChatAttributes.WHITE);
log(LogLevels.INFO, message, ChatColors.getColorByName("white"));
}
}

View File

@ -13,7 +13,8 @@
package de.bixilon.minosoft.modding;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.ChatColors;
import de.bixilon.minosoft.game.datatypes.text.RGBColor;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.logging.LogLevels;
@ -30,10 +31,10 @@ public class Logger {
* @param message Raw message to log
*/
public void game(String message) {
log(LogLevels.GAME, message, TextComponent.ChatAttributes.GREEN);
log(LogLevels.GAME, message, ChatColors.getColorByName("green"));
}
public void log(LogLevels level, String message, TextComponent.ChatAttributes color) {
public void log(LogLevels level, String message, RGBColor color) {
Log.log(level, String.format("[%s] ", modName), message, color);
}
@ -43,7 +44,7 @@ public class Logger {
* @param message Raw message to log
*/
public void fatal(String message) {
log(LogLevels.FATAL, message, TextComponent.ChatAttributes.DARK_RED);
log(LogLevels.FATAL, message, ChatColors.getColorByName("dark_red"));
}
/**
@ -52,7 +53,7 @@ public class Logger {
* @param message Raw message to log
*/
public void info(String message) {
log(LogLevels.INFO, message, TextComponent.ChatAttributes.WHITE);
log(LogLevels.INFO, message, ChatColors.getColorByName("white"));
}
/**
@ -61,7 +62,7 @@ public class Logger {
* @param message Raw message to log
*/
public void warn(String message) {
log(LogLevels.WARNING, message, TextComponent.ChatAttributes.RED);
log(LogLevels.WARNING, message, ChatColors.getColorByName("red"));
}
/**
@ -70,7 +71,7 @@ public class Logger {
* @param message Raw message to log
*/
public void debug(String message) {
log(LogLevels.DEBUG, message, TextComponent.ChatAttributes.GRAY);
log(LogLevels.DEBUG, message, ChatColors.getColorByName("gray"));
}
/**
@ -79,7 +80,7 @@ public class Logger {
* @param message Raw message to log
*/
public void verbose(String message) {
log(LogLevels.VERBOSE, message, TextComponent.ChatAttributes.YELLOW);
log(LogLevels.VERBOSE, message, ChatColors.getColorByName("yellow"));
}
/**
@ -88,6 +89,6 @@ public class Logger {
* @param message Raw message to log
*/
public void protocol(String message) {
log(LogLevels.PROTOCOL, message, TextComponent.ChatAttributes.BLUE);
log(LogLevels.PROTOCOL, message, ChatColors.getColorByName("blue"));
}
}

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.modding.event.events;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.modding.event.EventListener;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketBossBar;
@ -26,7 +26,7 @@ import java.util.UUID;
public class BossBarChangeEvent extends CancelableEvent {
private UUID uuid;
private PacketBossBar.BossBarActions action;
private TextComponent title;
private BaseComponent title;
private float health;
private PacketBossBar.BossBarColors color;
private PacketBossBar.BossBarDivisions divisions;
@ -35,7 +35,7 @@ public class BossBarChangeEvent extends CancelableEvent {
private boolean createFog;
public BossBarChangeEvent(Connection connection, UUID uuid, PacketBossBar.BossBarActions action, TextComponent title, float health, PacketBossBar.BossBarColors color, PacketBossBar.BossBarDivisions divisions, boolean isDragonBar, boolean shouldDarkenSky, boolean createFog) {
public BossBarChangeEvent(Connection connection, UUID uuid, PacketBossBar.BossBarActions action, BaseComponent title, float health, PacketBossBar.BossBarColors color, PacketBossBar.BossBarDivisions divisions, boolean isDragonBar, boolean shouldDarkenSky, boolean createFog) {
super(connection);
this.uuid = uuid;
this.action = action;
@ -77,11 +77,11 @@ public class BossBarChangeEvent extends CancelableEvent {
this.action = action;
}
public TextComponent getTitle() {
public BaseComponent getTitle() {
return title;
}
public void setTitle(TextComponent title) {
public void setTitle(BaseComponent title) {
this.title = title;
}

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.modding.event.events;
import de.bixilon.minosoft.game.datatypes.ChatTextPositions;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.modding.event.EventListener;
import de.bixilon.minosoft.modding.event.events.annotations.MinimumProtocolVersion;
import de.bixilon.minosoft.protocol.network.Connection;
@ -23,11 +23,11 @@ import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketChatMessageRe
import java.util.UUID;
public class ChatMessageReceivingEvent extends CancelableEvent {
private final TextComponent message;
private final BaseComponent message;
private final ChatTextPositions position;
private final UUID sender;
public ChatMessageReceivingEvent(Connection connection, TextComponent message, ChatTextPositions position, UUID sender) {
public ChatMessageReceivingEvent(Connection connection, BaseComponent message, ChatTextPositions position, UUID sender) {
super(connection);
this.message = message;
this.position = position;
@ -41,7 +41,7 @@ public class ChatMessageReceivingEvent extends CancelableEvent {
this.sender = pkg.getSender();
}
public TextComponent getMessage() {
public BaseComponent getMessage() {
return message;
}

View File

@ -13,15 +13,15 @@
package de.bixilon.minosoft.modding.event.events;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.modding.event.EventListener;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.packets.clientbound.login.PacketLoginDisconnect;
public class DisconnectEvent extends Event {
private final TextComponent reason;
private final BaseComponent reason;
public DisconnectEvent(Connection connection, TextComponent reason) {
public DisconnectEvent(Connection connection, BaseComponent reason) {
super(connection);
this.reason = reason;
}
@ -31,7 +31,7 @@ public class DisconnectEvent extends Event {
this.reason = pkg.getReason();
}
public TextComponent getReason() {
public BaseComponent getReason() {
return reason;
}

View File

@ -13,15 +13,15 @@
package de.bixilon.minosoft.modding.event.events;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.modding.event.EventListener;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.protocol.packets.clientbound.play.PacketDisconnect;
public class LoginDisconnectEvent extends Event {
private final TextComponent reason;
private final BaseComponent reason;
public LoginDisconnectEvent(Connection connection, TextComponent reason) {
public LoginDisconnectEvent(Connection connection, BaseComponent reason) {
super(connection);
this.reason = reason;
}
@ -31,7 +31,7 @@ public class LoginDisconnectEvent extends Event {
this.reason = pkg.getReason();
}
public TextComponent getReason() {
public BaseComponent getReason() {
return reason;
}

View File

@ -14,7 +14,8 @@
package de.bixilon.minosoft.ping;
import com.google.gson.JsonObject;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.game.datatypes.text.TextComponent;
import de.bixilon.minosoft.gui.main.GUITools;
import javafx.scene.image.Image;
@ -25,7 +26,7 @@ public class ServerListPing {
int maxPlayers;
String base64Favicon;
Image favicon;
TextComponent motd;
BaseComponent motd;
String serverBrand;
public ServerListPing(JsonObject json) {
@ -37,10 +38,10 @@ public class ServerListPing {
favicon = GUITools.getImageFromBase64(base64Favicon);
}
try {
if (json.get("description").isJsonPrimitive()) {
motd = BaseComponent.fromString(json.get("description").getAsString());
} else {
motd = new TextComponent(json.getAsJsonObject("description"));
} catch (Exception ignored) {
motd = new TextComponent(json.get("description").getAsString());
}
serverBrand = json.getAsJsonObject("version").get("name").getAsString();
@ -71,7 +72,7 @@ public class ServerListPing {
return favicon;
}
public TextComponent getMotd() {
public BaseComponent getMotd() {
return motd;
}

View File

@ -13,14 +13,14 @@
package de.bixilon.minosoft.protocol.packets.clientbound.login;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
public class PacketLoginDisconnect implements ClientboundPacket {
TextComponent reason;
BaseComponent reason;
@Override
public boolean read(InByteBuffer buffer) {
@ -35,10 +35,10 @@ public class PacketLoginDisconnect implements ClientboundPacket {
@Override
public void log() {
Log.protocol(String.format("Receiving login disconnect packet (%s)", reason.getColoredMessage()));
Log.protocol(String.format("Receiving login disconnect packet (%s)", reason.getANSIColoredMessage()));
}
public TextComponent getReason() {
public BaseComponent getReason() {
return reason;
}
}

View File

@ -13,12 +13,12 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.inventory.Slot;
import de.bixilon.minosoft.game.datatypes.player.advancements.Advancement;
import de.bixilon.minosoft.game.datatypes.player.advancements.AdvancementDisplay;
import de.bixilon.minosoft.game.datatypes.player.advancements.AdvancementProgress;
import de.bixilon.minosoft.game.datatypes.player.advancements.CriterionProgress;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -47,8 +47,8 @@ public class PacketAdvancements implements ClientboundPacket {
}
AdvancementDisplay display = null;
if (buffer.readBoolean()) {
TextComponent title = buffer.readTextComponent();
TextComponent description = buffer.readTextComponent();
BaseComponent title = buffer.readTextComponent();
BaseComponent description = buffer.readTextComponent();
Slot icon = buffer.readSlot();
AdvancementDisplay.AdvancementFrameTypes frameType = AdvancementDisplay.AdvancementFrameTypes.byId(buffer.readVarInt());
int flags = buffer.readInt();

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -27,7 +27,7 @@ public class PacketBossBar implements ClientboundPacket {
BossBarActions action;
//fields depend on action
TextComponent title;
BaseComponent title;
float health;
BossBarColors color;
BossBarDivisions divisions;
@ -64,10 +64,10 @@ public class PacketBossBar implements ClientboundPacket {
@Override
public void log() {
switch (action) {
case ADD -> Log.protocol(String.format("Received boss bar (action=%s, uuid=%s, title=\"%s\", health=%s, color=%s, divisions=%s, dragonBar=%s, darkenSky=%s)", action, uuid.toString(), title.getColoredMessage(), health, color, divisions, isDragonBar(), shouldDarkenSky()));
case ADD -> Log.protocol(String.format("Received boss bar (action=%s, uuid=%s, title=\"%s\", health=%s, color=%s, divisions=%s, dragonBar=%s, darkenSky=%s)", action, uuid.toString(), title.getANSIColoredMessage(), health, color, divisions, isDragonBar(), shouldDarkenSky()));
case REMOVE -> Log.protocol(String.format("Received boss bar (action=%s, uuid=%s)", action, uuid.toString()));
case UPDATE_HEALTH -> Log.protocol(String.format("Received boss bar (action=%s, uuid=%s, health=%s)", action, uuid.toString(), health));
case UPDATE_TITLE -> Log.protocol(String.format("Received boss bar (action=%s, uuid=%s, title=\"%s\")", action, uuid.toString(), title.getColoredMessage()));
case UPDATE_TITLE -> Log.protocol(String.format("Received boss bar (action=%s, uuid=%s, title=\"%s\")", action, uuid.toString(), title.getANSIColoredMessage()));
case UPDATE_STYLE -> Log.protocol(String.format("Received boss bar (action=%s, uuid=%s, color=%s, divisions=%s)", action, uuid.toString(), color, divisions));
case UPDATE_FLAGS -> Log.protocol(String.format("Received boss bar (action=%s, uuid=%s, dragonBar=%s, darkenSky=%s)", action, uuid.toString(), isDragonBar(), shouldDarkenSky()));
}
@ -101,7 +101,7 @@ public class PacketBossBar implements ClientboundPacket {
return health;
}
public TextComponent getTitle() {
public BaseComponent getTitle() {
return title;
}

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.ChatTextPositions;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -23,7 +23,7 @@ import de.bixilon.minosoft.protocol.protocol.PacketHandler;
import java.util.UUID;
public class PacketChatMessageReceiving implements ClientboundPacket {
TextComponent message;
BaseComponent message;
ChatTextPositions position;
UUID sender;
@ -48,10 +48,10 @@ public class PacketChatMessageReceiving implements ClientboundPacket {
@Override
public void log() {
Log.protocol(String.format("Received chat message (message=\"%s\")", message.getRawMessage()));
Log.protocol(String.format("Received chat message (message=\"%s\")", message.getMessage()));
}
public TextComponent getMessage() {
public BaseComponent getMessage() {
return message;
}

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -25,7 +25,7 @@ public class PacketCombatEvent implements ClientboundPacket {
int duration;
int playerId;
int entityId;
TextComponent message;
BaseComponent message;
@Override
public boolean read(InByteBuffer buffer) {

View File

@ -13,14 +13,14 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
public class PacketDisconnect implements ClientboundPacket {
TextComponent reason;
BaseComponent reason;
@Override
public boolean read(InByteBuffer buffer) {
@ -35,10 +35,10 @@ public class PacketDisconnect implements ClientboundPacket {
@Override
public void log() {
Log.game(String.format("Disconnected: %s", reason.getColoredMessage()));
Log.game(String.format("Disconnected: %s", reason.getANSIColoredMessage()));
}
public TextComponent getReason() {
public BaseComponent getReason() {
return reason;
}
}

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -110,7 +110,7 @@ public class PacketMapData implements ClientboundPacket {
byte x = buffer.readByte();
byte z = buffer.readByte();
byte direction = buffer.readByte();
TextComponent displayName = null;
BaseComponent displayName = null;
if (buffer.readBoolean()) {
displayName = buffer.readTextComponent();
}
@ -220,7 +220,7 @@ public class PacketMapData implements ClientboundPacket {
final byte direction;
final byte x;
final byte z;
final TextComponent displayName;
final BaseComponent displayName;
public MapPinSet(MapPinTypes type, int direction, byte x, byte z) {
this.type = type;
@ -230,7 +230,7 @@ public class PacketMapData implements ClientboundPacket {
displayName = null;
}
public MapPinSet(MapPinTypes type, int direction, byte x, byte z, TextComponent displayName) {
public MapPinSet(MapPinTypes type, int direction, byte x, byte z, BaseComponent displayName) {
this.type = type;
this.direction = (byte) direction;
this.x = x;

View File

@ -13,9 +13,9 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.inventory.InventoryProperties;
import de.bixilon.minosoft.game.datatypes.inventory.InventoryTypes;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -24,7 +24,7 @@ import de.bixilon.minosoft.protocol.protocol.PacketHandler;
public class PacketOpenWindow implements ClientboundPacket {
byte windowId;
InventoryTypes type;
TextComponent title;
BaseComponent title;
byte slotCount;
int entityId;
@ -72,7 +72,7 @@ public class PacketOpenWindow implements ClientboundPacket {
return entityId;
}
public TextComponent getTitle() {
public BaseComponent getTitle() {
return title;
}

View File

@ -14,10 +14,10 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.GameModes;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.player.PlayerListItemBulk;
import de.bixilon.minosoft.game.datatypes.player.PlayerProperties;
import de.bixilon.minosoft.game.datatypes.player.PlayerProperty;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -61,7 +61,7 @@ public class PacketPlayerListItem implements ClientboundPacket {
}
GameModes gameMode = GameModes.byId(buffer.readVarInt());
int ping = buffer.readVarInt();
TextComponent displayName = (buffer.readBoolean() ? buffer.readTextComponent() : null);
BaseComponent displayName = (buffer.readBoolean() ? buffer.readTextComponent() : null);
listItemBulk = new PlayerListItemBulk(uuid, name, ping, gameMode, displayName, playerProperties, action);
}
case UPDATE_GAMEMODE -> listItemBulk = new PlayerListItemBulk(uuid, null, 0, GameModes.byId(buffer.readVarInt()), null, null, action);

View File

@ -13,7 +13,6 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.ChatColors;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -41,43 +40,28 @@ public class PacketScoreboardDisplayScoreboard implements ClientboundPacket {
}
public enum ScoreboardAnimations {
LIST(0),
SIDEBAR(1),
BELOW_NAME(2),
TEAM_BLACK(ChatColors.BLACK.getColor() + 3),
TEAM_DARK_BLUE(ChatColors.DARK_BLUE.getColor() + 3),
TEAM_DARK_GREEN(ChatColors.DARK_GREEN.getColor() + 3),
TEAM_DARK_AQUA(ChatColors.DARK_AQUA.getColor() + 3),
TEAM_DARK_RED(ChatColors.DARK_RED.getColor() + 3),
TEAM_DARK_PURPLE(ChatColors.DARK_PURPLE.getColor() + 3),
TEAM_GOLD(ChatColors.GOLD.getColor() + 3),
TEAM_GRAY(ChatColors.GRAY.getColor() + 3),
TEAM_DARK_GRAY(ChatColors.DARK_GRAY.getColor() + 3),
TEAM_BLUE(ChatColors.BLUE.getColor() + 3),
TEAM_GREEN(ChatColors.GREEN.getColor() + 3),
TEAM_AQUA(ChatColors.AQUA.getColor() + 3),
TEAM_RED(ChatColors.RED.getColor() + 3),
TEAM_PURPLE(ChatColors.PURPLE.getColor() + 3),
TEAM_YELLOW(ChatColors.YELLOW.getColor() + 3),
TEAM_WHITE(ChatColors.WHITE.getColor() + 3);
final int id;
ScoreboardAnimations(int id) {
this.id = id;
}
LIST,
SIDEBAR,
BELOW_NAME,
TEAM_BLACK,
TEAM_DARK_BLUE,
TEAM_DARK_GREEN,
TEAM_DARK_AQUA,
TEAM_DARK_RED,
TEAM_DARK_PURPLE,
TEAM_GOLD,
TEAM_GRAY,
TEAM_DARK_GRAY,
TEAM_BLUE,
TEAM_GREEN,
TEAM_AQUA,
TEAM_RED,
TEAM_PURPLE,
TEAM_YELLOW,
TEAM_WHITE;
public static ScoreboardAnimations byId(int id) {
for (ScoreboardAnimations animation : values()) {
if (animation.getId() == id) {
return animation;
}
}
return null;
}
public int getId() {
return id;
return values()[id];
}
}
}

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -21,7 +21,7 @@ import de.bixilon.minosoft.protocol.protocol.PacketHandler;
public class PacketScoreboardObjective implements ClientboundPacket {
String name;
TextComponent value;
BaseComponent value;
ScoreboardObjectiveActions action;
ScoreboardObjectiveTypes type;
@ -59,7 +59,7 @@ public class PacketScoreboardObjective implements ClientboundPacket {
@Override
public void log() {
if (action == ScoreboardObjectiveActions.CREATE || action == ScoreboardObjectiveActions.UPDATE) {
Log.protocol(String.format("Received scoreboard objective action (action=%s, name=\"%s\", value=\"%s\", type=%s)", action, name, value.getColoredMessage(), type));
Log.protocol(String.format("Received scoreboard objective action (action=%s, name=\"%s\", value=\"%s\", type=%s)", action, name, value.getANSIColoredMessage(), type));
} else {
Log.protocol(String.format("Received scoreboard objective action (action=%s, name=\"%s\")", action, name));
}
@ -69,7 +69,7 @@ public class PacketScoreboardObjective implements ClientboundPacket {
return name;
}
public TextComponent getValue() {
public BaseComponent getValue() {
return value;
}

View File

@ -13,15 +13,15 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
public class PacketTabHeaderAndFooter implements ClientboundPacket {
TextComponent header;
TextComponent footer;
BaseComponent header;
BaseComponent footer;
@Override
public boolean read(InByteBuffer buffer) {
@ -37,15 +37,15 @@ public class PacketTabHeaderAndFooter implements ClientboundPacket {
@Override
public void log() {
Log.protocol(String.format("Received tab list header: %s", header.getColoredMessage()));
Log.protocol(String.format("Received tab list footer: %s", footer.getColoredMessage()));
Log.protocol(String.format("Received tab list header: %s", header.getANSIColoredMessage()));
Log.protocol(String.format("Received tab list footer: %s", footer.getANSIColoredMessage()));
}
public TextComponent getHeader() {
public BaseComponent getHeader() {
return header;
}
public TextComponent getFooter() {
public BaseComponent getFooter() {
return footer;
}
}

View File

@ -13,8 +13,9 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.ChatColors;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.game.datatypes.text.ChatColors;
import de.bixilon.minosoft.game.datatypes.text.RGBColor;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -24,14 +25,14 @@ import de.bixilon.minosoft.util.BitByte;
public class PacketTeams implements ClientboundPacket {
String name;
TeamActions action;
TextComponent displayName;
TextComponent prefix;
TextComponent suffix;
BaseComponent displayName;
BaseComponent prefix;
BaseComponent suffix;
boolean friendlyFire;
boolean seeFriendlyInvisibles;
TeamCollisionRules collisionRule = TeamCollisionRules.NEVER;
TeamNameTagVisibilities nameTagVisibility = TeamNameTagVisibilities.ALWAYS;
TextComponent.ChatAttributes color = TextComponent.ChatAttributes.WHITE;
RGBColor color;
String[] playerNames;
@Override
@ -57,9 +58,9 @@ public class PacketTeams implements ClientboundPacket {
collisionRule = TeamCollisionRules.byName(buffer.readString());
}
if (buffer.getProtocolId() < 352) {
color = TextComponent.ChatAttributes.byColor(ChatColors.byId(buffer.readByte()));
color = ChatColors.getColorById(buffer.readByte());
} else {
color = TextComponent.ChatAttributes.byColor(ChatColors.byId(buffer.readVarInt()));
color = ChatColors.getColorById(buffer.readVarInt());
}
}
if (buffer.getProtocolId() >= 375) {
@ -112,15 +113,15 @@ public class PacketTeams implements ClientboundPacket {
return action;
}
public TextComponent getDisplayName() {
public BaseComponent getDisplayName() {
return displayName;
}
public TextComponent getPrefix() {
public BaseComponent getPrefix() {
return prefix;
}
public TextComponent getSuffix() {
public BaseComponent getSuffix() {
return suffix;
}
@ -132,7 +133,7 @@ public class PacketTeams implements ClientboundPacket {
return seeFriendlyInvisibles;
}
public TextComponent.ChatAttributes getColor() {
public RGBColor getColor() {
return color;
}

View File

@ -14,8 +14,8 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.MapSet;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.VersionValueMap;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
@ -25,8 +25,8 @@ public class PacketTitle implements ClientboundPacket {
TitleActions action;
//fields depend on action
TextComponent text;
TextComponent subText;
BaseComponent text;
BaseComponent subText;
int fadeInTime;
int stayTime;
int fadeOutTime;
@ -54,8 +54,8 @@ public class PacketTitle implements ClientboundPacket {
@Override
public void log() {
switch (action) {
case SET_TITLE -> Log.protocol(String.format("Received title (action=%s, text=%s)", action, text.getColoredMessage()));
case SET_SUBTITLE -> Log.protocol(String.format("Received title (action=%s, subText=%s)", action, subText.getColoredMessage()));
case SET_TITLE -> Log.protocol(String.format("Received title (action=%s, text=%s)", action, text.getANSIColoredMessage()));
case SET_SUBTITLE -> Log.protocol(String.format("Received title (action=%s, subText=%s)", action, subText.getANSIColoredMessage()));
case SET_TIMES_AND_DISPLAY -> Log.protocol(String.format("Received title (action=%s, fadeInTime=%d, stayTime=%d, fadeOutTime=%d)", action, fadeInTime, stayTime, fadeOutTime));
case HIDE, RESET -> Log.protocol(String.format("Received title (action=%s)", action));
}
@ -73,11 +73,11 @@ public class PacketTitle implements ClientboundPacket {
return stayTime;
}
public TextComponent getSubText() {
public BaseComponent getSubText() {
return subText;
}
public TextComponent getText() {
public BaseComponent getText() {
return text;
}

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.protocol.packets.clientbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
@ -21,7 +21,7 @@ import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
import de.bixilon.minosoft.protocol.protocol.PacketHandler;
public class PacketUpdateSignReceiving implements ClientboundPacket {
final TextComponent[] lines = new TextComponent[4];
final BaseComponent[] lines = new BaseComponent[4];
BlockPosition position;
@Override
@ -51,7 +51,7 @@ public class PacketUpdateSignReceiving implements ClientboundPacket {
return position;
}
public TextComponent[] getLines() {
public BaseComponent[] getLines() {
return lines;
}
}

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.protocol.packets.serverbound.play;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.logging.Log;
import de.bixilon.minosoft.protocol.network.Connection;
@ -23,9 +23,9 @@ import de.bixilon.minosoft.protocol.protocol.Packets;
public class PacketUpdateSignSending implements ServerboundPacket {
final BlockPosition position;
final TextComponent[] lines;
final BaseComponent[] lines;
public PacketUpdateSignSending(BlockPosition position, TextComponent[] lines) {
public PacketUpdateSignSending(BlockPosition position, BaseComponent[] lines) {
this.position = position;
this.lines = lines;
}
@ -40,7 +40,7 @@ public class PacketUpdateSignSending implements ServerboundPacket {
}
if (buffer.getProtocolId() < 21 || buffer.getProtocolId() >= 62) {
for (int i = 0; i < 4; i++) {
buffer.writeString(lines[i].getRawMessage());
buffer.writeString(lines[i].getMessage());
}
} else {
for (int i = 0; i < 4; i++) {

View File

@ -16,7 +16,6 @@ package de.bixilon.minosoft.protocol.protocol;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import de.bixilon.minosoft.game.datatypes.Directions;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.entities.Location;
import de.bixilon.minosoft.game.datatypes.entities.Poses;
import de.bixilon.minosoft.game.datatypes.entities.meta.EntityMetaData;
@ -27,6 +26,7 @@ import de.bixilon.minosoft.game.datatypes.objectLoader.particle.data.DustParticl
import de.bixilon.minosoft.game.datatypes.objectLoader.particle.data.ItemParticleData;
import de.bixilon.minosoft.game.datatypes.objectLoader.particle.data.ParticleData;
import de.bixilon.minosoft.game.datatypes.objectLoader.recipes.Ingredient;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.util.BitByte;
@ -199,8 +199,8 @@ public class InByteBuffer {
return new BlockPosition(x, y, z);
}
public TextComponent readTextComponent() {
return new TextComponent(readString());
public BaseComponent readTextComponent() {
return BaseComponent.fromString(readString());
}
public int getLength() {

View File

@ -14,8 +14,8 @@
package de.bixilon.minosoft.protocol.protocol;
import com.google.gson.JsonObject;
import de.bixilon.minosoft.game.datatypes.TextComponent;
import de.bixilon.minosoft.game.datatypes.inventory.Slot;
import de.bixilon.minosoft.game.datatypes.text.BaseComponent;
import de.bixilon.minosoft.game.datatypes.world.BlockPosition;
import de.bixilon.minosoft.protocol.network.Connection;
import de.bixilon.minosoft.util.nbt.tag.CompoundTag;
@ -74,10 +74,21 @@ public class OutByteBuffer {
}
}
public void writeTextComponent(BaseComponent component) {
writeString(component.getMessage()); //ToDo: test if this should not be json
}
public void writeJSON(JsonObject j) {
writeString(j.toString());
}
public void writeString(String s) {
writeVarInt(s.length());
for (byte b : s.getBytes(StandardCharsets.UTF_8)) {
bytes.add(b);
}
}
public void writeVarLong(long value) {
do
{
@ -124,11 +135,8 @@ public class OutByteBuffer {
writeInt((int) (d * 32.0D));
}
public void writeString(String s) {
writeVarInt(s.length());
for (byte b : s.getBytes(StandardCharsets.UTF_8)) {
bytes.add(b);
}
public void writeVarInt(int value) {
writeVarInt(value, bytes);
}
public ArrayList<Byte> getBytes() {
@ -147,14 +155,6 @@ public class OutByteBuffer {
writeLong((((long) (position.getX() & 0x3FFFFFF) << 38) | ((long) (position.getZ() & 0x3FFFFFF) << 12) | (long) (position.getY() & 0xFFF)));
}
public void writeVarInt(int value) {
writeVarInt(value, bytes);
}
public void writeTextComponent(TextComponent component) {
writeJSON(component.getRaw());
}
public static void writeVarInt(int value, ArrayList<Byte> write) {
// thanks https://wiki.vg/Protocol#VarInt_and_VarLong
do

View File

@ -68,7 +68,7 @@ public class PacketHandler {
} else {
connection.setVersion(version);
}
Log.info(String.format("Status response received: %s/%s online. MotD: '%s'", pkg.getResponse().getPlayerOnline(), pkg.getResponse().getMaxPlayers(), pkg.getResponse().getMotd().getColoredMessage()));
Log.info(String.format("Status response received: %s/%s online. MotD: '%s'", pkg.getResponse().getPlayerOnline(), pkg.getResponse().getMaxPlayers(), pkg.getResponse().getMotd().getANSIColoredMessage()));
connection.handlePingCallbacks(pkg.getResponse());
}
@ -117,7 +117,7 @@ public class PacketHandler {
public void handle(PacketLoginDisconnect pkg) {
connection.fireEvent(new LoginDisconnectEvent(connection, pkg.getReason()));
Log.info(String.format("Disconnecting from server (reason=%s)", pkg.getReason().getColoredMessage()));
Log.info(String.format("Disconnecting from server (reason=%s)", pkg.getReason().getANSIColoredMessage()));
connection.disconnect();
}
@ -370,7 +370,7 @@ public class PacketHandler {
nbt.writeBlockPosition(pkg.getPosition());
nbt.writeTag("id", new StringTag("minecraft:sign"));
for (int i = 0; i < 4; i++) {
nbt.writeTag(String.format("Text%d", (i + 1)), new StringTag(pkg.getLines()[i].getRaw().toString()));
nbt.writeTag(String.format("Text%d", (i + 1)), new StringTag(pkg.getLines()[i].getLegacyText()));
}
}