mirror of
https://github.com/ViaVersion/ViaLegacy.git
synced 2024-12-22 16:38:16 +01:00
Replaced chat component translation with mcstructs
This commit is contained in:
parent
4998dbec16
commit
4d2161d5f1
@ -54,7 +54,10 @@ import net.raphimc.vialegacy.api.remapper.LegacyItemRewriter;
|
||||
import net.raphimc.vialegacy.api.splitter.PreNettySplitter;
|
||||
import net.raphimc.vialegacy.api.util.PacketUtil;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.providers.EncryptionProvider;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.rewriter.*;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.rewriter.ChatComponentRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.rewriter.ItemRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.rewriter.SoundRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.rewriter.StatisticRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.storage.*;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.types.MetaType1_6_4;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.types.Types1_6_4;
|
||||
@ -125,7 +128,7 @@ public class Protocol1_7_2_5to1_6_4 extends StatelessTransitionProtocol<Clientbo
|
||||
this.registerClientbound(ClientboundPackets1_6_4.CHAT_MESSAGE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Types1_6_4.STRING, Type.STRING, msg -> TranslationRewriter.toClient(ChatComponentRewriter.toClient(msg))); // message
|
||||
map(Types1_6_4.STRING, Type.STRING, ChatComponentRewriter::toClient); // message
|
||||
}
|
||||
});
|
||||
this.registerClientbound(ClientboundPackets1_6_4.ENTITY_EQUIPMENT, new PacketHandlers() {
|
||||
|
@ -18,6 +18,8 @@
|
||||
package net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.rewriter;
|
||||
|
||||
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.ATextComponent;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.components.StringComponent;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.components.TranslationComponent;
|
||||
@ -27,27 +29,81 @@ import com.viaversion.viaversion.libs.mcstructs.text.utils.TextUtils;
|
||||
|
||||
public class ChatComponentRewriter {
|
||||
|
||||
private static final Object2ObjectMap<String, String> TRANSLATIONS = new Object2ObjectOpenHashMap<>(37, 0.99F);
|
||||
|
||||
static {
|
||||
TRANSLATIONS.put("menu.playdemo", "Play Demo World");
|
||||
TRANSLATIONS.put("options.ao.off", "Off");
|
||||
TRANSLATIONS.put("options.framerateLimit", "Performance");
|
||||
TRANSLATIONS.put("options.resourcepack", "Resource Packs");
|
||||
TRANSLATIONS.put("performance.max", "Max FPS");
|
||||
TRANSLATIONS.put("performance.balanced", "Balanced");
|
||||
TRANSLATIONS.put("performance.powersaver", "Power saver");
|
||||
TRANSLATIONS.put("key.forward", "Forward");
|
||||
TRANSLATIONS.put("key.left", "Left");
|
||||
TRANSLATIONS.put("key.back", "Back");
|
||||
TRANSLATIONS.put("key.right", "Right");
|
||||
TRANSLATIONS.put("key.drop", "Drop");
|
||||
TRANSLATIONS.put("key.chat", "Chat");
|
||||
TRANSLATIONS.put("key.fog", "Toggle Fog");
|
||||
TRANSLATIONS.put("key.attack", "Attack");
|
||||
TRANSLATIONS.put("key.use", "Use Item");
|
||||
TRANSLATIONS.put("key.command", "Command");
|
||||
TRANSLATIONS.put("resourcePack.title", "Select Resource Pack");
|
||||
TRANSLATIONS.put("tile.dirt.name", "Dirt");
|
||||
TRANSLATIONS.put("tile.sand.name", "Sand");
|
||||
TRANSLATIONS.put("tile.flower.name", "Flower");
|
||||
TRANSLATIONS.put("tile.rose.name", "Rose");
|
||||
TRANSLATIONS.put("item.fishRaw.name", "Raw Fish");
|
||||
TRANSLATIONS.put("item.fishCooked.name", "Cooked Fish");
|
||||
TRANSLATIONS.put("commands.give.usage", "/give <player> <item> [amount] [data]");
|
||||
TRANSLATIONS.put("commands.give.success", "Given %s (ID %s) * %s to %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.objectives.add.wrongType", "Invalid objective criteria type. Valid types are: %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.objectives.list.count", "Showing %s objective(s) on scoreboard");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.list.count", "Showing %s tracked players on the scoreboard");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.list.player.count", "Showing %s tracked objective(s) for %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.list.count", "Showing %s teams on the scoreboard");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.list.player.count", "Showing %s player(s) in team %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.empty.usage", "/scoreboard teams clear <name>");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.option.usage", "/scoreboard teams option <team> <friendlyfire|color> <value>");
|
||||
TRANSLATIONS.put("commands.weather.usage", "/weather <clear/rain/thunder> [duration in seconds]");
|
||||
TRANSLATIONS.put("mco.configure.world.subscription.extend", "Extend");
|
||||
TRANSLATIONS.put("mco.configure.world.restore.question.line1", "Your realm will be restored to a previous version");
|
||||
}
|
||||
|
||||
public static String toClient(final String text) {
|
||||
final ATextComponent component = TextComponentSerializer.V1_6.deserialize(text);
|
||||
ATextComponent component = TextComponentSerializer.V1_6.deserialize(text);
|
||||
// Replace translation keys with their actual translations
|
||||
TextUtils.iterateAll(component, c -> {
|
||||
if (c instanceof TranslationComponent) {
|
||||
final TranslationComponent translationComponent = (TranslationComponent) c;
|
||||
if (TRANSLATIONS.containsKey(translationComponent.getKey())) {
|
||||
translationComponent.setKey(TRANSLATIONS.get(translationComponent.getKey()));
|
||||
}
|
||||
}
|
||||
});
|
||||
// Convert all section sign formatted strings to json formatted ones with styles so the formatting isn't reset on chat line split
|
||||
ATextComponent newComponent = TextUtils.replace(component, ".*", c -> LegacyStringDeserializer.parse(c.asSingleString(), true).setParentStyle(c.getStyle()));
|
||||
component = TextUtils.replace(component, c -> {
|
||||
if (c instanceof StringComponent) {
|
||||
return LegacyStringDeserializer.parse(c.asSingleString(), true).setParentStyle(c.getStyle());
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
});
|
||||
// Clickable URLs are handled clientside -> Add click events to the json components
|
||||
newComponent.forEach(c -> {
|
||||
TextUtils.iterateAll(component, c -> {
|
||||
if (c instanceof TranslationComponent) {
|
||||
final TranslationComponent translationComponent = (TranslationComponent) c;
|
||||
final Object[] args = translationComponent.getArgs();
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
if (args[i] instanceof ATextComponent) {
|
||||
args[i] = TextUtils.makeURLsClickable((ATextComponent) args[i]);
|
||||
} else {
|
||||
args[i] = TextUtils.makeURLsClickable(new StringComponent(args[i].toString()));
|
||||
if (args[i] != null && !(args[i] instanceof ATextComponent)) {
|
||||
args[i] = new StringComponent(args[i].toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
newComponent = TextUtils.makeURLsClickable(newComponent);
|
||||
// Also convert "using" -> "with" in translatable components
|
||||
return TextComponentSerializer.V1_7.serialize(newComponent);
|
||||
component = TextUtils.replace(component, TextUtils::makeURLsClickable);
|
||||
return TextComponentSerializer.V1_7.serialize(component);
|
||||
}
|
||||
|
||||
public static String toClientDisconnect(final String reason) {
|
||||
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaLegacy - https://github.com/RaphiMC/ViaLegacy
|
||||
* Copyright (C) 2020-2024 RK_01/RaphiMC and contributors
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import com.viaversion.viaversion.libs.gson.JsonObject;
|
||||
import com.viaversion.viaversion.rewriter.ComponentRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_2_5to1_6_4.ClientboundPackets1_6_4;
|
||||
|
||||
public class TranslationRewriter {
|
||||
|
||||
private static final Object2ObjectMap<String, String> TRANSLATIONS = new Object2ObjectOpenHashMap<>(37, 0.99F);
|
||||
|
||||
static {
|
||||
TRANSLATIONS.put("menu.playdemo", "Play Demo World");
|
||||
TRANSLATIONS.put("options.ao.off", "Off");
|
||||
TRANSLATIONS.put("options.framerateLimit", "Performance");
|
||||
TRANSLATIONS.put("options.resourcepack", "Resource Packs");
|
||||
TRANSLATIONS.put("performance.max", "Max FPS");
|
||||
TRANSLATIONS.put("performance.balanced", "Balanced");
|
||||
TRANSLATIONS.put("performance.powersaver", "Power saver");
|
||||
TRANSLATIONS.put("key.forward", "Forward");
|
||||
TRANSLATIONS.put("key.left", "Left");
|
||||
TRANSLATIONS.put("key.back", "Back");
|
||||
TRANSLATIONS.put("key.right", "Right");
|
||||
TRANSLATIONS.put("key.drop", "Drop");
|
||||
TRANSLATIONS.put("key.chat", "Chat");
|
||||
TRANSLATIONS.put("key.fog", "Toggle Fog");
|
||||
TRANSLATIONS.put("key.attack", "Attack");
|
||||
TRANSLATIONS.put("key.use", "Use Item");
|
||||
TRANSLATIONS.put("key.command", "Command");
|
||||
TRANSLATIONS.put("resourcePack.title", "Select Resource Pack");
|
||||
TRANSLATIONS.put("tile.dirt.name", "Dirt");
|
||||
TRANSLATIONS.put("tile.sand.name", "Sand");
|
||||
TRANSLATIONS.put("tile.flower.name", "Flower");
|
||||
TRANSLATIONS.put("tile.rose.name", "Rose");
|
||||
TRANSLATIONS.put("item.fishRaw.name", "Raw Fish");
|
||||
TRANSLATIONS.put("item.fishCooked.name", "Cooked Fish");
|
||||
TRANSLATIONS.put("commands.give.usage", "/give <player> <item> [amount] [data]");
|
||||
TRANSLATIONS.put("commands.give.success", "Given %s (ID %s) * %s to %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.objectives.add.wrongType", "Invalid objective criteria type. Valid types are: %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.objectives.list.count", "Showing %s objective(s) on scoreboard");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.list.count", "Showing %s tracked players on the scoreboard");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.list.player.count", "Showing %s tracked objective(s) for %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.list.count", "Showing %s teams on the scoreboard");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.list.player.count", "Showing %s player(s) in team %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.empty.usage", "/scoreboard teams clear <name>");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.option.usage", "/scoreboard teams option <team> <friendlyfire|color> <value>");
|
||||
TRANSLATIONS.put("commands.weather.usage", "/weather <clear/rain/thunder> [duration in seconds]");
|
||||
TRANSLATIONS.put("mco.configure.world.subscription.extend", "Extend");
|
||||
TRANSLATIONS.put("mco.configure.world.restore.question.line1", "Your realm will be restored to a previous version");
|
||||
}
|
||||
|
||||
private static final ComponentRewriter<ClientboundPackets1_6_4> REWRITER = new ComponentRewriter<ClientboundPackets1_6_4>(null, ComponentRewriter.ReadType.JSON) {
|
||||
@Override
|
||||
protected void handleTranslate(JsonObject object, String translate) {
|
||||
final String text = TRANSLATIONS.get(translate);
|
||||
if (text != null) {
|
||||
object.addProperty("translate", text);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static String toClient(final String text) {
|
||||
return REWRITER.processText(text).toString();
|
||||
}
|
||||
|
||||
}
|
@ -32,7 +32,7 @@ import com.viaversion.viaversion.protocols.base.BaseProtocol1_7;
|
||||
import com.viaversion.viaversion.protocols.base.ClientboundLoginPackets;
|
||||
import net.raphimc.vialegacy.ViaLegacy;
|
||||
import net.raphimc.vialegacy.api.util.UuidUtil;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_6_10to1_7_2_5.rewriter.TranslationRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_6_10to1_7_2_5.rewriter.ChatComponentRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.model.GameProfile;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.providers.GameProfileFetcher;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.types.Types1_7_6;
|
||||
@ -79,7 +79,7 @@ public class Protocol1_7_6_10to1_7_2_5 extends AbstractProtocol<ClientboundPacke
|
||||
this.registerClientbound(ClientboundPackets1_7_2.CHAT_MESSAGE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.STRING, Type.STRING, TranslationRewriter::toClient); // message
|
||||
map(Type.STRING, Type.STRING, ChatComponentRewriter::toClient); // message
|
||||
}
|
||||
});
|
||||
this.registerClientbound(ClientboundPackets1_7_2.BLOCK_ENTITY_DATA, new PacketHandlers() {
|
||||
|
@ -19,11 +19,12 @@ package net.raphimc.vialegacy.protocols.release.protocol1_7_6_10to1_7_2_5.rewrit
|
||||
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import com.viaversion.viaversion.libs.gson.JsonObject;
|
||||
import com.viaversion.viaversion.rewriter.ComponentRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_6_10to1_7_2_5.ClientboundPackets1_7_2;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.ATextComponent;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.components.TranslationComponent;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.serializer.TextComponentSerializer;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.utils.TextUtils;
|
||||
|
||||
public class TranslationRewriter {
|
||||
public class ChatComponentRewriter {
|
||||
|
||||
private static final Object2ObjectMap<String, String> TRANSLATIONS = new Object2ObjectOpenHashMap<>(86, 0.99F);
|
||||
|
||||
@ -116,18 +117,18 @@ public class TranslationRewriter {
|
||||
TRANSLATIONS.put("mco.invites.nopending", "No pending invitations!");
|
||||
}
|
||||
|
||||
private static final ComponentRewriter<ClientboundPackets1_7_2> REWRITER = new ComponentRewriter<ClientboundPackets1_7_2>(null, ComponentRewriter.ReadType.JSON) {
|
||||
@Override
|
||||
protected void handleTranslate(JsonObject object, String translate) {
|
||||
final String text = TRANSLATIONS.get(translate);
|
||||
if (text != null) {
|
||||
object.addProperty("translate", text);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static String toClient(final String text) {
|
||||
return REWRITER.processText(text).toString();
|
||||
final ATextComponent component = TextComponentSerializer.V1_7.deserialize(text);
|
||||
// Replace translation keys with their actual translations
|
||||
TextUtils.iterateAll(component, c -> {
|
||||
if (c instanceof TranslationComponent) {
|
||||
final TranslationComponent translationComponent = (TranslationComponent) c;
|
||||
if (TRANSLATIONS.containsKey(translationComponent.getKey())) {
|
||||
translationComponent.setKey(TRANSLATIONS.get(translationComponent.getKey()));
|
||||
}
|
||||
}
|
||||
});
|
||||
return TextComponentSerializer.V1_7.serialize(component);
|
||||
}
|
||||
|
||||
}
|
@ -60,9 +60,8 @@ import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.model.MapDa
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.model.MapIcon;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.model.TabListEntry;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.providers.GameProfileFetcher;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.rewriter.ChatItemRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.rewriter.ChatComponentRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.rewriter.ItemRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.rewriter.TranslationRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.storage.*;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.types.Types1_7_6;
|
||||
|
||||
@ -72,7 +71,7 @@ import java.util.*;
|
||||
public class Protocol1_8to1_7_6_10 extends AbstractProtocol<ClientboundPackets1_7_2, ClientboundPackets1_8, ServerboundPackets1_7_2, ServerboundPackets1_8> {
|
||||
|
||||
private final LegacyItemRewriter<Protocol1_8to1_7_6_10> itemRewriter = new ItemRewriter(this);
|
||||
private final ChatItemRewriter chatItemRewriter = new ChatItemRewriter(this);
|
||||
private final ChatComponentRewriter chatComponentRewriter = new ChatComponentRewriter(this);
|
||||
private final MetadataRewriter metadataRewriter = new MetadataRewriter(this);
|
||||
|
||||
public Protocol1_8to1_7_6_10() {
|
||||
@ -154,7 +153,7 @@ public class Protocol1_8to1_7_6_10 extends AbstractProtocol<ClientboundPackets1_
|
||||
this.registerClientbound(ClientboundPackets1_7_2.CHAT_MESSAGE, new PacketHandlers() {
|
||||
@Override
|
||||
public void register() {
|
||||
map(Type.STRING, Type.STRING, msg -> TranslationRewriter.toClient(chatItemRewriter.remapShowItem(msg))); // message
|
||||
map(Type.STRING, Type.STRING, chatComponentRewriter::toClient); // message
|
||||
create(Type.BYTE, (byte) 0); // position
|
||||
}
|
||||
});
|
||||
|
@ -17,30 +17,94 @@
|
||||
*/
|
||||
package net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.rewriter;
|
||||
|
||||
|
||||
import com.viaversion.viaversion.api.minecraft.item.DataItem;
|
||||
import com.viaversion.viaversion.api.minecraft.item.Item;
|
||||
import com.viaversion.viaversion.api.protocol.Protocol;
|
||||
import com.viaversion.viaversion.libs.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import com.viaversion.viaversion.libs.gson.JsonArray;
|
||||
import com.viaversion.viaversion.libs.gson.JsonElement;
|
||||
import com.viaversion.viaversion.libs.gson.JsonObject;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import com.viaversion.viaversion.libs.mcstructs.snbt.SNbtSerializer;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.ATextComponent;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.components.StringComponent;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.components.TranslationComponent;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.events.hover.HoverEventAction;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.events.hover.impl.TextHoverEvent;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.serializer.TextComponentSerializer;
|
||||
import com.viaversion.viaversion.libs.mcstructs.text.utils.TextUtils;
|
||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
|
||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.ShortTag;
|
||||
import com.viaversion.viaversion.libs.opennbt.tag.builtin.StringTag;
|
||||
import com.viaversion.viaversion.rewriter.ComponentRewriter;
|
||||
import net.raphimc.vialegacy.ViaLegacy;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_6_10to1_7_2_5.ClientboundPackets1_7_2;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.Protocol1_8to1_7_6_10;
|
||||
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class ChatItemRewriter {
|
||||
public class ChatComponentRewriter {
|
||||
|
||||
private static final Object2ObjectMap<String, String> TRANSLATIONS = new Object2ObjectOpenHashMap<>(59, 0.99F);
|
||||
private static final Int2ObjectOpenHashMap<String> ID_TO_NAME = new Int2ObjectOpenHashMap<>(315, 0.99F);
|
||||
|
||||
static {
|
||||
TRANSLATIONS.put("gui.toMenu", "Back to title screen");
|
||||
TRANSLATIONS.put("generator.amplified", "Amplified");
|
||||
TRANSLATIONS.put("disconnect.loginFailedInfo.serversUnavailable", "The authentication are currently down for maintenance.");
|
||||
TRANSLATIONS.put("options.aoDesc0", "Enable faux ambient occlusion on blocks.");
|
||||
TRANSLATIONS.put("options.framerateLimitDesc0", "Selects the maximum frame rate:");
|
||||
TRANSLATIONS.put("options.framerateLimitDesc1", "35fps, 120fps, or 200+fps.");
|
||||
TRANSLATIONS.put("options.viewBobbingDesc0", "Enables view-bob when moving.");
|
||||
TRANSLATIONS.put("options.renderCloudsDesc0", "Enables the rendering of clouds.");
|
||||
TRANSLATIONS.put("options.graphicsDesc0", "'Fancy': Enables extra transparency.");
|
||||
TRANSLATIONS.put("options.graphicsDesc1", "'Fast': Suggested for lower-end hardware.");
|
||||
TRANSLATIONS.put("options.renderDistanceDesc0", "Maximum render distance. Smaller values");
|
||||
TRANSLATIONS.put("options.renderDistanceDesc1", "run better on lower-end hardware.");
|
||||
TRANSLATIONS.put("options.particlesDesc0", "Selects the overall amount of particles.");
|
||||
TRANSLATIONS.put("options.particlesDesc1", "On lower-end hardware, less is better.");
|
||||
TRANSLATIONS.put("options.advancedOpenglDesc0", "Enables occlusion queries. On AMD and Intel");
|
||||
TRANSLATIONS.put("options.advancedOpenglDesc1", "hardware, this may decrease performance.");
|
||||
TRANSLATIONS.put("options.fboEnableDesc0", "Enables the use of Framebuffer Objects.");
|
||||
TRANSLATIONS.put("options.fboEnableDesc1", "Necessary for certain Minecraft features.");
|
||||
TRANSLATIONS.put("options.postProcessEnableDesc0", "Enables post-processing. Disabling will");
|
||||
TRANSLATIONS.put("options.postProcessEnableDesc1", "result in reduction in Awesome Levels.");
|
||||
TRANSLATIONS.put("options.showCape", "Show Cape");
|
||||
TRANSLATIONS.put("options.anisotropicFiltering", "Anisotropic Filtering");
|
||||
TRANSLATIONS.put("tile.stone.name", "Stone");
|
||||
TRANSLATIONS.put("tile.sapling.roofed_oak.name", "Dark Oak Sapling");
|
||||
TRANSLATIONS.put("tile.sponge.name", "Sponge");
|
||||
TRANSLATIONS.put("tile.stairsStone.name", "Stone Stairs");
|
||||
TRANSLATIONS.put("tile.pressurePlate.name", "Pressure Plate");
|
||||
TRANSLATIONS.put("tile.fence.name", "Fence");
|
||||
TRANSLATIONS.put("tile.fenceGate.name", "Fence Gate");
|
||||
TRANSLATIONS.put("tile.trapdoor.name", "Trapdoor");
|
||||
TRANSLATIONS.put("item.doorWood.name", "Wooden Door");
|
||||
TRANSLATIONS.put("entity.Arrow.name", "arrow");
|
||||
TRANSLATIONS.put("achievement.overkill.desc", "Deal eight hearts of damage in a single hit");
|
||||
TRANSLATIONS.put("commands.generic.deprecatedId", "Warning: Using numeric IDs will not be supported in the future. Please use names, such as '%s'");
|
||||
TRANSLATIONS.put("commands.give.notFound", "There is no such item with ID %s");
|
||||
TRANSLATIONS.put("commands.effect.usage", "/effect <player> <effect> [seconds] [amplifier]");
|
||||
TRANSLATIONS.put("commands.clear.usage", "/clear <player> [item] [data]");
|
||||
TRANSLATIONS.put("commands.time.usage", "/time <set|add> <value>");
|
||||
TRANSLATIONS.put("commands.kill.usage", "/kill");
|
||||
TRANSLATIONS.put("commands.kill.success", "Ouch! That looked like it hurt");
|
||||
TRANSLATIONS.put("commands.tp.success.coordinates", "Teleported %s to %s,%s,%s");
|
||||
TRANSLATIONS.put("commands.tp.usage", "/tp [target player] <destination player> OR /tp [target player] <x> <y> <z>");
|
||||
TRANSLATIONS.put("commands.scoreboard.usage", "/scoreboard <objectives|players|teams>");
|
||||
TRANSLATIONS.put("commands.scoreboard.objectives.usage", "/scoreboard objectives <list|add|remove|setdisplay>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.usage", "/scoreboard players <set|add|remove|reset|list>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.set.usage", "/scoreboard players set <player> <objective> <score>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.add.usage", "/scoreboard players add <player> <objective> <count>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.remove.usage", "/scoreboard players remove <player> <objective> <count>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.reset.usage", "/scoreboard players reset <player>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.reset.success", "Reset all scores of player %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.usage", "/scoreboard teams <list|add|remove|empty|join|leave|option>");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.empty.usage", "/scoreboard teams empty");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.option.usage", "/scoreboard teams option <team> <friendlyfire|color|seeFriendlyInvisibles> <value>");
|
||||
TRANSLATIONS.put("commands.spawnpoint.usage", "/spawnpoint OR /spawnpoint <player> OR /spawnpoint <player> <x> <y> <z>");
|
||||
TRANSLATIONS.put("commands.setworldspawn.usage", "/setworldspawn OR /setworldspawn <x> <y> <z>");
|
||||
TRANSLATIONS.put("commands.gamerule.usage", "/gamerule <rule name> <value> OR /gamerule <rule name>");
|
||||
TRANSLATIONS.put("commands.testfor.usage", "/testfor <player>");
|
||||
TRANSLATIONS.put("commands.testfor.failed", "/testfor is only usable by commandblocks with analog output");
|
||||
TRANSLATIONS.put("commands.achievement.usage", "/achievement give <stat_name> [player]");
|
||||
|
||||
ID_TO_NAME.put(1, "stone");
|
||||
ID_TO_NAME.put(2, "grass");
|
||||
ID_TO_NAME.put(3, "dirt");
|
||||
@ -358,64 +422,61 @@ public class ChatItemRewriter {
|
||||
ID_TO_NAME.put(2267, "record_wait");
|
||||
}
|
||||
|
||||
private final ComponentRewriter<ClientboundPackets1_7_2> SHOW_ITEM;
|
||||
private final Protocol<?, ?, ?, ?> protocol;
|
||||
|
||||
public ChatItemRewriter(final Protocol1_8to1_7_6_10 protocol) {
|
||||
this.SHOW_ITEM = new ComponentRewriter<ClientboundPackets1_7_2>(protocol, ComponentRewriter.ReadType.JSON) {
|
||||
@Override
|
||||
protected void handleHoverEvent(JsonObject hoverEvent) {
|
||||
super.handleHoverEvent(hoverEvent);
|
||||
final String action = hoverEvent.getAsJsonPrimitive("action").getAsString();
|
||||
if (!action.equals("show_item")) return;
|
||||
|
||||
final JsonElement value = hoverEvent.get("value");
|
||||
if (value == null) return;
|
||||
|
||||
final ATextComponent nbt = TextComponentSerializer.V1_7.deserialize(value);
|
||||
|
||||
try {
|
||||
final CompoundTag tag = (CompoundTag) SNbtSerializer.V1_7.deserialize(nbt.asUnformattedString());
|
||||
final CompoundTag itemTag = tag.get("tag");
|
||||
final ShortTag idTag = tag.get("id");
|
||||
final ShortTag damageTag = tag.get("Damage");
|
||||
|
||||
// Call item converter
|
||||
final short damage = damageTag != null ? damageTag.asShort() : 0;
|
||||
final short id = idTag != null ? idTag.asShort() : 1;
|
||||
final Item item = new DataItem();
|
||||
item.setIdentifier(id);
|
||||
item.setData(damage);
|
||||
item.setTag(itemTag);
|
||||
this.handleItem(item);
|
||||
|
||||
// Serialize again
|
||||
if (damage != item.data()) {
|
||||
tag.put("Damage", new ShortTag(item.data()));
|
||||
}
|
||||
tag.put("id", new StringTag("minecraft:" + ID_TO_NAME.getOrDefault(item.identifier(), "stone")));
|
||||
if (item.tag() != null) {
|
||||
tag.put("tag", new CompoundTag(item.tag().getValue()));
|
||||
}
|
||||
|
||||
final JsonArray array = new JsonArray();
|
||||
final JsonObject object = new JsonObject();
|
||||
array.add(object);
|
||||
final String serializedNBT = SNbtSerializer.V1_8.serialize(tag);
|
||||
object.addProperty("text", serializedNBT);
|
||||
hoverEvent.add("value", array);
|
||||
} catch (Throwable e) {
|
||||
ViaLegacy.getPlatform().getLogger().log(Level.WARNING, "Error remapping NBT in show_item:" + nbt.asUnformattedString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleItem(Item item) {
|
||||
this.protocol.getItemRewriter().handleItemToClient(item);
|
||||
}
|
||||
};
|
||||
public ChatComponentRewriter(final Protocol<?, ?, ?, ?> protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
public String remapShowItem(final String text) {
|
||||
return SHOW_ITEM.processText(text).toString();
|
||||
public String toClient(final String text) {
|
||||
final ATextComponent component = TextComponentSerializer.V1_7.deserialize(text);
|
||||
// Replace translation keys with their actual translations
|
||||
TextUtils.iterateAll(component, c -> {
|
||||
if (c instanceof TranslationComponent) {
|
||||
final TranslationComponent translationComponent = (TranslationComponent) c;
|
||||
if (TRANSLATIONS.containsKey(translationComponent.getKey())) {
|
||||
translationComponent.setKey(TRANSLATIONS.get(translationComponent.getKey()));
|
||||
}
|
||||
}
|
||||
});
|
||||
// Translate item hover events
|
||||
TextUtils.iterateAll(component, c -> {
|
||||
if (c.getStyle().getHoverEvent() instanceof TextHoverEvent) {
|
||||
final TextHoverEvent textHoverEvent = (TextHoverEvent) c.getStyle().getHoverEvent();
|
||||
if (textHoverEvent.getAction().equals(HoverEventAction.SHOW_ITEM)) {
|
||||
try {
|
||||
final CompoundTag tag = (CompoundTag) SNbtSerializer.V1_7.deserialize(textHoverEvent.getText().asUnformattedString());
|
||||
final ShortTag idTag = tag.get("id");
|
||||
final ShortTag damageTag = tag.get("Damage");
|
||||
final CompoundTag itemTag = tag.get("tag");
|
||||
|
||||
final short damage = damageTag != null ? damageTag.asShort() : 0;
|
||||
Item item = new DataItem();
|
||||
item.setIdentifier(idTag.asShort());
|
||||
item.setData(damage);
|
||||
item.setTag(itemTag);
|
||||
item = this.protocol.getItemRewriter().handleItemToClient(item);
|
||||
|
||||
if (!ID_TO_NAME.containsKey(item.identifier())) {
|
||||
throw new IllegalArgumentException("Invalid item ID: " + item.identifier());
|
||||
}
|
||||
tag.put("id", new StringTag("minecraft:" + ID_TO_NAME.get(item.identifier())));
|
||||
if (damage != item.data()) {
|
||||
tag.put("Damage", new ShortTag(item.data()));
|
||||
}
|
||||
if (item.tag() != itemTag) {
|
||||
tag.put("tag", item.tag());
|
||||
}
|
||||
|
||||
c.getStyle().setHoverEvent(new TextHoverEvent(textHoverEvent.getAction(), new StringComponent(SNbtSerializer.V1_8.serialize(tag))));
|
||||
} catch (Throwable e) {
|
||||
ViaLegacy.getPlatform().getLogger().log(Level.WARNING, "Error remapping NBT in show_item:" + textHoverEvent.getText().asUnformattedString(), e);
|
||||
c.getStyle().setHoverEvent(new TextHoverEvent(textHoverEvent.getAction(), new StringComponent())); // Invalid item
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return TextComponentSerializer.V1_8.serialize(component);
|
||||
}
|
||||
|
||||
}
|
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* This file is part of ViaLegacy - https://github.com/RaphiMC/ViaLegacy
|
||||
* Copyright (C) 2020-2024 RK_01/RaphiMC and contributors
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package net.raphimc.vialegacy.protocols.release.protocol1_8to1_7_6_10.rewriter;
|
||||
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectMap;
|
||||
import com.viaversion.viaversion.libs.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import com.viaversion.viaversion.libs.gson.JsonObject;
|
||||
import com.viaversion.viaversion.rewriter.ComponentRewriter;
|
||||
import net.raphimc.vialegacy.protocols.release.protocol1_7_6_10to1_7_2_5.ClientboundPackets1_7_2;
|
||||
|
||||
public class TranslationRewriter {
|
||||
|
||||
private static final Object2ObjectMap<String, String> TRANSLATIONS = new Object2ObjectOpenHashMap<>(59, 0.99F);
|
||||
|
||||
static {
|
||||
TRANSLATIONS.put("gui.toMenu", "Back to title screen");
|
||||
TRANSLATIONS.put("generator.amplified", "Amplified");
|
||||
TRANSLATIONS.put("disconnect.loginFailedInfo.serversUnavailable", "The authentication are currently down for maintenance.");
|
||||
TRANSLATIONS.put("options.aoDesc0", "Enable faux ambient occlusion on blocks.");
|
||||
TRANSLATIONS.put("options.framerateLimitDesc0", "Selects the maximum frame rate:");
|
||||
TRANSLATIONS.put("options.framerateLimitDesc1", "35fps, 120fps, or 200+fps.");
|
||||
TRANSLATIONS.put("options.viewBobbingDesc0", "Enables view-bob when moving.");
|
||||
TRANSLATIONS.put("options.renderCloudsDesc0", "Enables the rendering of clouds.");
|
||||
TRANSLATIONS.put("options.graphicsDesc0", "'Fancy': Enables extra transparency.");
|
||||
TRANSLATIONS.put("options.graphicsDesc1", "'Fast': Suggested for lower-end hardware.");
|
||||
TRANSLATIONS.put("options.renderDistanceDesc0", "Maximum render distance. Smaller values");
|
||||
TRANSLATIONS.put("options.renderDistanceDesc1", "run better on lower-end hardware.");
|
||||
TRANSLATIONS.put("options.particlesDesc0", "Selects the overall amount of particles.");
|
||||
TRANSLATIONS.put("options.particlesDesc1", "On lower-end hardware, less is better.");
|
||||
TRANSLATIONS.put("options.advancedOpenglDesc0", "Enables occlusion queries. On AMD and Intel");
|
||||
TRANSLATIONS.put("options.advancedOpenglDesc1", "hardware, this may decrease performance.");
|
||||
TRANSLATIONS.put("options.fboEnableDesc0", "Enables the use of Framebuffer Objects.");
|
||||
TRANSLATIONS.put("options.fboEnableDesc1", "Necessary for certain Minecraft features.");
|
||||
TRANSLATIONS.put("options.postProcessEnableDesc0", "Enables post-processing. Disabling will");
|
||||
TRANSLATIONS.put("options.postProcessEnableDesc1", "result in reduction in Awesome Levels.");
|
||||
TRANSLATIONS.put("options.showCape", "Show Cape");
|
||||
TRANSLATIONS.put("options.anisotropicFiltering", "Anisotropic Filtering");
|
||||
TRANSLATIONS.put("tile.stone.name", "Stone");
|
||||
TRANSLATIONS.put("tile.sapling.roofed_oak.name", "Dark Oak Sapling");
|
||||
TRANSLATIONS.put("tile.sponge.name", "Sponge");
|
||||
TRANSLATIONS.put("tile.stairsStone.name", "Stone Stairs");
|
||||
TRANSLATIONS.put("tile.pressurePlate.name", "Pressure Plate");
|
||||
TRANSLATIONS.put("tile.fence.name", "Fence");
|
||||
TRANSLATIONS.put("tile.fenceGate.name", "Fence Gate");
|
||||
TRANSLATIONS.put("tile.trapdoor.name", "Trapdoor");
|
||||
TRANSLATIONS.put("item.doorWood.name", "Wooden Door");
|
||||
TRANSLATIONS.put("entity.Arrow.name", "arrow");
|
||||
TRANSLATIONS.put("achievement.overkill.desc", "Deal eight hearts of damage in a single hit");
|
||||
TRANSLATIONS.put("commands.generic.deprecatedId", "Warning: Using numeric IDs will not be supported in the future. Please use names, such as '%s'");
|
||||
TRANSLATIONS.put("commands.give.notFound", "There is no such item with ID %s");
|
||||
TRANSLATIONS.put("commands.effect.usage", "/effect <player> <effect> [seconds] [amplifier]");
|
||||
TRANSLATIONS.put("commands.clear.usage", "/clear <player> [item] [data]");
|
||||
TRANSLATIONS.put("commands.time.usage", "/time <set|add> <value>");
|
||||
TRANSLATIONS.put("commands.kill.usage", "/kill");
|
||||
TRANSLATIONS.put("commands.kill.success", "Ouch! That looked like it hurt");
|
||||
TRANSLATIONS.put("commands.tp.success.coordinates", "Teleported %s to %s,%s,%s");
|
||||
TRANSLATIONS.put("commands.tp.usage", "/tp [target player] <destination player> OR /tp [target player] <x> <y> <z>");
|
||||
TRANSLATIONS.put("commands.scoreboard.usage", "/scoreboard <objectives|players|teams>");
|
||||
TRANSLATIONS.put("commands.scoreboard.objectives.usage", "/scoreboard objectives <list|add|remove|setdisplay>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.usage", "/scoreboard players <set|add|remove|reset|list>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.set.usage", "/scoreboard players set <player> <objective> <score>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.add.usage", "/scoreboard players add <player> <objective> <count>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.remove.usage", "/scoreboard players remove <player> <objective> <count>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.reset.usage", "/scoreboard players reset <player>");
|
||||
TRANSLATIONS.put("commands.scoreboard.players.reset.success", "Reset all scores of player %s");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.usage", "/scoreboard teams <list|add|remove|empty|join|leave|option>");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.empty.usage", "/scoreboard teams empty");
|
||||
TRANSLATIONS.put("commands.scoreboard.teams.option.usage", "/scoreboard teams option <team> <friendlyfire|color|seeFriendlyInvisibles> <value>");
|
||||
TRANSLATIONS.put("commands.spawnpoint.usage", "/spawnpoint OR /spawnpoint <player> OR /spawnpoint <player> <x> <y> <z>");
|
||||
TRANSLATIONS.put("commands.setworldspawn.usage", "/setworldspawn OR /setworldspawn <x> <y> <z>");
|
||||
TRANSLATIONS.put("commands.gamerule.usage", "/gamerule <rule name> <value> OR /gamerule <rule name>");
|
||||
TRANSLATIONS.put("commands.testfor.usage", "/testfor <player>");
|
||||
TRANSLATIONS.put("commands.testfor.failed", "/testfor is only usable by commandblocks with analog output");
|
||||
TRANSLATIONS.put("commands.achievement.usage", "/achievement give <stat_name> [player]");
|
||||
}
|
||||
|
||||
private static final ComponentRewriter<ClientboundPackets1_7_2> REWRITER = new ComponentRewriter<ClientboundPackets1_7_2>(null, ComponentRewriter.ReadType.JSON) {
|
||||
@Override
|
||||
protected void handleTranslate(JsonObject object, String translate) {
|
||||
final String text = TRANSLATIONS.get(translate);
|
||||
if (text != null) {
|
||||
object.addProperty("translate", text);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static String toClient(final String text) {
|
||||
return REWRITER.processText(text).toString();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user