diff --git a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java index 8b3632f9f..6cf31f06b 100644 --- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java +++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java @@ -53,7 +53,8 @@ public enum ProtocolVersion { MINECRAFT_1_16_1(736, "1.16.1"), MINECRAFT_1_16_2(751, "1.16.2"), MINECRAFT_1_16_3(753, "1.16.3"), - MINECRAFT_1_16_4(754, "1.16.4", "1.16.5"); + MINECRAFT_1_16_4(754, "1.16.4", "1.16.5"), + MINECRAFT_1_17(754, 5, "1.17"); // Note: this probably isnt intentional private static final int SNAPSHOT_BIT = 30; diff --git a/api/src/main/java/com/velocitypowered/api/proxy/Player.java b/api/src/main/java/com/velocitypowered/api/proxy/Player.java index 540adc75e..1a09ae3ca 100644 --- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java +++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java @@ -239,4 +239,19 @@ public interface Player extends CommandSource, Identified, InboundConnection, */ @Override boolean sendPluginMessage(ChannelIdentifier identifier, byte[] data); + + /** + * Sends the specified resource pack from {@code url} to the user, using the specified 20-byte + * SHA-1 hash. To monitor the status of the sent resource pack, subscribe to + * {@link PlayerResourcePackStatusEvent}. + * In 1.17 and newer you can additionally specify + * whether the resource pack is required or not. Setting this for an older client will have + * no effect. + * + * @param url the URL for the resource pack + * @param hash the SHA-1 hash value for the resource pack + * @param isRequired flag to set the resource pack as required in 1.17+ + */ + void sendResourcePack(String url, byte[] hash, boolean isRequired); + } diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java index fe49f71ee..9d6e98eac 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java @@ -871,12 +871,13 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { ResourcePackRequest request = new ResourcePackRequest(); request.setUrl(url); request.setHash(""); + request.setRequired(false); connection.write(request); } } @Override - public void sendResourcePack(String url, byte[] hash) { + public void sendResourcePack(String url, byte[] hash, boolean isRequired) { Preconditions.checkNotNull(url, "url"); Preconditions.checkNotNull(hash, "hash"); Preconditions.checkArgument(hash.length == 20, "Hash length is not 20"); @@ -885,10 +886,16 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player { ResourcePackRequest request = new ResourcePackRequest(); request.setUrl(url); request.setHash(ByteBufUtil.hexDump(hash)); + request.setRequired(isRequired); connection.write(request); } } + @Override + public void sendResourcePack(String url, byte[] hash) { + sendResourcePack(url, hash, false); + } + /** * Sends a {@link KeepAlive} packet to the player with a random ID. * The response will be ignored by Velocity as it will not match the diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackRequest.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackRequest.java index 522ddc2c7..c2115970d 100644 --- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackRequest.java +++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackRequest.java @@ -30,6 +30,7 @@ public class ResourcePackRequest implements MinecraftPacket { private @MonotonicNonNull String url; private @MonotonicNonNull String hash; + private boolean isRequired; // 1.17+ public @Nullable String getUrl() { return url; @@ -39,6 +40,10 @@ public class ResourcePackRequest implements MinecraftPacket { this.url = url; } + public boolean isRequired() { + return isRequired; + } + public @Nullable String getHash() { return hash; } @@ -47,10 +52,17 @@ public class ResourcePackRequest implements MinecraftPacket { this.hash = hash; } + public void setRequired(boolean required) { + isRequired = required; + } + @Override public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) { this.url = ProtocolUtils.readString(buf); this.hash = ProtocolUtils.readString(buf); + if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) { + this.isRequired = buf.readBoolean(); + } } @Override @@ -60,6 +72,9 @@ public class ResourcePackRequest implements MinecraftPacket { } ProtocolUtils.writeString(buf, url); ProtocolUtils.writeString(buf, hash); + if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) { + buf.writeBoolean(isRequired); + } } @Override