2021-03-22 23:06:40 +01:00
|
|
|
/*
|
|
|
|
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
|
2023-01-12 12:45:53 +01:00
|
|
|
* Copyright (C) 2016-2023 ViaVersion and contributors
|
2021-03-22 23:06:40 +01:00
|
|
|
*
|
|
|
|
* 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/>.
|
|
|
|
*/
|
2021-04-26 21:16:10 +02:00
|
|
|
package com.viaversion.viaversion.rewriter;
|
2020-06-25 16:22:53 +02:00
|
|
|
|
|
|
|
import com.google.gson.JsonElement;
|
|
|
|
import com.google.gson.JsonObject;
|
2021-04-16 23:05:31 +02:00
|
|
|
import com.google.gson.JsonParser;
|
2020-06-25 16:22:53 +02:00
|
|
|
import com.google.gson.JsonPrimitive;
|
2020-07-28 09:59:35 +02:00
|
|
|
import com.google.gson.JsonSyntaxException;
|
2021-04-26 20:52:34 +02:00
|
|
|
import com.viaversion.viaversion.api.Via;
|
|
|
|
import com.viaversion.viaversion.api.protocol.Protocol;
|
2021-04-27 13:41:39 +02:00
|
|
|
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
|
2023-02-12 10:54:47 +01:00
|
|
|
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
|
2021-04-26 20:52:34 +02:00
|
|
|
import com.viaversion.viaversion.api.type.Type;
|
2020-06-25 16:22:53 +02:00
|
|
|
|
2020-06-27 23:41:46 +02:00
|
|
|
/**
|
|
|
|
* Handles json chat components, containing methods to override certain parts of the handling.
|
|
|
|
* Also contains methods to register a few of the packets using components.
|
|
|
|
*/
|
2023-02-04 18:29:22 +01:00
|
|
|
public class ComponentRewriter<C extends ClientboundPacketType> {
|
|
|
|
protected final Protocol<C, ?, ?, ?> protocol;
|
2020-06-27 23:41:46 +02:00
|
|
|
|
2023-02-04 18:29:22 +01:00
|
|
|
public ComponentRewriter(Protocol<C, ?, ?, ?> protocol) {
|
2020-06-27 23:41:46 +02:00
|
|
|
this.protocol = protocol;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Use empty constructor if no packet registering is needed.
|
|
|
|
*/
|
|
|
|
public ComponentRewriter() {
|
|
|
|
this.protocol = null;
|
|
|
|
}
|
|
|
|
|
2021-04-10 17:03:43 +02:00
|
|
|
/**
|
|
|
|
* Processes components at the beginning of the packet.
|
|
|
|
* Used for packets that have components as their very first value, so no special pre-reading is necessary.
|
|
|
|
*
|
|
|
|
* @param packetType clientbound packet type
|
|
|
|
*/
|
2023-02-04 18:29:22 +01:00
|
|
|
public void registerComponentPacket(C packetType) {
|
2023-02-12 11:44:25 +01:00
|
|
|
protocol.registerClientbound(packetType, wrapper -> processText(wrapper.passthrough(Type.COMPONENT)));
|
2020-06-28 22:19:59 +02:00
|
|
|
}
|
|
|
|
|
2021-11-21 11:12:13 +01:00
|
|
|
@Deprecated/*(forRemoval = true)**/
|
2023-02-04 18:29:22 +01:00
|
|
|
public void registerChatMessage(C packetType) {
|
2021-04-10 17:03:43 +02:00
|
|
|
registerComponentPacket(packetType);
|
|
|
|
}
|
|
|
|
|
2023-02-04 18:29:22 +01:00
|
|
|
public void registerBossBar(C packetType) {
|
2023-02-12 10:54:47 +01:00
|
|
|
protocol.registerClientbound(packetType, new PacketHandlers() {
|
2020-06-27 23:41:46 +02:00
|
|
|
@Override
|
2023-02-12 10:54:47 +01:00
|
|
|
public void register() {
|
2020-06-27 23:41:46 +02:00
|
|
|
map(Type.UUID);
|
|
|
|
map(Type.VAR_INT);
|
|
|
|
handler(wrapper -> {
|
|
|
|
int action = wrapper.get(Type.VAR_INT, 0);
|
|
|
|
if (action == 0 || action == 3) {
|
|
|
|
processText(wrapper.passthrough(Type.COMPONENT));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-04-10 17:03:43 +02:00
|
|
|
/**
|
|
|
|
* Handles sub 1.17 combat event components.
|
|
|
|
*/
|
2023-02-04 18:29:22 +01:00
|
|
|
public void registerCombatEvent(C packetType) {
|
2023-02-12 11:44:25 +01:00
|
|
|
protocol.registerClientbound(packetType, wrapper -> {
|
|
|
|
if (wrapper.passthrough(Type.VAR_INT) == 2) {
|
|
|
|
wrapper.passthrough(Type.VAR_INT);
|
|
|
|
wrapper.passthrough(Type.INT);
|
|
|
|
processText(wrapper.passthrough(Type.COMPONENT));
|
2020-06-27 23:41:46 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-04-10 17:03:43 +02:00
|
|
|
/**
|
|
|
|
* Handles sub 1.17 title components.
|
|
|
|
*/
|
2023-02-04 18:29:22 +01:00
|
|
|
public void registerTitle(C packetType) {
|
2023-02-12 11:44:25 +01:00
|
|
|
protocol.registerClientbound(packetType, wrapper -> {
|
|
|
|
int action = wrapper.passthrough(Type.VAR_INT);
|
|
|
|
if (action >= 0 && action <= 2) {
|
|
|
|
processText(wrapper.passthrough(Type.COMPONENT));
|
2020-06-27 23:41:46 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2020-06-25 16:22:53 +02:00
|
|
|
|
|
|
|
public JsonElement processText(String value) {
|
2020-07-28 09:59:35 +02:00
|
|
|
try {
|
2021-04-16 23:05:31 +02:00
|
|
|
JsonElement root = JsonParser.parseString(value);
|
2020-07-28 09:59:35 +02:00
|
|
|
processText(root);
|
|
|
|
return root;
|
|
|
|
} catch (JsonSyntaxException e) {
|
2020-08-06 10:15:38 +02:00
|
|
|
if (Via.getManager().isDebug()) {
|
|
|
|
Via.getPlatform().getLogger().severe("Error when trying to parse json: " + value);
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
// Yay to malformed json being accepted
|
|
|
|
return new JsonPrimitive(value);
|
2020-07-28 09:59:35 +02:00
|
|
|
}
|
2020-06-25 16:22:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void processText(JsonElement element) {
|
|
|
|
if (element == null || element.isJsonNull()) return;
|
|
|
|
if (element.isJsonArray()) {
|
|
|
|
processAsArray(element);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (element.isJsonPrimitive()) {
|
|
|
|
handleText(element.getAsJsonPrimitive());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonObject object = element.getAsJsonObject();
|
|
|
|
JsonPrimitive text = object.getAsJsonPrimitive("text");
|
|
|
|
if (text != null) {
|
|
|
|
handleText(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonElement translate = object.get("translate");
|
|
|
|
if (translate != null) {
|
|
|
|
handleTranslate(object, translate.getAsString());
|
|
|
|
|
|
|
|
JsonElement with = object.get("with");
|
|
|
|
if (with != null) {
|
|
|
|
processAsArray(with);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonElement extra = object.get("extra");
|
|
|
|
if (extra != null) {
|
|
|
|
processAsArray(extra);
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonObject hoverEvent = object.getAsJsonObject("hoverEvent");
|
|
|
|
if (hoverEvent != null) {
|
|
|
|
handleHoverEvent(hoverEvent);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void handleText(JsonPrimitive text) {
|
|
|
|
// To override if needed
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void handleTranslate(JsonObject object, String translate) {
|
|
|
|
// To override if needed
|
|
|
|
}
|
|
|
|
|
|
|
|
// To override if needed (don't forget to call super if needed)
|
|
|
|
protected void handleHoverEvent(JsonObject hoverEvent) {
|
|
|
|
String action = hoverEvent.getAsJsonPrimitive("action").getAsString();
|
|
|
|
if (action.equals("show_text")) {
|
|
|
|
JsonElement value = hoverEvent.get("value");
|
|
|
|
processText(value != null ? value : hoverEvent.get("contents"));
|
|
|
|
} else if (action.equals("show_entity")) {
|
|
|
|
JsonObject contents = hoverEvent.getAsJsonObject("contents");
|
|
|
|
if (contents != null) {
|
|
|
|
processText(contents.get("name"));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void processAsArray(JsonElement element) {
|
|
|
|
for (JsonElement jsonElement : element.getAsJsonArray()) {
|
|
|
|
processText(jsonElement);
|
|
|
|
}
|
|
|
|
}
|
2020-08-16 16:24:06 +02:00
|
|
|
|
2023-02-04 18:29:22 +01:00
|
|
|
public <T extends Protocol<C, ?, ?, ?>> T getProtocol() {
|
2020-08-16 16:24:06 +02:00
|
|
|
return (T) protocol;
|
|
|
|
}
|
2020-06-25 16:22:53 +02:00
|
|
|
}
|