3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-11-16 21:10:30 +01:00
Dieser Commit ist enthalten in:
Gero 2023-11-22 10:17:52 +01:00 committet von Shane Freeder
Ursprung a6d90105ec
Commit 814b53f12c
25 geänderte Dateien mit 406 neuen und 321 gelöschten Zeilen

Datei anzeigen

@ -63,7 +63,8 @@ public enum ProtocolVersion {
MINECRAFT_1_19_3(761, "1.19.3"), MINECRAFT_1_19_3(761, "1.19.3"),
MINECRAFT_1_19_4(762, "1.19.4"), MINECRAFT_1_19_4(762, "1.19.4"),
MINECRAFT_1_20(763, "1.20", "1.20.1"), MINECRAFT_1_20(763, "1.20", "1.20.1"),
MINECRAFT_1_20_2(764, "1.20.2"); MINECRAFT_1_20_2(764, "1.20.2"),
MINECRAFT_1_20_3(765, "1.20.3");
private static final int SNAPSHOT_BIT = 30; private static final int SNAPSHOT_BIT = 30;

Datei anzeigen

@ -19,6 +19,8 @@ import com.velocitypowered.api.proxy.player.TabList;
import com.velocitypowered.api.proxy.server.RegisteredServer; import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.api.util.ModInfo; import com.velocitypowered.api.util.ModInfo;
import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Optional; import java.util.Optional;
@ -236,6 +238,7 @@ public interface Player extends
* @return the applied resource pack or null if none. * @return the applied resource pack or null if none.
*/ */
@Nullable @Nullable
@Deprecated
ResourcePackInfo getAppliedResourcePack(); ResourcePackInfo getAppliedResourcePack();
/** /**
@ -246,8 +249,26 @@ public interface Player extends
* @return the pending resource pack or null if none * @return the pending resource pack or null if none
*/ */
@Nullable @Nullable
@Deprecated
ResourcePackInfo getPendingResourcePack(); ResourcePackInfo getPendingResourcePack();
/**
* Gets the {@link ResourcePackInfo} of the currently applied
* resource-packs.
*
* @return collection of the applied resource packs.
*/
Collection<ResourcePackInfo> getAppliedResourcePacks();
/**
* Gets the {@link ResourcePackInfo} of the resource packs
* the user is currently downloading or is currently
* prompted to install.
*
* @return collection of the pending resource packs
*/
Collection<ResourcePackInfo> getPendingResourcePacks();
/** /**
* <strong>Note that this method does not send a plugin message to the server the player * <strong>Note that this method does not send a plugin message to the server the player
* is connected to.</strong> You should only use this method if you are trying to communicate * is connected to.</strong> You should only use this method if you are trying to communicate

Datei anzeigen

@ -10,11 +10,20 @@ package com.velocitypowered.api.proxy.player;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.UUID;
/** /**
* Represents the information for a resource pack to apply that can be sent to the client. * Represents the information for a resource pack to apply that can be sent to the client.
*/ */
public interface ResourcePackInfo { public interface ResourcePackInfo {
/**
* Gets the id of this resource-pack.
*
* @return the id of the resource-pack
*/
UUID getId();
/** /**
* Gets the link the resource-pack can be found at. * Gets the link the resource-pack can be found at.
* *
@ -96,6 +105,13 @@ public interface ResourcePackInfo {
*/ */
interface Builder { interface Builder {
/**
* Sets the id of the resource pack.
*
* @param id the id the resource-pack
*/
Builder setId(UUID id);
/** /**
* Sets the resource-pack as required to play on the network. * Sets the resource-pack as required to play on the network.
* This feature was introduced in 1.17. * This feature was introduced in 1.17.

Datei anzeigen

@ -37,6 +37,7 @@ import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
import com.velocitypowered.proxy.protocol.packet.PingIdentify; import com.velocitypowered.proxy.protocol.packet.PingIdentify;
import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo; import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo;
import com.velocitypowered.proxy.protocol.packet.RemoveResourcePack;
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest; import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse; import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse;
import com.velocitypowered.proxy.protocol.packet.Respawn; import com.velocitypowered.proxy.protocol.packet.Respawn;
@ -248,6 +249,10 @@ public interface MinecraftSessionHandler {
return false; return false;
} }
default boolean handle(RemoveResourcePack packet) {
return false;
}
default boolean handle(ResourcePackResponse packet) { default boolean handle(ResourcePackResponse packet) {
return false; return false;
} }

Datei anzeigen

@ -49,11 +49,13 @@ import com.velocitypowered.proxy.protocol.packet.KeepAlive;
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItem; import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItem;
import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo; import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo;
import com.velocitypowered.proxy.protocol.packet.RemoveResourcePack;
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest; import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse; import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse;
import com.velocitypowered.proxy.protocol.packet.ServerData; import com.velocitypowered.proxy.protocol.packet.ServerData;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse; import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse;
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo; import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import com.velocitypowered.proxy.protocol.packet.config.StartUpdate; import com.velocitypowered.proxy.protocol.packet.config.StartUpdate;
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil; import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@ -167,7 +169,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
public boolean handle(ResourcePackRequest packet) { public boolean handle(ResourcePackRequest packet) {
ResourcePackInfo.Builder builder = new VelocityResourcePackInfo.BuilderImpl( ResourcePackInfo.Builder builder = new VelocityResourcePackInfo.BuilderImpl(
Preconditions.checkNotNull(packet.getUrl())) Preconditions.checkNotNull(packet.getUrl()))
.setPrompt(packet.getPrompt()) .setId(packet.getId())
.setPrompt(packet.getPrompt() == null ? null : packet.getPrompt().getComponent())
.setShouldForce(packet.isRequired()) .setShouldForce(packet.isRequired())
.setOrigin(ResourcePackInfo.Origin.DOWNSTREAM_SERVER); .setOrigin(ResourcePackInfo.Origin.DOWNSTREAM_SERVER);
@ -213,6 +216,11 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
return true; return true;
} }
@Override
public boolean handle(RemoveResourcePack packet) {
//TODO
}
@Override @Override
public boolean handle(PluginMessage packet) { public boolean handle(PluginMessage packet) {
if (bungeecordMessageResponder.process(packet)) { if (bungeecordMessageResponder.process(packet)) {
@ -304,7 +312,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
ping -> server.getEventManager() ping -> server.getEventManager()
.fire(new ProxyPingEvent(this.serverConn.getPlayer(), ping)), .fire(new ProxyPingEvent(this.serverConn.getPlayer(), ping)),
playerConnection.eventLoop()).thenAcceptAsync(pingEvent -> this.playerConnection.write( playerConnection.eventLoop()).thenAcceptAsync(pingEvent -> this.playerConnection.write(
new ServerData(pingEvent.getPing().getDescriptionComponent(), new ServerData(new ComponentHolder(this.serverConn.ensureConnected().getProtocolVersion(),
pingEvent.getPing().getDescriptionComponent()),
pingEvent.getPing().getFavicon().orElse(null), packet.isSecureChatEnforced())), pingEvent.getPing().getFavicon().orElse(null), packet.isSecureChatEnforced())),
playerConnection.eventLoop()); playerConnection.eventLoop());
return true; return true;

Datei anzeigen

@ -68,6 +68,7 @@ import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest; import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
import com.velocitypowered.proxy.protocol.packet.chat.ChatQueue; import com.velocitypowered.proxy.protocol.packet.chat.ChatQueue;
import com.velocitypowered.proxy.protocol.packet.chat.ChatType; import com.velocitypowered.proxy.protocol.packet.chat.ChatType;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import com.velocitypowered.proxy.protocol.packet.chat.builder.ChatBuilderFactory; import com.velocitypowered.proxy.protocol.packet.chat.builder.ChatBuilderFactory;
import com.velocitypowered.proxy.protocol.packet.chat.legacy.LegacyChat; import com.velocitypowered.proxy.protocol.packet.chat.legacy.LegacyChat;
import com.velocitypowered.proxy.protocol.packet.config.StartUpdate; import com.velocitypowered.proxy.protocol.packet.config.StartUpdate;
@ -84,6 +85,7 @@ import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -1015,22 +1017,36 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player,
request.setHash(""); request.setHash("");
} }
request.setRequired(queued.getShouldForce()); request.setRequired(queued.getShouldForce());
request.setPrompt(queued.getPrompt()); request.setPrompt(queued.getPrompt() == null ? null : new ComponentHolder(getProtocolVersion(), queued.getPrompt()));
connection.write(request); connection.write(request);
} }
} }
@Override @Override
@Deprecated
public @Nullable ResourcePackInfo getAppliedResourcePack() { public @Nullable ResourcePackInfo getAppliedResourcePack() {
//TODO which resource pack should be returned here?
return appliedResourcePack; return appliedResourcePack;
} }
@Override @Override
@Deprecated
public @Nullable ResourcePackInfo getPendingResourcePack() { public @Nullable ResourcePackInfo getPendingResourcePack() {
//TODO which resource pack should be returned here?
return pendingResourcePack; return pendingResourcePack;
} }
@Override
public Collection<ResourcePackInfo> getAppliedResourcePacks() {
//TODO
}
@Override
public Collection<ResourcePackInfo> getPendingResourcePacks() {
//TODO
}
/** /**
* Clears the applied resource pack field. * Clears the applied resource pack field.
*/ */
@ -1089,6 +1105,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player,
* Gives an indication about the previous resource pack responses. * Gives an indication about the previous resource pack responses.
*/ */
public @Nullable Boolean getPreviousResourceResponse() { public @Nullable Boolean getPreviousResourceResponse() {
//TODO can probably be removed
return previousResourceResponse; return previousResourceResponse;
} }

Datei anzeigen

@ -22,11 +22,14 @@ import com.velocitypowered.api.proxy.player.ResourcePackInfo;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.UUID;
/** /**
* Implements {@link ResourcePackInfo}. * Implements {@link ResourcePackInfo}.
*/ */
public final class VelocityResourcePackInfo implements ResourcePackInfo { public final class VelocityResourcePackInfo implements ResourcePackInfo {
private final UUID id;
private final String url; private final String url;
private final @Nullable byte[] hash; private final @Nullable byte[] hash;
private final boolean shouldForce; private final boolean shouldForce;
@ -34,8 +37,9 @@ public final class VelocityResourcePackInfo implements ResourcePackInfo {
private final Origin origin; private final Origin origin;
private Origin originalOrigin; private Origin originalOrigin;
private VelocityResourcePackInfo(String url, @Nullable byte[] hash, boolean shouldForce, private VelocityResourcePackInfo(UUID id, String url, @Nullable byte[] hash, boolean shouldForce,
@Nullable Component prompt, Origin origin) { @Nullable Component prompt, Origin origin) {
this.id = id;
this.url = url; this.url = url;
this.hash = hash; this.hash = hash;
this.shouldForce = shouldForce; this.shouldForce = shouldForce;
@ -44,6 +48,11 @@ public final class VelocityResourcePackInfo implements ResourcePackInfo {
this.originalOrigin = origin; this.originalOrigin = origin;
} }
@Override
public UUID getId() {
return id;
}
@Override @Override
public String getUrl() { public String getUrl() {
return url; return url;
@ -81,6 +90,7 @@ public final class VelocityResourcePackInfo implements ResourcePackInfo {
@Override @Override
public Builder asBuilder() { public Builder asBuilder() {
return new BuilderImpl(url) return new BuilderImpl(url)
.setId(id)
.setShouldForce(shouldForce) .setShouldForce(shouldForce)
.setHash(hash) .setHash(hash)
.setPrompt(prompt); .setPrompt(prompt);
@ -89,6 +99,7 @@ public final class VelocityResourcePackInfo implements ResourcePackInfo {
@Override @Override
public Builder asBuilder(String newUrl) { public Builder asBuilder(String newUrl) {
return new BuilderImpl(newUrl) return new BuilderImpl(newUrl)
.setId(id)
.setShouldForce(shouldForce) .setShouldForce(shouldForce)
.setHash(hash) .setHash(hash)
.setPrompt(prompt); .setPrompt(prompt);
@ -99,6 +110,7 @@ public final class VelocityResourcePackInfo implements ResourcePackInfo {
*/ */
public static final class BuilderImpl implements ResourcePackInfo.Builder { public static final class BuilderImpl implements ResourcePackInfo.Builder {
private UUID id;
private final String url; private final String url;
private boolean shouldForce; private boolean shouldForce;
private @Nullable byte[] hash; private @Nullable byte[] hash;
@ -109,6 +121,12 @@ public final class VelocityResourcePackInfo implements ResourcePackInfo {
this.url = Preconditions.checkNotNull(url, "url"); this.url = Preconditions.checkNotNull(url, "url");
} }
@Override
public BuilderImpl setId(UUID id) {
this.id = id;
return this;
}
@Override @Override
public BuilderImpl setShouldForce(boolean shouldForce) { public BuilderImpl setShouldForce(boolean shouldForce) {
this.shouldForce = shouldForce; this.shouldForce = shouldForce;
@ -134,7 +152,7 @@ public final class VelocityResourcePackInfo implements ResourcePackInfo {
@Override @Override
public ResourcePackInfo build() { public ResourcePackInfo build() {
return new VelocityResourcePackInfo(url, hash, shouldForce, prompt, origin); return new VelocityResourcePackInfo(id, url, hash, shouldForce, prompt, origin);
} }
public BuilderImpl setOrigin(Origin origin) { public BuilderImpl setOrigin(Origin origin) {

Datei anzeigen

@ -1,128 +0,0 @@
/*
* Copyright (C) 2018-2023 Velocity 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 <https://www.gnu.org/licenses/>.
*/
package com.velocitypowered.proxy.connection.registry;
import com.velocitypowered.proxy.connection.player.VelocityResourcePackInfo;
import com.velocitypowered.proxy.protocol.packet.config.RegistrySync;
import net.kyori.adventure.key.Key;
import org.jetbrains.annotations.Nullable;
/**
* Holds the registry data that is sent
* to the client during the config stage.
*/
public class ClientConfigData {
private final @Nullable VelocityResourcePackInfo resourcePackInfo;
private final DataTag tag;
private final RegistrySync registry;
private final Key[] features;
private final String brand;
private ClientConfigData(@Nullable VelocityResourcePackInfo resourcePackInfo, DataTag tag,
RegistrySync registry, Key[] features, String brand) {
this.resourcePackInfo = resourcePackInfo;
this.tag = tag;
this.registry = registry;
this.features = features;
this.brand = brand;
}
public RegistrySync getRegistry() {
return registry;
}
public DataTag getTag() {
return tag;
}
public Key[] getFeatures() {
return features;
}
public @Nullable VelocityResourcePackInfo getResourcePackInfo() {
return resourcePackInfo;
}
public String getBrand() {
return brand;
}
/**
* Creates a new builder.
*
* @return ClientConfigData.Builder
*/
public static ClientConfigData.Builder builder() {
return new Builder();
}
/**
* Builder for ClientConfigData.
*/
public static class Builder {
private VelocityResourcePackInfo resourcePackInfo;
private DataTag tag;
private RegistrySync registry;
private Key[] features;
private String brand;
private Builder() {
}
/**
* Clears the builder.
*/
public void clear() {
this.resourcePackInfo = null;
this.tag = null;
this.registry = null;
this.features = null;
this.brand = null;
}
public Builder resourcePack(@Nullable VelocityResourcePackInfo resourcePackInfo) {
this.resourcePackInfo = resourcePackInfo;
return this;
}
public Builder dataTag(DataTag tag) {
this.tag = tag;
return this;
}
public Builder registry(RegistrySync registry) {
this.registry = registry;
return this;
}
public Builder features(Key[] features) {
this.features = features;
return this;
}
public Builder brand(String brand) {
this.brand = brand;
return this;
}
public ClientConfigData build() {
return new ClientConfigData(resourcePackInfo, tag, registry, features, brand);
}
}
}

Datei anzeigen

@ -1,95 +0,0 @@
/*
* Copyright (C) 2019-2023 Velocity 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 <https://www.gnu.org/licenses/>.
*/
package com.velocitypowered.proxy.connection.registry;
import com.google.common.collect.ImmutableList;
import java.util.List;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import org.jetbrains.annotations.NotNull;
/**
* Represents a data tag.
*/
public class DataTag {
private final ImmutableList<DataTag.Set> entrySets;
public DataTag(ImmutableList<DataTag.Set> entrySets) {
this.entrySets = entrySets;
}
/**
* Returns the entry sets.
*
* @return List of entry sets
*/
public List<Set> getEntrySets() {
return entrySets;
}
/**
* Represents a data tag set.
*/
public static class Set implements Keyed {
private final Key key;
private final ImmutableList<Entry> entries;
public Set(Key key, ImmutableList<Entry> entries) {
this.key = key;
this.entries = entries;
}
/**
* Returns the entries.
*
* @return List of entries
*/
public List<Entry> getEntries() {
return entries;
}
@Override
public @NotNull Key key() {
return key;
}
}
/**
* Represents a data tag entry.
*/
public static class Entry implements Keyed {
private final Key key;
private final int[] elements;
public Entry(Key key, int[] elements) {
this.key = key;
this.elements = elements;
}
public int[] getElements() {
return elements;
}
@Override
public @NotNull Key key() {
return key;
}
}
}

Datei anzeigen

@ -34,15 +34,16 @@ import io.netty.buffer.ByteBufUtil;
import io.netty.handler.codec.CorruptedFrameException; import io.netty.handler.codec.CorruptedFrameException;
import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.EncoderException; import io.netty.handler.codec.EncoderException;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import net.kyori.adventure.key.Key; import net.kyori.adventure.key.Key;
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.BinaryTagIO; import net.kyori.adventure.nbt.BinaryTagIO;
import net.kyori.adventure.nbt.BinaryTagType;
import net.kyori.adventure.nbt.BinaryTagTypes;
import net.kyori.adventure.nbt.CompoundBinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
@ -64,6 +65,11 @@ public enum ProtocolUtils {
.build(); .build();
public static final int DEFAULT_MAX_STRING_SIZE = 65536; // 64KiB public static final int DEFAULT_MAX_STRING_SIZE = 65536; // 64KiB
private static final BinaryTagType<? extends BinaryTag>[] BINARY_TAG_TYPES = new BinaryTagType[] {
BinaryTagTypes.END, BinaryTagTypes.BYTE, BinaryTagTypes.SHORT, BinaryTagTypes.INT,
BinaryTagTypes.LONG, BinaryTagTypes.FLOAT, BinaryTagTypes.DOUBLE,
BinaryTagTypes.BYTE_ARRAY, BinaryTagTypes.STRING, BinaryTagTypes.LIST,
BinaryTagTypes.COMPOUND, BinaryTagTypes.INT_ARRAY, BinaryTagTypes.LONG_ARRAY};
private static final QuietDecoderException BAD_VARINT_CACHED = private static final QuietDecoderException BAD_VARINT_CACHED =
new QuietDecoderException("Bad VarInt decoded"); new QuietDecoderException("Bad VarInt decoded");
private static final int[] VARINT_EXACT_BYTE_LENGTHS = new int[33]; private static final int[] VARINT_EXACT_BYTE_LENGTHS = new int[33];
@ -367,29 +373,53 @@ public enum ProtocolUtils {
* Reads a {@link net.kyori.adventure.nbt.CompoundBinaryTag} from the {@code buf}. * Reads a {@link net.kyori.adventure.nbt.CompoundBinaryTag} from the {@code buf}.
* *
* @param buf the buffer to read from * @param buf the buffer to read from
* @param reader the NBT reader to use * @param reader the {@link BinaryTagIO.Reader} to use
* @return {@link net.kyori.adventure.nbt.CompoundBinaryTag} the CompoundTag from the buffer * @return {@link net.kyori.adventure.nbt.CompoundBinaryTag} the CompoundTag from the buffer
*/ */
public static CompoundBinaryTag readCompoundTag(ByteBuf buf, BinaryTagIO.Reader reader) { public static CompoundBinaryTag readCompoundTag(ByteBuf buf, ProtocolVersion version, BinaryTagIO.Reader reader) {
BinaryTag binaryTag = readBinaryTag(buf, version, reader);
if (binaryTag.type() != BinaryTagTypes.COMPOUND) {
throw new DecoderException("Expected root tag to be CompoundTag, but is " + binaryTag.getClass().getSimpleName());
}
return (CompoundBinaryTag) binaryTag;
}
/**
* Reads a {@link net.kyori.adventure.nbt.BinaryTag} from the {@code buf}.
*
* @param buf the buffer to read from
* @param reader the {@link BinaryTagIO.Reader} to use
* @return {@link net.kyori.adventure.nbt.BinaryTag} the BinaryTag from the buffer
*/
public static BinaryTag readBinaryTag(ByteBuf buf, ProtocolVersion version, BinaryTagIO.Reader reader) {
BinaryTagType<?> type = BINARY_TAG_TYPES[buf.readByte()];
if (version.compareTo(ProtocolVersion.MINECRAFT_1_20_2) < 0) {
buf.skipBytes(buf.readUnsignedShort());
}
try { try {
return reader.read((DataInput) new ByteBufInputStream(buf)); return type.read(new ByteBufInputStream(buf));
} catch (IOException thrown) { } catch (IOException thrown) {
throw new DecoderException( throw new DecoderException("Unable to parse BinaryTag, full error: " + thrown.getMessage());
"Unable to parse NBT CompoundTag, full error: " + thrown.getMessage());
} }
} }
/** /**
* Writes a CompoundTag to the {@code buf}. * Writes a {@link net.kyori.adventure.nbt.BinaryTag} to the {@code buf}.
* *
* @param buf the buffer to write to * @param buf the buffer to write to
* @param compoundTag the CompoundTag to write * @param tag the BinaryTag to write
*/ */
public static void writeCompoundTag(ByteBuf buf, CompoundBinaryTag compoundTag) { public static <T extends BinaryTag> void writeBinaryTag(ByteBuf buf, ProtocolVersion version, T tag) {
BinaryTagType<T> type = (BinaryTagType<T>) tag.type();
buf.writeByte(type.id());
try { try {
BinaryTagIO.writer().write(compoundTag, (DataOutput) new ByteBufOutputStream(buf)); if (version.compareTo(ProtocolVersion.MINECRAFT_1_20_2) < 0) {
// Empty name
buf.writeShort(0);
}
type.write(tag, new ByteBufOutputStream(buf));
} catch (IOException e) { } catch (IOException e) {
throw new EncoderException("Unable to encode NBT CompoundTag"); throw new EncoderException("Unable to encode BinaryTag");
} }
} }

Datei anzeigen

@ -34,6 +34,7 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19_1;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19_3; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19_3;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19_4; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_19_4;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_20_2; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_20_2;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_20_3;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_7_2; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_7_2;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9;
@ -62,6 +63,7 @@ import com.velocitypowered.proxy.protocol.packet.LoginPluginResponse;
import com.velocitypowered.proxy.protocol.packet.PingIdentify; import com.velocitypowered.proxy.protocol.packet.PingIdentify;
import com.velocitypowered.proxy.protocol.packet.PluginMessage; import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo; import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo;
import com.velocitypowered.proxy.protocol.packet.RemoveResourcePack;
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest; import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse; import com.velocitypowered.proxy.protocol.packet.ResourcePackResponse;
import com.velocitypowered.proxy.protocol.packet.Respawn; import com.velocitypowered.proxy.protocol.packet.Respawn;
@ -154,10 +156,16 @@ public enum StateRegistry {
clientbound.register( clientbound.register(
RegistrySync.class, RegistrySync::new, map(0x05, MINECRAFT_1_20_2, false)); RegistrySync.class, RegistrySync::new, map(0x05, MINECRAFT_1_20_2, false));
clientbound.register( clientbound.register(
ResourcePackRequest.class, ResourcePackRequest::new, map(0x06, MINECRAFT_1_20_2, false)); RemoveResourcePack.class, RemoveResourcePack::new, map(0x06, MINECRAFT_1_20_3, false));
clientbound.register( clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new,
ActiveFeatures.class, ActiveFeatures::new, map(0x07, MINECRAFT_1_20_2, false)); map(0x06, MINECRAFT_1_20_2, false),
clientbound.register(TagsUpdate.class, TagsUpdate::new, map(0x08, MINECRAFT_1_20_2, false)); map(0x07, MINECRAFT_1_20_3, false));
clientbound.register(ActiveFeatures.class, ActiveFeatures::new,
map(0x07, MINECRAFT_1_20_2, false),
map(0x08, MINECRAFT_1_20_3, false));
clientbound.register(TagsUpdate.class, TagsUpdate::new,
map(0x08, MINECRAFT_1_20_2, false),
map(0x09, MINECRAFT_1_20_3, false));
} }
}, },
PLAY { PLAY {
@ -228,7 +236,8 @@ public enum StateRegistry {
map(0x0D, MINECRAFT_1_19_1, false), map(0x0D, MINECRAFT_1_19_1, false),
map(0x0C, MINECRAFT_1_19_3, false), map(0x0C, MINECRAFT_1_19_3, false),
map(0x0D, MINECRAFT_1_19_4, false), map(0x0D, MINECRAFT_1_19_4, false),
map(0x0F, MINECRAFT_1_20_2, false)); map(0x0F, MINECRAFT_1_20_2, false),
map(0x10, MINECRAFT_1_20_3, false));
serverbound.register( serverbound.register(
KeepAlive.class, KeepAlive.class,
KeepAlive::new, KeepAlive::new,
@ -244,7 +253,8 @@ public enum StateRegistry {
map(0x12, MINECRAFT_1_19_1, false), map(0x12, MINECRAFT_1_19_1, false),
map(0x11, MINECRAFT_1_19_3, false), map(0x11, MINECRAFT_1_19_3, false),
map(0x12, MINECRAFT_1_19_4, false), map(0x12, MINECRAFT_1_19_4, false),
map(0x14, MINECRAFT_1_20_2, false)); map(0x14, MINECRAFT_1_20_2, false),
map(0x15, MINECRAFT_1_20_3, false));
serverbound.register( serverbound.register(
ResourcePackResponse.class, ResourcePackResponse.class,
ResourcePackResponse::new, ResourcePackResponse::new,
@ -257,7 +267,8 @@ public enum StateRegistry {
map(0x21, MINECRAFT_1_16_2, false), map(0x21, MINECRAFT_1_16_2, false),
map(0x23, MINECRAFT_1_19, false), map(0x23, MINECRAFT_1_19, false),
map(0x24, MINECRAFT_1_19_1, false), map(0x24, MINECRAFT_1_19_1, false),
map(0x27, MINECRAFT_1_20_2, false)); map(0x27, MINECRAFT_1_20_2, false),
map(0x28, MINECRAFT_1_20_3, false));
serverbound.register( serverbound.register(
FinishedUpdate.class, FinishedUpdate::new, map(0x0B, MINECRAFT_1_20_2, false)); FinishedUpdate.class, FinishedUpdate::new, map(0x0B, MINECRAFT_1_20_2, false));
@ -385,7 +396,10 @@ public enum StateRegistry {
map(0x3E, MINECRAFT_1_19_1, true), map(0x3E, MINECRAFT_1_19_1, true),
map(0x3D, MINECRAFT_1_19_3, true), map(0x3D, MINECRAFT_1_19_3, true),
map(0x41, MINECRAFT_1_19_4, true), map(0x41, MINECRAFT_1_19_4, true),
map(0x43, MINECRAFT_1_20_2, true)); map(0x43, MINECRAFT_1_20_2, true),
map(0x45, MINECRAFT_1_20_3, true));
clientbound.register(
RemoveResourcePack.class, RemoveResourcePack::new, map(0x43, MINECRAFT_1_20_3, false));
clientbound.register( clientbound.register(
ResourcePackRequest.class, ResourcePackRequest.class,
ResourcePackRequest::new, ResourcePackRequest::new,
@ -403,7 +417,8 @@ public enum StateRegistry {
map(0x3D, MINECRAFT_1_19_1, false), map(0x3D, MINECRAFT_1_19_1, false),
map(0x3C, MINECRAFT_1_19_3, false), map(0x3C, MINECRAFT_1_19_3, false),
map(0x40, MINECRAFT_1_19_4, false), map(0x40, MINECRAFT_1_19_4, false),
map(0x42, MINECRAFT_1_20_2, false)); map(0x42, MINECRAFT_1_20_2, false),
map(0x44, MINECRAFT_1_20_3, false));
clientbound.register( clientbound.register(
HeaderAndFooter.class, HeaderAndFooter.class,
HeaderAndFooter::new, HeaderAndFooter::new,
@ -422,7 +437,8 @@ public enum StateRegistry {
map(0x63, MINECRAFT_1_19_1, true), map(0x63, MINECRAFT_1_19_1, true),
map(0x61, MINECRAFT_1_19_3, true), map(0x61, MINECRAFT_1_19_3, true),
map(0x65, MINECRAFT_1_19_4, true), map(0x65, MINECRAFT_1_19_4, true),
map(0x68, MINECRAFT_1_20_2, true)); map(0x68, MINECRAFT_1_20_2, true),
map(0x6A, MINECRAFT_1_20_3, true));
clientbound.register( clientbound.register(
LegacyTitlePacket.class, LegacyTitlePacket.class,
LegacyTitlePacket::new, LegacyTitlePacket::new,
@ -440,7 +456,8 @@ public enum StateRegistry {
map(0x5B, MINECRAFT_1_19_1, true), map(0x5B, MINECRAFT_1_19_1, true),
map(0x59, MINECRAFT_1_19_3, true), map(0x59, MINECRAFT_1_19_3, true),
map(0x5D, MINECRAFT_1_19_4, true), map(0x5D, MINECRAFT_1_19_4, true),
map(0x5F, MINECRAFT_1_20_2, true)); map(0x5F, MINECRAFT_1_20_2, true),
map(0x61, MINECRAFT_1_20_3, true));
clientbound.register( clientbound.register(
TitleTextPacket.class, TitleTextPacket.class,
TitleTextPacket::new, TitleTextPacket::new,
@ -449,7 +466,8 @@ public enum StateRegistry {
map(0x5D, MINECRAFT_1_19_1, true), map(0x5D, MINECRAFT_1_19_1, true),
map(0x5B, MINECRAFT_1_19_3, true), map(0x5B, MINECRAFT_1_19_3, true),
map(0x5F, MINECRAFT_1_19_4, true), map(0x5F, MINECRAFT_1_19_4, true),
map(0x61, MINECRAFT_1_20_2, true)); map(0x61, MINECRAFT_1_20_2, true),
map(0x63, MINECRAFT_1_20_3, true));
clientbound.register( clientbound.register(
TitleActionbarPacket.class, TitleActionbarPacket.class,
TitleActionbarPacket::new, TitleActionbarPacket::new,
@ -458,7 +476,8 @@ public enum StateRegistry {
map(0x43, MINECRAFT_1_19_1, true), map(0x43, MINECRAFT_1_19_1, true),
map(0x42, MINECRAFT_1_19_3, true), map(0x42, MINECRAFT_1_19_3, true),
map(0x46, MINECRAFT_1_19_4, true), map(0x46, MINECRAFT_1_19_4, true),
map(0x48, MINECRAFT_1_20_2, true)); map(0x48, MINECRAFT_1_20_2, true),
map(0x4A, MINECRAFT_1_20_3, true));
clientbound.register( clientbound.register(
TitleTimesPacket.class, TitleTimesPacket.class,
TitleTimesPacket::new, TitleTimesPacket::new,
@ -467,7 +486,8 @@ public enum StateRegistry {
map(0x5E, MINECRAFT_1_19_1, true), map(0x5E, MINECRAFT_1_19_1, true),
map(0x5C, MINECRAFT_1_19_3, true), map(0x5C, MINECRAFT_1_19_3, true),
map(0x60, MINECRAFT_1_19_4, true), map(0x60, MINECRAFT_1_19_4, true),
map(0x62, MINECRAFT_1_20_2, true)); map(0x62, MINECRAFT_1_20_2, true),
map(0x64, MINECRAFT_1_20_3, true));
clientbound.register( clientbound.register(
TitleClearPacket.class, TitleClearPacket.class,
TitleClearPacket::new, TitleClearPacket::new,
@ -507,7 +527,8 @@ public enum StateRegistry {
map(0x62, MINECRAFT_1_19_1, true), map(0x62, MINECRAFT_1_19_1, true),
map(0x60, MINECRAFT_1_19_3, true), map(0x60, MINECRAFT_1_19_3, true),
map(0x64, MINECRAFT_1_19_4, true), map(0x64, MINECRAFT_1_19_4, true),
map(0x67, MINECRAFT_1_20_2, true)); map(0x67, MINECRAFT_1_20_2, true),
map(0x69, MINECRAFT_1_20_3, true));
clientbound.register( clientbound.register(
PlayerChatCompletion.class, PlayerChatCompletion.class,
PlayerChatCompletion::new, PlayerChatCompletion::new,
@ -522,8 +543,13 @@ public enum StateRegistry {
map(0x42, MINECRAFT_1_19_1, false), map(0x42, MINECRAFT_1_19_1, false),
map(0x41, MINECRAFT_1_19_3, false), map(0x41, MINECRAFT_1_19_3, false),
map(0x45, MINECRAFT_1_19_4, false), map(0x45, MINECRAFT_1_19_4, false),
map(0x47, MINECRAFT_1_20_2, false)); map(0x47, MINECRAFT_1_20_2, false),
clientbound.register(StartUpdate.class, StartUpdate::new, map(0x65, MINECRAFT_1_20_2, false)); map(0x49, MINECRAFT_1_20_3, false));
clientbound.register(
StartUpdate.class,
StartUpdate::new,
map(0x65, MINECRAFT_1_20_2, false),
map(0x67, MINECRAFT_1_20_3, false));
} }
}, },
LOGIN { LOGIN {

Datei anzeigen

@ -21,6 +21,7 @@ import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import java.util.UUID; import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -35,7 +36,7 @@ public class BossBar implements MinecraftPacket {
public static final int UPDATE_PROPERTIES = 5; public static final int UPDATE_PROPERTIES = 5;
private @Nullable UUID uuid; private @Nullable UUID uuid;
private int action; private int action;
private @Nullable String name; private @Nullable ComponentHolder name;
private float percent; private float percent;
private int color; private int color;
private int overlay; private int overlay;
@ -60,11 +61,11 @@ public class BossBar implements MinecraftPacket {
this.action = action; this.action = action;
} }
public @Nullable String getName() { public @Nullable ComponentHolder getName() {
return name; return name;
} }
public void setName(String name) { public void setName(ComponentHolder name) {
this.name = name; this.name = name;
} }
@ -119,7 +120,7 @@ public class BossBar implements MinecraftPacket {
this.action = ProtocolUtils.readVarInt(buf); this.action = ProtocolUtils.readVarInt(buf);
switch (action) { switch (action) {
case ADD: case ADD:
this.name = ProtocolUtils.readString(buf); this.name = ComponentHolder.read(buf, version);
this.percent = buf.readFloat(); this.percent = buf.readFloat();
this.color = ProtocolUtils.readVarInt(buf); this.color = ProtocolUtils.readVarInt(buf);
this.overlay = ProtocolUtils.readVarInt(buf); this.overlay = ProtocolUtils.readVarInt(buf);
@ -131,7 +132,7 @@ public class BossBar implements MinecraftPacket {
this.percent = buf.readFloat(); this.percent = buf.readFloat();
break; break;
case UPDATE_NAME: case UPDATE_NAME:
this.name = ProtocolUtils.readString(buf); this.name = ComponentHolder.read(buf, version);
break; break;
case UPDATE_STYLE: case UPDATE_STYLE:
this.color = ProtocolUtils.readVarInt(buf); this.color = ProtocolUtils.readVarInt(buf);
@ -157,7 +158,7 @@ public class BossBar implements MinecraftPacket {
if (name == null) { if (name == null) {
throw new IllegalStateException("No name specified!"); throw new IllegalStateException("No name specified!");
} }
ProtocolUtils.writeString(buf, name); name.write(buf, version);
buf.writeFloat(percent); buf.writeFloat(percent);
ProtocolUtils.writeVarInt(buf, color); ProtocolUtils.writeVarInt(buf, color);
ProtocolUtils.writeVarInt(buf, overlay); ProtocolUtils.writeVarInt(buf, overlay);
@ -172,7 +173,7 @@ public class BossBar implements MinecraftPacket {
if (name == null) { if (name == null) {
throw new IllegalStateException("No name specified!"); throw new IllegalStateException("No name specified!");
} }
ProtocolUtils.writeString(buf, name); name.write(buf, version);
break; break;
case UPDATE_STYLE: case UPDATE_STYLE:
ProtocolUtils.writeVarInt(buf, color); ProtocolUtils.writeVarInt(buf, color);

Datei anzeigen

@ -17,39 +17,36 @@
package com.velocitypowered.proxy.protocol.packet; package com.velocitypowered.proxy.protocol.packet;
import static com.velocitypowered.proxy.protocol.ProtocolUtils.writeString;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
public class HeaderAndFooter implements MinecraftPacket { public class HeaderAndFooter implements MinecraftPacket {
private static final String EMPTY_COMPONENT = "{\"translate\":\"\"}";
private static final HeaderAndFooter RESET = new HeaderAndFooter(); private static final HeaderAndFooter RESET = new HeaderAndFooter();
private final String header; private final ComponentHolder header;
private final String footer; private final ComponentHolder footer;
public HeaderAndFooter() { public HeaderAndFooter() {
this(EMPTY_COMPONENT, EMPTY_COMPONENT); this(ComponentHolder.EMPTY, ComponentHolder.EMPTY);
} }
public HeaderAndFooter(String header, String footer) { public HeaderAndFooter(ComponentHolder header, ComponentHolder footer) {
this.header = Preconditions.checkNotNull(header, "header"); this.header = Preconditions.checkNotNull(header, "header");
this.footer = Preconditions.checkNotNull(footer, "footer"); this.footer = Preconditions.checkNotNull(footer, "footer");
} }
public String getHeader() { public ComponentHolder getHeader() {
return header; return header;
} }
public String getFooter() { public ComponentHolder getFooter() {
return footer; return footer;
} }
@ -60,8 +57,8 @@ public class HeaderAndFooter implements MinecraftPacket {
@Override @Override
public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
writeString(buf, header); header.write(buf, version);
writeString(buf, footer); footer.write(buf, version);
} }
@Override @Override
@ -71,8 +68,8 @@ public class HeaderAndFooter implements MinecraftPacket {
public static HeaderAndFooter create(Component header, public static HeaderAndFooter create(Component header,
Component footer, ProtocolVersion protocolVersion) { Component footer, ProtocolVersion protocolVersion) {
GsonComponentSerializer serializer = ProtocolUtils.getJsonChatSerializer(protocolVersion); return new HeaderAndFooter(new ComponentHolder(protocolVersion, header),
return new HeaderAndFooter(serializer.serialize(header), serializer.serialize(footer)); new ComponentHolder(protocolVersion, footer));
} }
public static HeaderAndFooter reset() { public static HeaderAndFooter reset() {

Datei anzeigen

@ -255,12 +255,12 @@ public class JoinGame implements MinecraftPacket {
this.previousGamemode = buf.readByte(); this.previousGamemode = buf.readByte();
this.levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf)); this.levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf));
this.registry = ProtocolUtils.readCompoundTag(buf, JOINGAME_READER); this.registry = ProtocolUtils.readCompoundTag(buf, version, JOINGAME_READER);
String dimensionIdentifier; String dimensionIdentifier;
String levelName = null; String levelName = null;
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0 if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0
&& version.compareTo(ProtocolVersion.MINECRAFT_1_19) < 0) { && version.compareTo(ProtocolVersion.MINECRAFT_1_19) < 0) {
this.currentDimensionData = ProtocolUtils.readCompoundTag(buf, JOINGAME_READER); this.currentDimensionData = ProtocolUtils.readCompoundTag(buf, version, JOINGAME_READER);
dimensionIdentifier = ProtocolUtils.readString(buf); dimensionIdentifier = ProtocolUtils.readString(buf);
} else { } else {
dimensionIdentifier = ProtocolUtils.readString(buf); dimensionIdentifier = ProtocolUtils.readString(buf);
@ -390,10 +390,10 @@ public class JoinGame implements MinecraftPacket {
buf.writeByte(previousGamemode); buf.writeByte(previousGamemode);
ProtocolUtils.writeStringArray(buf, levelNames.toArray(String[]::new)); ProtocolUtils.writeStringArray(buf, levelNames.toArray(String[]::new));
ProtocolUtils.writeCompoundTag(buf, this.registry); ProtocolUtils.writeBinaryTag(buf, version, this.registry);
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0 if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0
&& version.compareTo(ProtocolVersion.MINECRAFT_1_19) < 0) { && version.compareTo(ProtocolVersion.MINECRAFT_1_19) < 0) {
ProtocolUtils.writeCompoundTag(buf, currentDimensionData); ProtocolUtils.writeBinaryTag(buf, version, currentDimensionData);
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier()); ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
} else { } else {
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier()); ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());

Datei anzeigen

@ -0,0 +1,54 @@
/*
* Copyright (C) 2018-2021 Velocity 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 <https://www.gnu.org/licenses/>.
*/
package com.velocitypowered.proxy.protocol.packet;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import io.netty.buffer.ByteBuf;
import java.util.UUID;
public class RemoveResourcePack implements MinecraftPacket {
private UUID id;
public RemoveResourcePack() {
}
public RemoveResourcePack(UUID id) {
this.id = id;
}
@Override
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
this.id = ProtocolUtils.readUuid(buf);
}
@Override
public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
ProtocolUtils.writeUuid(buf, id);
}
@Override
public boolean handle(MinecraftSessionHandler handler) {
return handler.handle(this);
}
}

Datei anzeigen

@ -25,24 +25,33 @@ import com.velocitypowered.proxy.connection.player.VelocityResourcePackInfo;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction; import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil; import io.netty.buffer.ByteBufUtil;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.UUID;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class ResourcePackRequest implements MinecraftPacket { public class ResourcePackRequest implements MinecraftPacket {
private @MonotonicNonNull UUID id; // 1.20.3+
private @MonotonicNonNull String url; private @MonotonicNonNull String url;
private @MonotonicNonNull String hash; private @MonotonicNonNull String hash;
private boolean isRequired; // 1.17+ private boolean isRequired; // 1.17+
private @Nullable Component prompt; // 1.17+ private @Nullable ComponentHolder prompt; // 1.17+
private static final Pattern PLAUSIBLE_SHA1_HASH = Pattern.compile("^[a-z0-9]{40}$"); // 1.20.2+ private static final Pattern PLAUSIBLE_SHA1_HASH = Pattern.compile("^[a-z0-9]{40}$"); // 1.20.2+
public @Nullable UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
public @Nullable String getUrl() { public @Nullable String getUrl() {
return url; return url;
} }
@ -67,22 +76,25 @@ public class ResourcePackRequest implements MinecraftPacket {
isRequired = required; isRequired = required;
} }
public @Nullable Component getPrompt() { public @Nullable ComponentHolder getPrompt() {
return prompt; return prompt;
} }
public void setPrompt(Component prompt) { public void setPrompt(ComponentHolder prompt) {
this.prompt = prompt; this.prompt = prompt;
} }
@Override @Override
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) { public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_20_3) >= 0) {
this.id = ProtocolUtils.readUuid(buf);
}
this.url = ProtocolUtils.readString(buf); this.url = ProtocolUtils.readString(buf);
this.hash = ProtocolUtils.readString(buf); this.hash = ProtocolUtils.readString(buf);
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) { if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) {
this.isRequired = buf.readBoolean(); this.isRequired = buf.readBoolean();
if (buf.readBoolean()) { if (buf.readBoolean()) {
this.prompt = GsonComponentSerializer.gson().deserialize(ProtocolUtils.readString(buf)); this.prompt = ComponentHolder.read(buf, protocolVersion);
} else { } else {
this.prompt = null; this.prompt = null;
} }
@ -91,6 +103,12 @@ public class ResourcePackRequest implements MinecraftPacket {
@Override @Override
public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) { public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_20_3) >= 0) {
if (id == null) {
throw new IllegalStateException("Resource pack id not set yet!");
}
ProtocolUtils.writeUuid(buf, id);
}
if (url == null || hash == null) { if (url == null || hash == null) {
throw new IllegalStateException("Packet not fully filled in yet!"); throw new IllegalStateException("Packet not fully filled in yet!");
} }
@ -100,7 +118,7 @@ public class ResourcePackRequest implements MinecraftPacket {
buf.writeBoolean(isRequired); buf.writeBoolean(isRequired);
if (prompt != null) { if (prompt != null) {
buf.writeBoolean(true); buf.writeBoolean(true);
ProtocolUtils.writeString(buf, GsonComponentSerializer.gson().serialize(prompt)); prompt.write(buf, protocolVersion);
} else { } else {
buf.writeBoolean(false); buf.writeBoolean(false);
} }
@ -109,7 +127,8 @@ public class ResourcePackRequest implements MinecraftPacket {
public VelocityResourcePackInfo toServerPromptedPack() { public VelocityResourcePackInfo toServerPromptedPack() {
ResourcePackInfo.Builder builder = ResourcePackInfo.Builder builder =
new VelocityResourcePackInfo.BuilderImpl(Preconditions.checkNotNull(url)).setPrompt(prompt) new VelocityResourcePackInfo.BuilderImpl(Preconditions.checkNotNull(url))
.setId(id).setPrompt(prompt == null ? null : prompt.getComponent())
.setShouldForce(isRequired).setOrigin(ResourcePackInfo.Origin.DOWNSTREAM_SERVER); .setShouldForce(isRequired).setOrigin(ResourcePackInfo.Origin.DOWNSTREAM_SERVER);
if (hash != null && !hash.isEmpty()) { if (hash != null && !hash.isEmpty()) {

Datei anzeigen

@ -165,7 +165,7 @@ public class Respawn implements MinecraftPacket {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) { if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0 if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0
&& version.compareTo(ProtocolVersion.MINECRAFT_1_19) < 0) { && version.compareTo(ProtocolVersion.MINECRAFT_1_19) < 0) {
this.currentDimensionData = ProtocolUtils.readCompoundTag(buf, BinaryTagIO.reader()); this.currentDimensionData = ProtocolUtils.readCompoundTag(buf, version, BinaryTagIO.reader());
dimensionIdentifier = ProtocolUtils.readString(buf); dimensionIdentifier = ProtocolUtils.readString(buf);
} else { } else {
dimensionIdentifier = ProtocolUtils.readString(buf); dimensionIdentifier = ProtocolUtils.readString(buf);
@ -210,7 +210,7 @@ public class Respawn implements MinecraftPacket {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) { if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0 if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0
&& version.compareTo(ProtocolVersion.MINECRAFT_1_19) < 0) { && version.compareTo(ProtocolVersion.MINECRAFT_1_19) < 0) {
ProtocolUtils.writeCompoundTag(buf, currentDimensionData); ProtocolUtils.writeBinaryTag(buf, version, currentDimensionData);
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier()); ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
} else { } else {
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier()); ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());

Datei anzeigen

@ -22,23 +22,23 @@ import com.velocitypowered.api.util.Favicon;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Base64; import java.util.Base64;
public class ServerData implements MinecraftPacket { public class ServerData implements MinecraftPacket {
private @Nullable Component description; private @Nullable ComponentHolder description;
private @Nullable Favicon favicon; private @Nullable Favicon favicon;
private boolean secureChatEnforced; // Added in 1.19.1 private boolean secureChatEnforced; // Added in 1.19.1
public ServerData() { public ServerData() {
} }
public ServerData(@Nullable Component description, @Nullable Favicon favicon, public ServerData(@Nullable ComponentHolder description, @Nullable Favicon favicon,
boolean secureChatEnforced) { boolean secureChatEnforced) {
this.description = description; this.description = description;
this.favicon = favicon; this.favicon = favicon;
this.secureChatEnforced = secureChatEnforced; this.secureChatEnforced = secureChatEnforced;
@ -48,8 +48,7 @@ public class ServerData implements MinecraftPacket {
public void decode(ByteBuf buf, ProtocolUtils.Direction direction, public void decode(ByteBuf buf, ProtocolUtils.Direction direction,
ProtocolVersion protocolVersion) { ProtocolVersion protocolVersion) {
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_19_4) >= 0 || buf.readBoolean()) { if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_19_4) >= 0 || buf.readBoolean()) {
this.description = ProtocolUtils.getJsonChatSerializer(protocolVersion) this.description = ComponentHolder.read(buf, protocolVersion);
.deserialize(ProtocolUtils.readString(buf));
} }
if (buf.readBoolean()) { if (buf.readBoolean()) {
String iconBase64; String iconBase64;
@ -77,10 +76,7 @@ public class ServerData implements MinecraftPacket {
buf.writeBoolean(hasDescription); buf.writeBoolean(hasDescription);
} }
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_19_4) >= 0 || hasDescription) { if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_19_4) >= 0 || hasDescription) {
ProtocolUtils.writeString( this.description.write(buf, protocolVersion);
buf,
ProtocolUtils.getJsonChatSerializer(protocolVersion).serialize(this.description)
);
} }
boolean hasFavicon = this.favicon != null; boolean hasFavicon = this.favicon != null;
@ -108,7 +104,7 @@ public class ServerData implements MinecraftPacket {
return handler.handle(this); return handler.handle(this);
} }
public @Nullable Component getDescription() { public @Nullable ComponentHolder getDescription() {
return description; return description;
} }

Datei anzeigen

@ -22,6 +22,7 @@ import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler; import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.protocol.MinecraftPacket; import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import com.velocitypowered.proxy.protocol.packet.chat.RemoteChatSession; import com.velocitypowered.proxy.protocol.packet.chat.RemoteChatSession;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import java.util.ArrayList; import java.util.ArrayList;
@ -31,7 +32,6 @@ import java.util.Collection;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
public class UpsertPlayerInfo implements MinecraftPacket { public class UpsertPlayerInfo implements MinecraftPacket {
@ -179,16 +179,14 @@ public class UpsertPlayerInfo implements MinecraftPacket {
}), }),
UPDATE_DISPLAY_NAME((version, buf, info) -> { // read UPDATE_DISPLAY_NAME((version, buf, info) -> { // read
if (buf.readBoolean()) { if (buf.readBoolean()) {
info.displayName = ProtocolUtils.getJsonChatSerializer(version) info.displayName = ComponentHolder.read(buf, version);
.deserialize(ProtocolUtils.readString(buf));
} else { } else {
info.displayName = null; info.displayName = null;
} }
}, (version, buf, info) -> { // write }, (version, buf, info) -> { // write
buf.writeBoolean(info.displayName != null); buf.writeBoolean(info.displayName != null);
if (info.displayName != null) { if (info.displayName != null) {
ProtocolUtils.writeString(buf, ProtocolUtils.getJsonChatSerializer(version) info.displayName.write(buf, version);
.serialize(info.displayName));
} }
}); });
@ -219,7 +217,7 @@ public class UpsertPlayerInfo implements MinecraftPacket {
private int latency; private int latency;
private int gameMode; private int gameMode;
@Nullable @Nullable
private Component displayName; private ComponentHolder displayName;
@Nullable @Nullable
private RemoteChatSession chatSession; private RemoteChatSession chatSession;
@ -248,7 +246,7 @@ public class UpsertPlayerInfo implements MinecraftPacket {
} }
@Nullable @Nullable
public Component getDisplayName() { public ComponentHolder getDisplayName() {
return displayName; return displayName;
} }
@ -273,7 +271,7 @@ public class UpsertPlayerInfo implements MinecraftPacket {
this.gameMode = gameMode; this.gameMode = gameMode;
} }
public void setDisplayName(@Nullable Component displayName) { public void setDisplayName(@Nullable ComponentHolder displayName) {
this.displayName = displayName; this.displayName = displayName;
} }

Datei anzeigen

@ -0,0 +1,82 @@
package com.velocitypowered.proxy.protocol.packet.chat;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import io.netty.buffer.ByteBuf;
import net.kyori.adventure.nbt.BinaryTag;
import net.kyori.adventure.nbt.BinaryTagIO;
import net.kyori.adventure.nbt.StringBinaryTag;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
public class ComponentHolder {
public static ComponentHolder EMPTY = new ComponentHolder(null, Component.empty());
static {
EMPTY.json = "{\"text\":\"\"}";
EMPTY.binaryTag = StringBinaryTag.stringBinaryTag("");
}
private final ProtocolVersion version;
private @MonotonicNonNull Component component;
private @MonotonicNonNull String json;
private @MonotonicNonNull BinaryTag binaryTag;
public ComponentHolder(ProtocolVersion version, Component component) {
this.version = version;
this.component = component;
}
public ComponentHolder(ProtocolVersion version, String json) {
this.version = version;
this.json = json;
}
public ComponentHolder(ProtocolVersion version, BinaryTag binaryTag) {
this.version = version;
this.binaryTag = binaryTag;
}
public Component getComponent() {
if (component == null) {
if (json != null) {
component = ProtocolUtils.getJsonChatSerializer(version).deserialize(json);
} else if (binaryTag != null) {
//TODO component = deserialize(binaryTag);
throw new UnsupportedOperationException("binary tag -> component not implemented yet");
}
}
return component;
}
public String getJson() {
if (json == null) {
json = ProtocolUtils.getJsonChatSerializer(version).serialize(getComponent());
}
return json;
}
public BinaryTag getBinaryTag() {
if (binaryTag == null) {
//TODO binaryTag = serialize(getComponent());
throw new UnsupportedOperationException("component -> binary tag not implemented yet");
}
return binaryTag;
}
public static ComponentHolder read(ByteBuf buf, ProtocolVersion version) {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_20_3) >= 0) {
return new ComponentHolder(version, ProtocolUtils.readBinaryTag(buf, version, BinaryTagIO.reader()));
} else {
return new ComponentHolder(version, ProtocolUtils.readString(buf));
}
}
public void write(ByteBuf buf, ProtocolVersion version) {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_20_3) >= 0) {
ProtocolUtils.writeBinaryTag(buf, version, getBinaryTag());
} else {
ProtocolUtils.writeString(buf, getJson());
}
}
}

Datei anzeigen

@ -17,6 +17,7 @@
package com.velocitypowered.proxy.tablist; package com.velocitypowered.proxy.tablist;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.player.TabList; import com.velocitypowered.api.proxy.player.TabList;
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItem; import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItem;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo; import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo;
@ -27,6 +28,8 @@ import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo;
*/ */
public interface InternalTabList extends TabList { public interface InternalTabList extends TabList {
Player getPlayer();
default void processLegacy(LegacyPlayerListItem packet) { default void processLegacy(LegacyPlayerListItem packet) {
} }

Datei anzeigen

@ -59,6 +59,11 @@ public class KeyedVelocityTabList implements InternalTabList {
this.connection = player.getConnection(); this.connection = player.getConnection();
} }
@Override
public Player getPlayer() {
return player;
}
@Deprecated @Deprecated
@Override @Override
public void setHeaderAndFooter(Component header, Component footer) { public void setHeaderAndFooter(Component header, Component footer) {

Datei anzeigen

@ -19,6 +19,7 @@ package com.velocitypowered.proxy.tablist;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.player.ChatSession; import com.velocitypowered.api.proxy.player.ChatSession;
import com.velocitypowered.api.proxy.player.TabListEntry; import com.velocitypowered.api.proxy.player.TabListEntry;
import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.api.util.GameProfile;
@ -27,6 +28,7 @@ import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.console.VelocityConsole; import com.velocitypowered.proxy.console.VelocityConsole;
import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo; import com.velocitypowered.proxy.protocol.packet.RemovePlayerInfo;
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo; import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import com.velocitypowered.proxy.protocol.packet.chat.RemoteChatSession; import com.velocitypowered.proxy.protocol.packet.chat.RemoteChatSession;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -64,6 +66,11 @@ public class VelocityTabList implements InternalTabList {
this.entries = Maps.newHashMap(); this.entries = Maps.newHashMap();
} }
@Override
public Player getPlayer() {
return player;
}
@Override @Override
public void setHeaderAndFooter(Component header, Component footer) { public void setHeaderAndFooter(Component header, Component footer) {
Preconditions.checkNotNull(header, "header"); Preconditions.checkNotNull(header, "header");
@ -103,7 +110,8 @@ public class VelocityTabList implements InternalTabList {
if (!Objects.equals(previousEntry.getDisplayNameComponent().orElse(null), if (!Objects.equals(previousEntry.getDisplayNameComponent().orElse(null),
entry.getDisplayNameComponent().orElse(null))) { entry.getDisplayNameComponent().orElse(null))) {
actions.add(UpsertPlayerInfo.Action.UPDATE_DISPLAY_NAME); actions.add(UpsertPlayerInfo.Action.UPDATE_DISPLAY_NAME);
playerInfoEntry.setDisplayName(entry.getDisplayNameComponent().get()); playerInfoEntry.setDisplayName(new ComponentHolder(player.getProtocolVersion(),
entry.getDisplayNameComponent().get()));
} }
if (!Objects.equals(previousEntry.getLatency(), entry.getLatency())) { if (!Objects.equals(previousEntry.getLatency(), entry.getLatency())) {
actions.add(UpsertPlayerInfo.Action.UPDATE_LATENCY); actions.add(UpsertPlayerInfo.Action.UPDATE_LATENCY);
@ -132,7 +140,8 @@ public class VelocityTabList implements InternalTabList {
playerInfoEntry.setProfile(entry.getProfile()); playerInfoEntry.setProfile(entry.getProfile());
if (entry.getDisplayNameComponent().isPresent()) { if (entry.getDisplayNameComponent().isPresent()) {
actions.add(UpsertPlayerInfo.Action.UPDATE_DISPLAY_NAME); actions.add(UpsertPlayerInfo.Action.UPDATE_DISPLAY_NAME);
playerInfoEntry.setDisplayName(entry.getDisplayNameComponent().get()); playerInfoEntry.setDisplayName(new ComponentHolder(player.getProtocolVersion(),
entry.getDisplayNameComponent().get()));
} }
if (entry.getChatSession() != null) { if (entry.getChatSession() != null) {
actions.add(UpsertPlayerInfo.Action.INITIALIZE_CHAT); actions.add(UpsertPlayerInfo.Action.INITIALIZE_CHAT);
@ -243,7 +252,7 @@ public class VelocityTabList implements InternalTabList {
currentEntry.setLatencyWithoutUpdate(entry.getLatency()); currentEntry.setLatencyWithoutUpdate(entry.getLatency());
} }
if (actions.contains(UpsertPlayerInfo.Action.UPDATE_DISPLAY_NAME)) { if (actions.contains(UpsertPlayerInfo.Action.UPDATE_DISPLAY_NAME)) {
currentEntry.setDisplayNameWithoutUpdate(entry.getDisplayName()); currentEntry.setDisplayNameWithoutUpdate(entry.getDisplayName().getComponent());
} }
if (actions.contains(UpsertPlayerInfo.Action.INITIALIZE_CHAT)) { if (actions.contains(UpsertPlayerInfo.Action.INITIALIZE_CHAT)) {
currentEntry.setChatSession(entry.getChatSession()); currentEntry.setChatSession(entry.getChatSession());

Datei anzeigen

@ -23,6 +23,8 @@ import com.velocitypowered.api.proxy.player.TabListEntry;
import com.velocitypowered.api.util.GameProfile; import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo; import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfo;
import java.util.Optional; import java.util.Optional;
import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -78,7 +80,7 @@ public class VelocityTabListEntry implements TabListEntry {
public TabListEntry setDisplayName(@Nullable Component displayName) { public TabListEntry setDisplayName(@Nullable Component displayName) {
this.displayName = displayName; this.displayName = displayName;
UpsertPlayerInfo.Entry upsertEntry = this.tabList.createRawEntry(this); UpsertPlayerInfo.Entry upsertEntry = this.tabList.createRawEntry(this);
upsertEntry.setDisplayName(displayName); upsertEntry.setDisplayName(new ComponentHolder(this.tabList.getPlayer().getProtocolVersion(), displayName));
this.tabList.emitActionRaw(UpsertPlayerInfo.Action.UPDATE_DISPLAY_NAME, upsertEntry); this.tabList.emitActionRaw(UpsertPlayerInfo.Action.UPDATE_DISPLAY_NAME, upsertEntry);
return this; return this;
} }

Datei anzeigen

@ -20,7 +20,7 @@ package com.velocitypowered.proxy.util.bossbar;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
import com.velocitypowered.api.network.ProtocolVersion; import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer; import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
import com.velocitypowered.proxy.protocol.ProtocolUtils; import com.velocitypowered.proxy.protocol.packet.chat.ComponentHolder;
import com.velocitypowered.proxy.util.collect.Enum2IntMap; import com.velocitypowered.proxy.util.collect.Enum2IntMap;
import com.velocitypowered.proxy.util.concurrent.Once; import com.velocitypowered.proxy.util.concurrent.Once;
import java.util.Collections; import java.util.Collections;
@ -212,8 +212,7 @@ public class AdventureBossBarManager implements BossBar.Listener {
.proxy.protocol.packet.BossBar(); .proxy.protocol.packet.BossBar();
packet.setUuid(this.id); packet.setUuid(this.id);
packet.setAction(com.velocitypowered.proxy.protocol.packet.BossBar.ADD); packet.setAction(com.velocitypowered.proxy.protocol.packet.BossBar.ADD);
packet.setName(ProtocolUtils.getJsonChatSerializer(player.getProtocolVersion()) packet.setName(new ComponentHolder(player.getProtocolVersion(), player.translateMessage(bar.name())));
.serialize(player.translateMessage(bar.name())));
packet.setColor(COLORS_TO_PROTOCOL.get(bar.color())); packet.setColor(COLORS_TO_PROTOCOL.get(bar.color()));
packet.setOverlay(OVERLAY_TO_PROTOCOL.get(bar.overlay())); packet.setOverlay(OVERLAY_TO_PROTOCOL.get(bar.overlay()));
packet.setPercent(bar.progress()); packet.setPercent(bar.progress());
@ -247,7 +246,7 @@ public class AdventureBossBarManager implements BossBar.Listener {
.proxy.protocol.packet.BossBar(); .proxy.protocol.packet.BossBar();
packet.setUuid(this.id); packet.setUuid(this.id);
packet.setAction(com.velocitypowered.proxy.protocol.packet.BossBar.UPDATE_NAME); packet.setAction(com.velocitypowered.proxy.protocol.packet.BossBar.UPDATE_NAME);
packet.setName(ProtocolUtils.getJsonChatSerializer(version).serialize(name)); packet.setName(new ComponentHolder(version, name));
return packet; return packet;
} }