fix some bugs in TranslatableComponent (allow parent mapping), other fixes and improvements

This commit is contained in:
Bixilon 2020-11-22 18:53:48 +01:00
parent 44605c1fe3
commit ac87d42c48
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
10 changed files with 90 additions and 35 deletions

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.data.assets; package de.bixilon.minosoft.data.assets;
import com.google.common.base.StandardSystemProperty;
import com.google.errorprone.annotations.DoNotCall; import com.google.errorprone.annotations.DoNotCall;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -254,7 +255,7 @@ public class AssetsManager {
private static String saveAsset(InputStream data) throws IOException { private static String saveAsset(InputStream data) throws IOException {
File tempDestinationFile = null; File tempDestinationFile = null;
while (tempDestinationFile == null || tempDestinationFile.exists()) { // file exist? lol while (tempDestinationFile == null || tempDestinationFile.exists()) { // file exist? lol
tempDestinationFile = new File(System.getProperty("java.io.tmpdir") + "/minosoft/" + Util.generateRandomString(32)); tempDestinationFile = new File(System.getProperty(StandardSystemProperty.JAVA_IO_TMPDIR.value()) + "/minosoft/" + Util.generateRandomString(32));
} }
Util.createParentFolderIfNotExist(tempDestinationFile); Util.createParentFolderIfNotExist(tempDestinationFile);

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.data.entities.block; package de.bixilon.minosoft.data.entities.block;
import de.bixilon.minosoft.data.text.ChatColors;
import de.bixilon.minosoft.data.text.RGBColor; import de.bixilon.minosoft.data.text.RGBColor;
import de.bixilon.minosoft.util.nbt.tag.IntTag; import de.bixilon.minosoft.util.nbt.tag.IntTag;
import de.bixilon.minosoft.util.nbt.tag.NBTTag; import de.bixilon.minosoft.util.nbt.tag.NBTTag;
@ -26,6 +27,10 @@ public class BedEntityMetaData extends BlockEntityMetaData {
} }
public BedEntityMetaData(NBTTag nbt) { public BedEntityMetaData(NBTTag nbt) {
if (nbt == null) {
color = ChatColors.RED;
return;
}
if (nbt instanceof StringTag stringTag) { if (nbt instanceof StringTag stringTag) {
// yes, we support bed rgb colors :D // yes, we support bed rgb colors :D
color = new RGBColor(stringTag.getValue()); color = new RGBColor(stringTag.getValue());

View File

@ -212,11 +212,9 @@ public abstract class Entity {
@EntityMetaDataFunction(identifier = "pose") @EntityMetaDataFunction(identifier = "pose")
public Poses getPose() { public Poses getPose() {
if (isCrouching()) { if (isCrouching()) {
// crouching
return Poses.SNEAKING; return Poses.SNEAKING;
} }
if (isSwimming()) { if (isSwimming()) {
// crouching
return Poses.SWIMMING; return Poses.SWIMMING;
} }
if (isFlyingWithElytra()) { if (isFlyingWithElytra()) {

View File

@ -16,6 +16,7 @@ package de.bixilon.minosoft.data.text;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import de.bixilon.minosoft.modding.event.events.annotations.Unsafe; import de.bixilon.minosoft.modding.event.events.annotations.Unsafe;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import de.bixilon.minosoft.util.hash.BetterHashSet; import de.bixilon.minosoft.util.hash.BetterHashSet;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.Node; import javafx.scene.Node;
@ -40,7 +41,7 @@ public class BaseComponent extends ChatComponent {
while (iterator.current() != CharacterIterator.DONE) { while (iterator.current() != CharacterIterator.DONE) {
char c = iterator.current(); char c = iterator.current();
iterator.next(); iterator.next();
if (c != '§') { if (c != ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR) {
currentText.append(c); currentText.append(c);
continue; continue;
} }
@ -92,7 +93,7 @@ public class BaseComponent extends ChatComponent {
TextComponent thisTextComponent = null; TextComponent thisTextComponent = null;
if (json.has("text")) { if (json.has("text")) {
String text = json.get("text").getAsString(); String text = json.get("text").getAsString();
if (text.contains("§")) { if (text.contains(String.valueOf(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR))) {
// legacy text component // legacy text component
parts.add(new BaseComponent(text)); parts.add(new BaseComponent(text));
return; return;
@ -140,20 +141,20 @@ public class BaseComponent extends ChatComponent {
parts.add(thisTextComponent); parts.add(thisTextComponent);
} }
final TextComponent parentParameter = thisTextComponent == null ? parent : thisTextComponent;
if (json.has("extra")) { if (json.has("extra")) {
JsonArray extras = json.getAsJsonArray("extra"); JsonArray extras = json.getAsJsonArray("extra");
TextComponent finalThisChatPart = thisTextComponent; extras.forEach((extra -> parts.add(new BaseComponent(parentParameter, extra.getAsJsonObject()))));
extras.forEach((extra -> parts.add(new BaseComponent(finalThisChatPart, extra.getAsJsonObject()))));
} }
if (json.has("translate")) { if (json.has("translate")) {
parts.add(new TranslatableComponent(json.get("translate").getAsString(), json.getAsJsonArray("with"))); parts.add(new TranslatableComponent(parentParameter, json.get("translate").getAsString(), json.getAsJsonArray("with")));
} }
} }
@Override @Override
public String toString() { public String toString() {
return getANSIColoredMessage(); return PostChatFormattingCodes.RESET.getANSI() + getANSIColoredMessage();
} }
public String getANSIColoredMessage() { public String getANSIColoredMessage() {

View File

@ -83,6 +83,10 @@ public final class ChatColors {
return colorIntMap.get(color); return colorIntMap.get(color);
} }
public static String getColorChar(RGBColor color) {
return String.format("%x", colorIntMap.get(color));
}
public static RGBColor getColorByName(String name) { public static RGBColor getColorByName(String name) {
return switch (name.toLowerCase()) { return switch (name.toLowerCase()) {
case "black" -> BLACK; case "black" -> BLACK;
@ -100,7 +104,7 @@ public final class ChatColors {
case "red" -> RED; case "red" -> RED;
case "light_purple" -> LIGHT_PURPLE; case "light_purple" -> LIGHT_PURPLE;
case "yellow" -> YELLOW; case "yellow" -> YELLOW;
case "white" -> WHITE; case "white", "reset" -> WHITE;
default -> throw new IllegalStateException("Unexpected value: " + name); default -> throw new IllegalStateException("Unexpected value: " + name);
}; };
} }

View File

@ -19,13 +19,19 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.Node; import javafx.scene.Node;
import javax.annotation.Nullable;
public abstract class ChatComponent { public abstract class ChatComponent {
public static ChatComponent fromString(String raw) { public static ChatComponent fromString(String raw) {
return fromString(null, raw);
}
public static ChatComponent fromString(@Nullable TextComponent parent, String raw) {
if (raw == null) { if (raw == null) {
return new BaseComponent(); return new BaseComponent();
} }
try { try {
return new BaseComponent(JsonParser.parseString(raw).getAsJsonObject()); return new BaseComponent(parent, JsonParser.parseString(raw).getAsJsonObject());
} catch (JsonParseException | IllegalStateException ignored) { } catch (JsonParseException | IllegalStateException ignored) {
} }
return new BaseComponent(raw); return new BaseComponent(raw);

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.data.text; package de.bixilon.minosoft.data.text;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import de.bixilon.minosoft.util.hash.BetterHashSet; import de.bixilon.minosoft.util.hash.BetterHashSet;
import javafx.animation.Animation; import javafx.animation.Animation;
import javafx.animation.KeyFrame; import javafx.animation.KeyFrame;
@ -140,11 +141,11 @@ public class TextComponent extends ChatComponent {
StringBuilder output = new StringBuilder(); StringBuilder output = new StringBuilder();
Integer colorChar = ChatColors.getColorId(color); Integer colorChar = ChatColors.getColorId(color);
if (colorChar != null) { if (colorChar != null) {
output.append('§').append(Integer.toHexString(colorChar)); output.append(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR).append(Integer.toHexString(colorChar));
} }
formatting.forEach((chatFormattingCode -> output.append('§').append(chatFormattingCode.getChar()))); formatting.forEach((chatFormattingCode -> output.append(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR).append(chatFormattingCode.getChar())));
output.append(text); output.append(text);
output.append('§').append(PostChatFormattingCodes.RESET.getChar()); output.append(ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR).append(PostChatFormattingCodes.RESET.getChar());
return output.toString(); return output.toString();
} }

View File

@ -15,54 +15,50 @@ package de.bixilon.minosoft.data.text;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import de.bixilon.minosoft.data.locale.minecraft.MinecraftLocaleManager; import de.bixilon.minosoft.data.locale.minecraft.MinecraftLocaleManager;
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.scene.Node; import javafx.scene.Node;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
public class TranslatableComponent extends ChatComponent { public class TranslatableComponent extends ChatComponent {
private final ArrayList<ChatComponent> data = new ArrayList<>(); private final ArrayList<ChatComponent> data = new ArrayList<>();
private final String key; private final String key;
private final TextComponent parent;
public TranslatableComponent(String key, JsonArray data) { public TranslatableComponent(String key, JsonArray data) {
this(null, key, data);
}
public TranslatableComponent(@Nullable TextComponent parent, String key, JsonArray data) {
this.parent = parent;
this.key = key; this.key = key;
if (data == null) { if (data == null) {
return; return;
} }
data.forEach((jsonElement -> { data.forEach((jsonElement -> {
if (jsonElement.isJsonPrimitive()) { if (jsonElement.isJsonPrimitive()) {
this.data.add(ChatComponent.fromString(jsonElement.getAsString())); this.data.add(ChatComponent.fromString(parent, jsonElement.getAsString()));
} else { } else {
this.data.add(new BaseComponent(jsonElement.getAsJsonObject())); this.data.add(new BaseComponent(parent, jsonElement.getAsJsonObject()));
} }
})); }));
} }
@Override @Override
public String getANSIColoredMessage() { public String getANSIColoredMessage() {
Object[] data = new String[this.data.size()]; return getList("getANSIColoredMessage");
for (int i = 0; i < this.data.size(); i++) {
data[i] = this.data.get(i).getANSIColoredMessage();
}
return MinecraftLocaleManager.translate(key, data);
} }
@Override @Override
public String getLegacyText() { public String getLegacyText() {
Object[] data = new String[this.data.size()]; return getList("getLegacyText");
for (int i = 0; i < this.data.size(); i++) {
data[i] = this.data.get(i).getLegacyText();
}
return MinecraftLocaleManager.translate(key, data);
} }
@Override @Override
public String getMessage() { public String getMessage() {
Object[] data = new String[this.data.size()]; return getList("getMessage");
for (int i = 0; i < this.data.size(); i++) {
data[i] = this.data.get(i).getMessage();
}
return MinecraftLocaleManager.translate(key, data);
} }
@Override @Override
@ -72,4 +68,46 @@ public class TranslatableComponent extends ChatComponent {
// This is just a dirty workaround to enable formatting and coloring. Still need to do hover, click, ... stuff // This is just a dirty workaround to enable formatting and coloring. Still need to do hover, click, ... stuff
return new BaseComponent(getLegacyText()).getJavaFXText(nodes); return new BaseComponent(getLegacyText()).getJavaFXText(nodes);
} }
// just used reflections to not write this twice anc only change the method name
private String getList(String methodName) {
try {
Object[] data = new String[this.data.size()];
for (int i = 0; i < this.data.size(); i++) {
data[i] = this.data.get(i).getClass().getMethod(methodName).invoke(this.data.get(i));
}
if (parent != null) {
StringBuilder builder = new StringBuilder();
if (methodName.equals("getANSIColoredMessage")) {
builder.append(ChatColors.getANSIColorByRGBColor(parent.getColor()));
} else if (methodName.equals("getLegacyText")) {
builder.append(ChatColors.getColorChar(parent.getColor()));
}
for (ChatFormattingCode code : parent.getFormatting()) {
if (code instanceof PreChatFormattingCodes preCode) {
builder.append(switch (methodName) {
case "getANSIColoredMessage" -> preCode.getANSI();
case "getLegacyText" -> ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR + preCode.getChar();
default -> "";
});
}
}
builder.append(MinecraftLocaleManager.translate(key, data));
for (ChatFormattingCode code : parent.getFormatting()) {
if (code instanceof PostChatFormattingCodes postCode) {
builder.append(switch (methodName) {
case "getANSIColoredMessage" -> postCode.getANSI();
case "getLegacyText" -> ProtocolDefinition.TEXT_COMPONENT_SPECIAL_PREFIX_CHAR + postCode.getChar();
default -> "";
});
}
}
return builder.toString();
}
return MinecraftLocaleManager.translate(key, data);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} }

View File

@ -276,15 +276,15 @@ public class PacketHandler {
} }
Log.game(switch (pkg.getReason()) { Log.game(switch (pkg.getReason()) {
case STOP_RAINING -> "Received weather packet: Starting rain..."; case START_RAINING -> "Received weather packet: Starting rain...";
case START_RAINING -> "Received weather packet: Stopping rain..."; case STOP_RAINING -> "Received weather packet: Stopping rain...";
case CHANGE_GAMEMODE -> String.format("Received game mode change: Now in %s", GameModes.byId(pkg.getValue().intValue())); case CHANGE_GAMEMODE -> String.format("Received game mode change: Now in %s", GameModes.byId(pkg.getValue().intValue()));
default -> ""; default -> "";
}); });
switch (pkg.getReason()) { switch (pkg.getReason()) {
case STOP_RAINING -> connection.getPlayer().getWorld().setRaining(true); case STOP_RAINING -> connection.getPlayer().getWorld().setRaining(false);
case START_RAINING -> connection.getPlayer().getWorld().setRaining(false); case START_RAINING -> connection.getPlayer().getWorld().setRaining(true);
case CHANGE_GAMEMODE -> connection.getPlayer().setGameMode(GameModes.byId(pkg.getValue().intValue())); case CHANGE_GAMEMODE -> connection.getPlayer().setGameMode(GameModes.byId(pkg.getValue().intValue()));
} }
} }

View File

@ -36,6 +36,7 @@ public final class ProtocolDefinition {
public static final int LAN_SERVER_MAXIMUM_SERVERS = 100; // maximum number of lan servers, set because otherwise dos attacks would be easy public static final int LAN_SERVER_MAXIMUM_SERVERS = 100; // maximum number of lan servers, set because otherwise dos attacks would be easy
public static final String DEFAULT_MOD = "minecraft"; public static final String DEFAULT_MOD = "minecraft";
public static final char TEXT_COMPONENT_SPECIAL_PREFIX_CHAR = '§';
public static final int DEFAULT_BUFFER_SIZE = 4096; public static final int DEFAULT_BUFFER_SIZE = 4096;