Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-17 05:20:14 +01:00
WIP 1.20.3
Dieser Commit ist enthalten in:
Ursprung
a6d90105ec
Commit
814b53f12c
@ -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;
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
@ -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() {
|
||||||
|
@ -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());
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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()) {
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
@ -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());
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren