Compare commits

...
11 Commits
6 changed files with 108 additions and 32 deletions

No files matched your search

@@ -29,6 +29,7 @@ import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.api.rewriter.EntityRewriter;
import com.viaversion.viaversion.api.rewriter.ItemRewriter;
@@ -150,12 +151,11 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
configurationState.setClientInformation(clientInformation);
wrapper.cancel();
});
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), -1, wrapper -> {
wrapper.setPacketType(ServerboundPackets1_19_4.PLUGIN_MESSAGE);
sanitizeCustomPayload(wrapper);
});
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.KEEP_ALIVE.getId(), -1, wrapper -> wrapper.setPacketType(ServerboundPackets1_19_4.KEEP_ALIVE));
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.PONG.getId(), -1, wrapper -> wrapper.setPacketType(ServerboundPackets1_19_4.PONG));
// If these are not queued, they may be received before the server switched its listener state to play
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.CUSTOM_PAYLOAD.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.PLUGIN_MESSAGE));
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.KEEP_ALIVE.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.KEEP_ALIVE));
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.PONG.getId(), -1, queueServerboundPacket(ServerboundPackets1_20_2.PONG));
// Cancel this, as it will always just be the response to a re-sent pack from us
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.RESOURCE_PACK.getId(), -1, PacketWrapper::cancel);
@@ -302,6 +302,14 @@ public final class Protocol1_20_2To1_20 extends AbstractProtocol<ClientboundPack
protocolInfo.setServerState(State.PLAY);
}
private PacketHandler queueServerboundPacket(final ServerboundPackets1_20_2 packetType) {
return wrapper -> {
wrapper.setPacketType(packetType);
wrapper.user().get(ConfigurationState.class).addPacketToQueue(wrapper, false);
wrapper.cancel();
};
}
private void sanitizeCustomPayload(final PacketWrapper wrapper) throws Exception {
final String channel = Key.namespaced(wrapper.passthrough(Type.STRING));
if (channel.equals("minecraft:brand")) {
@@ -35,6 +35,7 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.internal.LazilyParsedNumber;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.data.MappingData;
@@ -65,6 +66,7 @@ import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.rewriter.Entit
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
import com.viaversion.viaversion.rewriter.TagRewriter;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.BitSet;
import java.util.HashSet;
@@ -200,7 +202,7 @@ public final class Protocol1_20_3To1_20_2 extends AbstractProtocol<ClientboundPa
if (wrapper.passthrough(Type.BOOLEAN)) {
final int icons = wrapper.passthrough(Type.VAR_INT);
for (int i = 0; i < icons; i++) {
wrapper.passthrough(Type.BYTE); // Type
wrapper.passthrough(Type.VAR_INT); // Type
wrapper.passthrough(Type.BYTE); // X
wrapper.passthrough(Type.BYTE); // Y
wrapper.passthrough(Type.BYTE); // Rotation
@@ -264,7 +266,12 @@ public final class Protocol1_20_3To1_20_2 extends AbstractProtocol<ClientboundPa
registerClientbound(ClientboundPackets1_20_2.ACTIONBAR, this::convertComponent);
registerClientbound(ClientboundPackets1_20_2.TITLE_TEXT, this::convertComponent);
registerClientbound(ClientboundPackets1_20_2.TITLE_SUBTITLE, this::convertComponent);
registerClientbound(ClientboundPackets1_20_2.DISGUISED_CHAT, this::convertComponent);
registerClientbound(ClientboundPackets1_20_2.DISGUISED_CHAT, wrapper -> {
convertComponent(wrapper);
wrapper.passthrough(Type.VAR_INT); // Chat type
convertComponent(wrapper); // Name
convertOptionalComponent(wrapper); // Target name
});
registerClientbound(ClientboundPackets1_20_2.SYSTEM_CHAT, this::convertComponent);
registerClientbound(ClientboundPackets1_20_2.OPEN_WINDOW, wrapper -> {
wrapper.passthrough(Type.VAR_INT); // Container id
@@ -320,27 +327,45 @@ public final class Protocol1_20_3To1_20_2 extends AbstractProtocol<ClientboundPa
}
});
registerServerbound(ServerboundPackets1_20_3.RESOURCE_PACK_STATUS, wrapper -> wrapper.read(Type.UUID));
registerServerbound(ServerboundPackets1_20_3.RESOURCE_PACK_STATUS, resourcePackStatusHandler());
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.RESOURCE_PACK, wrapper -> wrapper.read(Type.UUID));
registerServerbound(State.CONFIGURATION, ServerboundConfigurationPackets1_20_2.RESOURCE_PACK, resourcePackStatusHandler());
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.RESOURCE_PACK.getId(), ClientboundConfigurationPackets1_20_3.RESOURCE_PACK_PUSH.getId(), resourcePackHandler(ClientboundConfigurationPackets1_20_3.RESOURCE_PACK_POP));
// TODO Auto map via packet types provider
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.UPDATE_ENABLED_FEATURES.getId(), ClientboundConfigurationPackets1_20_3.UPDATE_ENABLED_FEATURES.getId());
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.UPDATE_TAGS.getId(), ClientboundConfigurationPackets1_20_3.UPDATE_TAGS.getId());
registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.UPDATE_TAGS.getId(), ClientboundConfigurationPackets1_20_3.UPDATE_TAGS.getId(), tagRewriter.getGenericHandler());
}
private PacketHandler resourcePackStatusHandler() {
return wrapper -> {
wrapper.read(Type.UUID); // Pack UUID
final int action = wrapper.read(Type.VAR_INT);
if (action == 4) { // Downloaded
wrapper.cancel();
} else if (action > 4) { // Invalid url, failed reload, and discarded
wrapper.write(Type.VAR_INT, 2); // Failed download
} else {
wrapper.write(Type.VAR_INT, action);
}
};
}
private PacketHandler resourcePackHandler(final ClientboundPacketType popType) {
return wrapper -> {
wrapper.write(Type.UUID, UUID.randomUUID());
wrapper.passthrough(Type.STRING); // Url
wrapper.passthrough(Type.STRING); // Hash
wrapper.passthrough(Type.BOOLEAN); // Required
convertOptionalComponent(wrapper);
// Drop old resource packs first
final PacketWrapper dropPacksPacket = wrapper.create(popType);
dropPacksPacket.write(Type.OPTIONAL_UUID, null);
dropPacksPacket.send(Protocol1_20_3To1_20_2.class);
// Use the hash to write a pack uuid
final String url = wrapper.read(Type.STRING);
final String hash = wrapper.read(Type.STRING);
wrapper.write(Type.UUID, UUID.nameUUIDFromBytes(hash.getBytes(StandardCharsets.UTF_8)));
wrapper.write(Type.STRING, url);
wrapper.write(Type.STRING, hash);
wrapper.passthrough(Type.BOOLEAN); // Required
convertOptionalComponent(wrapper);
};
}
@@ -375,10 +400,12 @@ public final class Protocol1_20_3To1_20_2 extends AbstractProtocol<ClientboundPa
return null;
} else if (element.isJsonObject()) {
final CompoundTag tag = new CompoundTag();
for (final Map.Entry<String, JsonElement> entry : element.getAsJsonObject().entrySet()) {
// Not strictly needed, but might as well make it more compact
final JsonObject jsonObject = element.getAsJsonObject();
for (final Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
convertObjectEntry(entry.getKey(), entry.getValue(), tag);
}
addComponentType(jsonObject, tag);
return tag;
} else if (element.isJsonArray()) {
return convertJsonArray(element);
@@ -403,12 +430,37 @@ public final class Protocol1_20_3To1_20_2 extends AbstractProtocol<ClientboundPa
return new DoubleTag(number.doubleValue());
} else if (number instanceof Float) {
return new FloatTag(number.floatValue());
} else if (number instanceof LazilyParsedNumber) {
// TODO: This might need better handling
return new IntTag(number.intValue());
}
return new StringTag(primitive.getAsString()); // ???
return new IntTag(number.intValue()); // ???
}
throw new IllegalArgumentException("Unhandled json type " + element.getClass().getSimpleName() + " with value " + element.getAsString());
}
private static void addComponentType(final JsonObject object, final CompoundTag tag) {
if (object.has("type")) {
return;
}
// Add the type to speed up deserialization and make DFU errors slightly more useful
// Order is important
if (object.has("text")) {
tag.put("type", new StringTag("text"));
} else if (object.has("translate")) {
tag.put("type", new StringTag("translatable"));
} else if (object.has("score")) {
tag.put("type", new StringTag("score"));
} else if (object.has("selector")) {
tag.put("type", new StringTag("selector"));
} else if (object.has("keybind")) {
tag.put("type", new StringTag("keybind"));
} else if (object.has("nbt")) {
tag.put("type", new StringTag("nbt"));
}
}
private static ListTag convertJsonArray(final JsonElement element) {
// TODO Number arrays?
final ListTag listTag = new ListTag();
@@ -439,29 +491,38 @@ public final class Protocol1_20_3To1_20_2 extends AbstractProtocol<ClientboundPa
// Wrap all entries in compound tags as lists can only consist of one type of tag
final CompoundTag compoundTag = new CompoundTag();
compoundTag.put("type", new StringTag("text"));
compoundTag.put("text", new StringTag());
compoundTag.put("extra", convertedTag);
}
return processedListTag;
}
private static void convertObjectEntry(final String key, final JsonElement element, final CompoundTag tag) {
if ((key.equals("contents")) && element.isJsonObject()) {
/**
* Converts a json object entry to a tag entry.
*
* @param key key of the entry
* @param value value of the entry
* @param tag the resulting compound tag
*/
private static void convertObjectEntry(final String key, final JsonElement value, final CompoundTag tag) {
if ((key.equals("contents")) && value.isJsonObject()) {
// Store show_entity id as int array instead of uuid string
final JsonObject hoverEvent = element.getAsJsonObject();
// Not really required, but we might as well make it more compact
final JsonObject hoverEvent = value.getAsJsonObject();
final JsonElement id = hoverEvent.get("id");
final UUID uuid;
if (id != null && id.isJsonPrimitive() && (uuid = parseUUID(id.getAsString())) != null) {
hoverEvent.remove("id");
final CompoundTag convertedTag = (CompoundTag) convertToTag(element);
final CompoundTag convertedTag = (CompoundTag) convertToTag(value);
convertedTag.put("id", new IntArrayTag(UUIDIntArrayType.uuidToIntArray(uuid)));
tag.put(key, convertedTag);
return;
}
}
tag.put(key, convertToTag(element));
tag.put(key, convertToTag(value));
}
private static @Nullable UUID parseUUID(final String uuidString) {
@@ -24,6 +24,7 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityType;
import com.viaversion.viaversion.api.protocol.Protocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandler;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.util.Key;
@@ -149,6 +150,10 @@ public class TagRewriter<C extends ClientboundPacketType> {
protocol.registerClientbound(packetType, getGenericHandler());
}
public void registerGeneric(State state, ClientboundPacketType packetType) {
protocol.registerClientbound(state, packetType, getGenericHandler());
}
public PacketHandler getHandler(@Nullable RegistryType readUntilType) {
return wrapper -> {
for (RegistryType type : RegistryType.getValues()) {
+2 -2
View File
@@ -1,8 +1,8 @@
# Project properties - we put these here so they can be modified without causing a recompile of the build scripts
projectVersion=4.9.0
projectVersion=4.9.2
# Smile emoji
mcVersions=1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9
mcVersions=1.20.3, 1.20.2, 1.20.1, 1.20, 1.19.4, 1.19.3, 1.19.2, 1.19.1, 1.19, 1.18.2, 1.18.1, 1.18, 1.17.1, 1.17, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16, 1.15.2, 1.15.1, 1.15, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14, 1.13.2, 1.13.1, 1.13, 1.12.2, 1.12.1, 1.12, 1.11.2, 1.11.1, 1.11, 1.10.2, 1.10.1, 1.10, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9, 1.8.9
mcVersionRange=1.8-1.20.3
waterfallVersion=1.20
velocityVersion=3.2
@@ -24,10 +24,11 @@ import com.viaversion.viaversion.api.minecraft.entities.EntityTypes1_20_3;
import com.viaversion.viaversion.api.protocol.AbstractProtocol;
import com.viaversion.viaversion.api.protocol.packet.ClientboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.ServerboundPacketType;
import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.data.entity.EntityTrackerBase;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ServerboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundConfigurationPackets1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ServerboundPackets1_20_3;
import com.viaversion.viaversion.rewriter.SoundRewriter;
import com.viaversion.viaversion.rewriter.StatisticsRewriter;
@@ -39,7 +40,7 @@ import com.viaversion.viaversion.template.protocols.rewriter.EntityPacketRewrite
// Protocol1_99To_98, EntityPacketRewriter1_99, BlockItemPacketRewriter1_99
// ClientboundPackets1_20_2
// ServerboundPackets1_20_3
// ClientboundConfigurationPackets1_20_2
// ClientboundConfigurationPackets1_20_3
// ServerboundConfigurationPackets1_20_2
// Entity1_19_4Types (MAPPED type)
// 1.99, 1.98
@@ -61,6 +62,7 @@ public final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPackets
// Registers renames etc. as well as registry type id changes
final TagRewriter<ClientboundPackets1_20_2> tagRewriter = new TagRewriter<>(this);
tagRewriter.registerGeneric(ClientboundPackets1_20_2.TAGS);
tagRewriter.registerGeneric(State.CONFIGURATION, ClientboundConfigurationPackets1_20_3.UPDATE_TAGS);
// Registers sound id changes
final SoundRewriter<ClientboundPackets1_20_2> soundRewriter = new SoundRewriter<>(this);
@@ -128,7 +130,7 @@ public final class Protocol1_99To_98 extends AbstractProtocol<ClientboundPackets
@Override
protected ClientboundPacketType clientboundFinishConfigurationPacket() {
return ClientboundConfigurationPackets1_20_2.FINISH_CONFIGURATION;
return ClientboundConfigurationPackets1_20_3.FINISH_CONFIGURATION;
}
@Override
@@ -23,8 +23,8 @@ import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
import com.viaversion.viaversion.api.type.Type;
import com.viaversion.viaversion.api.type.types.version.Types1_20_3;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundConfigurationPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_2to1_20.packet.ClientboundPackets1_20_2;
import com.viaversion.viaversion.protocols.protocol1_20_3to1_20_2.packet.ClientboundConfigurationPackets1_20_3;
import com.viaversion.viaversion.rewriter.EntityRewriter;
import com.viaversion.viaversion.template.protocols.Protocol1_99To_98;
@@ -44,7 +44,7 @@ public final class EntityPacketRewriter1_99 extends EntityRewriter<ClientboundPa
registerMetadataRewriter(ClientboundPackets1_20_2.ENTITY_METADATA, /*Types1_OLD.METADATA_LIST, */Types1_20_3.METADATA_LIST); // Specify old and new metadata list if changed
registerRemoveEntities(ClientboundPackets1_20_2.REMOVE_ENTITIES);
protocol.registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_2.REGISTRY_DATA, new PacketHandlers() {
protocol.registerClientbound(State.CONFIGURATION, ClientboundConfigurationPackets1_20_3.REGISTRY_DATA, new PacketHandlers() {
@Override
protected void register() {
map(Type.COMPOUND_TAG); // Registry data