From 7f0964155c6f8f186dc7ae368e567ed42e5ff40d Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Wed, 4 Nov 2020 22:35:27 +0100
Subject: [PATCH 01/30] Snapshot 20w45a
---
.../api/network/ProtocolVersion.java | 3 ++-
.../com/velocitypowered/api/proxy/Player.java | 15 +++++++++++++++
.../proxy/connection/client/ConnectedPlayer.java | 9 ++++++++-
.../protocol/packet/ResourcePackRequest.java | 15 +++++++++++++++
4 files changed, 40 insertions(+), 2 deletions(-)
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
From d444bed96b7ddae64b00dccb8b3a8fc4c7e4a226 Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Thu, 5 Nov 2020 10:01:05 +0100
Subject: [PATCH 02/30] Adjust snapshot -> final version
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 6cf31f06b..67cd49963 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(754, 5, "1.17"); // Note: this probably isnt intentional
+ MINECRAFT_1_17(-1, 5, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
private static final int SNAPSHOT_BIT = 30;
From d8a39fc43897aefe488afa2ed83170f45505819f Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Wed, 11 Nov 2020 20:12:47 +0100
Subject: [PATCH 03/30] Snapshot 20w46a
---
.../com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
api/src/main/java/com/velocitypowered/api/proxy/Player.java | 4 +++-
.../proxy/connection/client/ConnectedPlayer.java | 5 -----
3 files changed, 4 insertions(+), 7 deletions(-)
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 67cd49963..aaa04f9a7 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 5, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
+ MINECRAFT_1_17(-1, 6, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
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 1a09ae3ca..4635c74fa 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java
@@ -226,7 +226,9 @@ public interface Player extends CommandSource, Identified, InboundConnection,
* @param url the URL for the resource pack
* @param hash the SHA-1 hash value for the resource pack
*/
- void sendResourcePack(String url, byte[] hash);
+ default void sendResourcePack(String url, byte[] hash) {
+ sendResourcePack(url, hash, false);
+ }
/**
* Note that this method does not send a plugin message to the server the player
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 9d6e98eac..602c002c1 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
@@ -891,11 +891,6 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
}
}
- @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
From b588bfe448fdd635b21881b34cd6bf419bcb5e8d Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Wed, 25 Nov 2020 18:34:45 +0100
Subject: [PATCH 04/30] Snapshot 20w48a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 aaa04f9a7..183dfbf4c 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 6, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
+ MINECRAFT_1_17(-1, 7, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
private static final int SNAPSHOT_BIT = 30;
From 040cc29c34adf5bbb19ceb6cb5f70d94d8847f8e Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Wed, 2 Dec 2020 20:39:34 +0100
Subject: [PATCH 05/30] Snapshot 20w49a
---
.../api/network/ProtocolVersion.java | 2 +-
.../connection/registry/DimensionData.java | 35 ++++++++++++++--
.../proxy/protocol/StateRegistry.java | 40 +++++++++++++------
3 files changed, 60 insertions(+), 17 deletions(-)
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 183dfbf4c..d60192074 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 7, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
+ MINECRAFT_1_17(-1, 8, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
private static final int SNAPSHOT_BIT = 30;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionData.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionData.java
index 406bce93a..7640d331f 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionData.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionData.java
@@ -43,6 +43,8 @@ public final class DimensionData {
private final @Nullable Boolean createDragonFight;
private final @Nullable Double coordinateScale;
private final @Nullable String effects;
+ private final @Nullable Integer minY; // Required and added by 1.17
+ private final @Nullable Integer height; // Required and added by 1.17
/**
* Initializes a new {@link DimensionData} instance.
@@ -64,6 +66,8 @@ public final class DimensionData {
* @param createDragonFight optional. Internal flag used in the end dimension
* @param coordinateScale optional, unknown purpose
* @param effects optional, unknown purpose
+ * @param minY the world effective lowest build-level
+ * @param height the world height above zero
*/
public DimensionData(String registryIdentifier,
@Nullable Integer dimensionId,
@@ -75,7 +79,8 @@ public final class DimensionData {
int logicalHeight, String burningBehaviourIdentifier,
@Nullable Long fixedTime, @Nullable Boolean createDragonFight,
@Nullable Double coordinateScale,
- @Nullable String effects) {
+ @Nullable String effects,
+ @Nullable Integer minY, @Nullable Integer height) {
Preconditions.checkNotNull(
registryIdentifier, "registryIdentifier cannot be null");
Preconditions.checkArgument(registryIdentifier.length() > 0,
@@ -103,6 +108,8 @@ public final class DimensionData {
this.createDragonFight = createDragonFight;
this.coordinateScale = coordinateScale;
this.effects = effects;
+ this.minY = minY;
+ this.height = height;
}
public String getRegistryIdentifier() {
@@ -173,6 +180,14 @@ public final class DimensionData {
return coordinateScale;
}
+ public @Nullable Integer getMinY() {
+ return minY;
+ }
+
+ public @Nullable Integer getHeight() {
+ return height;
+ }
+
/**
* Returns a fresh {@link DimensionData} with the specified {@code registryIdentifier}
* and {@code dimensionId}.
@@ -186,7 +201,7 @@ public final class DimensionData {
return new DimensionData(registryIdentifier, dimensionId, isNatural, ambientLight, isShrunk,
isUltrawarm, hasCeiling, hasSkylight, isPiglinSafe, doBedsWork, doRespawnAnchorsWork,
hasRaids, logicalHeight, burningBehaviourIdentifier, fixedTime, createDragonFight,
- coordinateScale, effects);
+ coordinateScale, effects, minY, height);
}
public boolean isUnannotated() {
@@ -223,11 +238,19 @@ public final class DimensionData {
? details.getDouble("coordinate_scale") : null;
String effects = details.keySet().contains("effects") ? details.getString("effects")
: null;
+ Integer minY = details.keySet().contains("min_y") ? details.getInt("min_y") : null;
+ Integer height = details.keySet().contains("height") ? details.getInt("height") : null;
+ if (version.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) {
+ Preconditions.checkNotNull(height,
+ "DimensionData requires 'minY' to be present for this version");
+ Preconditions.checkNotNull(minY,
+ "DimensionData requires 'height' to be present for this version");
+ }
return new DimensionData(
UNKNOWN_DIMENSION_ID, null, isNatural, ambientLight, isShrunk,
isUltrawarm, hasCeiling, hasSkylight, isPiglinSafe, doBedsWork, doRespawnAnchorsWork,
hasRaids, logicalHeight, burningBehaviourIdentifier, fixedTime, hasEnderdragonFight,
- coordinateScale, effects);
+ coordinateScale, effects, minY, height);
}
/**
@@ -306,6 +329,12 @@ public final class DimensionData {
if (effects != null) {
ret.putString("effects", effects);
}
+ if (minY != null) {
+ ret.putInt("min_y", minY);
+ }
+ if (height != null) {
+ ret.putInt("height", height);
+ }
return ret.build();
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
index 87bc5d091..c3c25d91c 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
@@ -25,6 +25,7 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_15;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_2;
+import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_17;
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_9;
@@ -145,25 +146,29 @@ public enum StateRegistry {
clientbound.register(BossBar.class, BossBar::new,
map(0x0C, MINECRAFT_1_9, false),
map(0x0D, MINECRAFT_1_15, false),
- map(0x0C, MINECRAFT_1_16, false));
+ map(0x0C, MINECRAFT_1_16, false),
+ map(0x0D, MINECRAFT_1_17, false));
clientbound.register(Chat.class, Chat::new,
map(0x02, MINECRAFT_1_7_2, true),
map(0x0F, MINECRAFT_1_9, true),
map(0x0E, MINECRAFT_1_13, true),
map(0x0F, MINECRAFT_1_15, true),
- map(0x0E, MINECRAFT_1_16, true));
+ map(0x0E, MINECRAFT_1_16, true),
+ map(0x0F, MINECRAFT_1_17, true));
clientbound.register(TabCompleteResponse.class, TabCompleteResponse::new,
map(0x3A, MINECRAFT_1_7_2, false),
map(0x0E, MINECRAFT_1_9, false),
map(0x10, MINECRAFT_1_13, false),
map(0x11, MINECRAFT_1_15, false),
map(0x10, MINECRAFT_1_16, false),
- map(0x0F, MINECRAFT_1_16_2, false));
+ map(0x0F, MINECRAFT_1_16_2, false),
+ map(0x10, MINECRAFT_1_17, false));
clientbound.register(AvailableCommands.class, AvailableCommands::new,
map(0x11, MINECRAFT_1_13, false),
map(0x12, MINECRAFT_1_15, false),
map(0x11, MINECRAFT_1_16, false),
- map(0x10, MINECRAFT_1_16_2, false));
+ map(0x10, MINECRAFT_1_16_2, false),
+ map(0x11, MINECRAFT_1_17, false));
clientbound.register(PluginMessage.class, PluginMessage::new,
map(0x3F, MINECRAFT_1_7_2, false),
map(0x18, MINECRAFT_1_9, false),
@@ -171,7 +176,8 @@ public enum StateRegistry {
map(0x18, MINECRAFT_1_14, false),
map(0x19, MINECRAFT_1_15, false),
map(0x18, MINECRAFT_1_16, false),
- map(0x17, MINECRAFT_1_16_2, false));
+ map(0x17, MINECRAFT_1_16_2, false),
+ map(0x18, MINECRAFT_1_17, false));
clientbound.register(Disconnect.class, Disconnect::new,
map(0x40, MINECRAFT_1_7_2, false),
map(0x1A, MINECRAFT_1_9, false),
@@ -179,7 +185,8 @@ public enum StateRegistry {
map(0x1A, MINECRAFT_1_14, false),
map(0x1B, MINECRAFT_1_15, false),
map(0x1A, MINECRAFT_1_16, false),
- map(0x19, MINECRAFT_1_16_2, false));
+ map(0x19, MINECRAFT_1_16_2, false),
+ map(0x1A, MINECRAFT_1_17, false));
clientbound.register(KeepAlive.class, KeepAlive::new,
map(0x00, MINECRAFT_1_7_2, false),
map(0x1F, MINECRAFT_1_9, false),
@@ -187,7 +194,8 @@ public enum StateRegistry {
map(0x20, MINECRAFT_1_14, false),
map(0x21, MINECRAFT_1_15, false),
map(0x20, MINECRAFT_1_16, false),
- map(0x1F, MINECRAFT_1_16_2, false));
+ map(0x1F, MINECRAFT_1_16_2, false),
+ map(0x20, MINECRAFT_1_17, false));
clientbound.register(JoinGame.class, JoinGame::new,
map(0x01, MINECRAFT_1_7_2, false),
map(0x23, MINECRAFT_1_9, false),
@@ -195,7 +203,8 @@ public enum StateRegistry {
map(0x25, MINECRAFT_1_14, false),
map(0x26, MINECRAFT_1_15, false),
map(0x25, MINECRAFT_1_16, false),
- map(0x24, MINECRAFT_1_16_2, false));
+ map(0x24, MINECRAFT_1_16_2, false),
+ map(0x25, MINECRAFT_1_17, false));
clientbound.register(Respawn.class, Respawn::new,
map(0x07, MINECRAFT_1_7_2, true),
map(0x33, MINECRAFT_1_9, true),
@@ -205,7 +214,8 @@ public enum StateRegistry {
map(0x3A, MINECRAFT_1_14, true),
map(0x3B, MINECRAFT_1_15, true),
map(0x3A, MINECRAFT_1_16, true),
- map(0x39, MINECRAFT_1_16_2, true));
+ map(0x39, MINECRAFT_1_16_2, true),
+ map(0x3A, MINECRAFT_1_17, true));
clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new,
map(0x48, MINECRAFT_1_8, true),
map(0x32, MINECRAFT_1_9, true),
@@ -215,7 +225,8 @@ public enum StateRegistry {
map(0x39, MINECRAFT_1_14, true),
map(0x3A, MINECRAFT_1_15, true),
map(0x39, MINECRAFT_1_16, true),
- map(0x38, MINECRAFT_1_16_2, true));
+ map(0x38, MINECRAFT_1_16_2, true),
+ map(0x39, MINECRAFT_1_17, true));
clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new,
map(0x47, MINECRAFT_1_8, true),
map(0x48, MINECRAFT_1_9, true),
@@ -225,7 +236,8 @@ public enum StateRegistry {
map(0x4E, MINECRAFT_1_13, true),
map(0x53, MINECRAFT_1_14, true),
map(0x54, MINECRAFT_1_15, true),
- map(0x53, MINECRAFT_1_16, true));
+ map(0x53, MINECRAFT_1_16, true),
+ map(0x54, MINECRAFT_1_17, true));
clientbound.register(TitlePacket.class, TitlePacket::new,
map(0x45, MINECRAFT_1_8, true),
map(0x45, MINECRAFT_1_9, true),
@@ -234,7 +246,8 @@ public enum StateRegistry {
map(0x4B, MINECRAFT_1_13, true),
map(0x4F, MINECRAFT_1_14, true),
map(0x50, MINECRAFT_1_15, true),
- map(0x4F, MINECRAFT_1_16, true));
+ map(0x4F, MINECRAFT_1_16, true),
+ map(0x50, MINECRAFT_1_17, true));
clientbound.register(PlayerListItem.class, PlayerListItem::new,
map(0x38, MINECRAFT_1_7_2, false),
map(0x2D, MINECRAFT_1_9, false),
@@ -243,7 +256,8 @@ public enum StateRegistry {
map(0x33, MINECRAFT_1_14, false),
map(0x34, MINECRAFT_1_15, false),
map(0x33, MINECRAFT_1_16, false),
- map(0x32, MINECRAFT_1_16_2, false));
+ map(0x32, MINECRAFT_1_16_2, false),
+ map(0x33, MINECRAFT_1_17, false));
}
},
LOGIN {
From 76493549bf6ba8faf33bfa4bd72003075c089054 Mon Sep 17 00:00:00 2001
From: "FivePB (Xer)"
Date: Fri, 18 Dec 2020 20:06:12 +0100
Subject: [PATCH 06/30] Snapshot 20w51a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 d60192074..01b02b1be 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 8, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
+ MINECRAFT_1_17(-1, 9, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
private static final int SNAPSHOT_BIT = 30;
From f0d9a445ed1421d9d38ef5bb6785c6b60a5252af Mon Sep 17 00:00:00 2001
From: FivePB
Date: Wed, 20 Jan 2021 20:13:56 +0100
Subject: [PATCH 07/30] Snapshot 21w03a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
api/src/main/java/com/velocitypowered/api/proxy/Player.java | 4 +++-
.../proxy/connection/registry/DimensionData.java | 4 ++--
3 files changed, 6 insertions(+), 4 deletions(-)
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 01b02b1be..7f6ee7fe5 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 9, "1.17"); // Note: Indev as of 20w45a (754, borked by Mojang)
+ MINECRAFT_1_17(-1, 11, "1.17"); // Snapshot: 21w03a, future protocol: 755
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 4635c74fa..5fb68d4c9 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java
@@ -252,8 +252,10 @@ public interface Player extends CommandSource, Identified, InboundConnection,
*
* @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+
+ * @param isRequired Only in 1.17+ or newer: If true shows the pack as required to play,
+ * and removes the decline option. Declining it anyway will disconnect the user.
*/
void sendResourcePack(String url, byte[] hash, boolean isRequired);
}
+
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionData.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionData.java
index 7640d331f..07b69baef 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionData.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/registry/DimensionData.java
@@ -242,9 +242,9 @@ public final class DimensionData {
Integer height = details.keySet().contains("height") ? details.getInt("height") : null;
if (version.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) {
Preconditions.checkNotNull(height,
- "DimensionData requires 'minY' to be present for this version");
- Preconditions.checkNotNull(minY,
"DimensionData requires 'height' to be present for this version");
+ Preconditions.checkNotNull(minY,
+ "DimensionData requires 'minY' to be present for this version");
}
return new DimensionData(
UNKNOWN_DIMENSION_ID, null, isNatural, ambientLight, isShrunk,
From 7ea7e775647992215fe8db8b5f99227327d5b6fe Mon Sep 17 00:00:00 2001
From: "FivePB (Xer)"
Date: Wed, 3 Feb 2021 23:49:49 +0100
Subject: [PATCH 08/30] Snapshot 21w05a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 7f6ee7fe5..ce3f4d8c9 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 11, "1.17"); // Snapshot: 21w03a, future protocol: 755
+ MINECRAFT_1_17(-1, 12, "1.17"); // Snapshot: 21w05a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 03327c2677be75fb0a0970f9ee8cad24c34e6292 Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Fri, 5 Feb 2021 08:05:46 +0100
Subject: [PATCH 09/30] Snapshot 21w05b
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 ce3f4d8c9..96c16cec0 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 12, "1.17"); // Snapshot: 21w05a, future protocol: 755
+ MINECRAFT_1_17(-1, 13, "1.17"); // Snapshot: 21w05b, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From c9e92bcc53a239c5ec9061c0209f6f1e072ac5f4 Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Wed, 10 Feb 2021 19:58:46 +0100
Subject: [PATCH 10/30] Snapshot 21w06a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 96c16cec0..e09ac5519 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 13, "1.17"); // Snapshot: 21w05b, future protocol: 755
+ MINECRAFT_1_17(-1, 14, "1.17"); // Snapshot: 21w06a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From b19cf16345c30d03aeed4f96fe3cd249566486e3 Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Thu, 18 Feb 2021 22:02:26 +0100
Subject: [PATCH 11/30] Snapshot 21w07a
---
.../api/network/ProtocolVersion.java | 2 +-
.../client/ClientSettingsWrapper.java | 2 +-
.../proxy/protocol/packet/ClientSettings.java | 20 ++++++++++++++++++-
3 files changed, 21 insertions(+), 3 deletions(-)
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 e09ac5519..8637d76b0 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 14, "1.17"); // Snapshot: 21w06a, future protocol: 755
+ MINECRAFT_1_17(-1, 15, "1.17"); // Snapshot: 21w07a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientSettingsWrapper.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientSettingsWrapper.java
index b268ee19c..38942fa16 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientSettingsWrapper.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientSettingsWrapper.java
@@ -26,7 +26,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public class ClientSettingsWrapper implements PlayerSettings {
static final PlayerSettings DEFAULT = new ClientSettingsWrapper(
- new ClientSettings("en_US", (byte) 10, 0, true, (short) 127, 1));
+ new ClientSettings("en_US", (byte) 10, 0, true, (short) 127, 1, true));
private final ClientSettings settings;
private final SkinParts parts;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientSettings.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientSettings.java
index a2d7e32bc..ef3818c99 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientSettings.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ClientSettings.java
@@ -33,12 +33,13 @@ public class ClientSettings implements MinecraftPacket {
private byte difficulty; // 1.7 Protocol
private short skinParts;
private int mainHand;
+ private boolean chatFilteringEnabled; // Added in 1.17
public ClientSettings() {
}
public ClientSettings(String locale, byte viewDistance, int chatVisibility, boolean chatColors,
- short skinParts, int mainHand) {
+ short skinParts, int mainHand, boolean chatFilteringEnabled) {
this.locale = locale;
this.viewDistance = viewDistance;
this.chatVisibility = chatVisibility;
@@ -98,6 +99,14 @@ public class ClientSettings implements MinecraftPacket {
this.mainHand = mainHand;
}
+ public boolean isChatFilteringEnabled() {
+ return chatFilteringEnabled;
+ }
+
+ public void setChatFilteringEnabled(boolean chatFilteringEnabled) {
+ this.chatFilteringEnabled = chatFilteringEnabled;
+ }
+
@Override
public String toString() {
return "ClientSettings{"
@@ -107,6 +116,7 @@ public class ClientSettings implements MinecraftPacket {
+ ", chatColors=" + chatColors
+ ", skinParts=" + skinParts
+ ", mainHand=" + mainHand
+ + ", chatFilteringEnabled=" + chatFilteringEnabled
+ '}';
}
@@ -125,6 +135,10 @@ public class ClientSettings implements MinecraftPacket {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_9) >= 0) {
this.mainHand = ProtocolUtils.readVarInt(buf);
+
+ if (version.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) {
+ this.chatFilteringEnabled = buf.readBoolean();
+ }
}
}
@@ -146,6 +160,10 @@ public class ClientSettings implements MinecraftPacket {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_9) >= 0) {
ProtocolUtils.writeVarInt(buf, mainHand);
+
+ if (version.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) {
+ buf.writeBoolean(chatFilteringEnabled);
+ }
}
}
From 22bc7590446d292800b7012c1592008cd42774bc Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Thu, 25 Feb 2021 14:42:23 +0100
Subject: [PATCH 12/30] Snapshot 21w08a
---
.../api/network/ProtocolVersion.java | 2 +-
.../connection/MinecraftSessionHandler.java | 29 ++-
.../client/ClientPlaySessionHandler.java | 5 +-
.../connection/client/ConnectedPlayer.java | 47 +++--
.../proxy/protocol/StateRegistry.java | 78 ++++++--
.../proxy/protocol/packet/TitlePacket.java | 174 ------------------
.../packet/title/GenericTitlePacket.java | 136 ++++++++++++++
.../packet/title/LegacyTitlePacket.java | 124 +++++++++++++
.../packet/title/TitleActionbarPacket.java | 59 ++++++
.../packet/title/TitleClearPacket.java | 57 ++++++
.../packet/title/TitleSubtitlePacket.java | 59 ++++++
.../packet/title/TitleTextPacket.java | 59 ++++++
.../packet/title/TitleTimesPacket.java | 85 +++++++++
.../proxy/protocol/PacketRegistryTest.java | 42 +++--
14 files changed, 726 insertions(+), 230 deletions(-)
delete mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TitlePacket.java
create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/GenericTitlePacket.java
create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/LegacyTitlePacket.java
create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleActionbarPacket.java
create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java
create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleSubtitlePacket.java
create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTextPacket.java
create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTimesPacket.java
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 8637d76b0..0149970e6 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 15, "1.17"); // Snapshot: 21w07a, future protocol: 755
+ MINECRAFT_1_17(-1, 16, "1.17"); // Snapshot: 21w08a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/MinecraftSessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/MinecraftSessionHandler.java
index 3dcb3807a..e72f42d64 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/MinecraftSessionHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/MinecraftSessionHandler.java
@@ -46,7 +46,12 @@ import com.velocitypowered.proxy.protocol.packet.StatusRequest;
import com.velocitypowered.proxy.protocol.packet.StatusResponse;
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequest;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse;
-import com.velocitypowered.proxy.protocol.packet.TitlePacket;
+import com.velocitypowered.proxy.protocol.packet.title.LegacyTitlePacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleActionbarPacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleClearPacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleSubtitlePacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleTextPacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleTimesPacket;
import io.netty.buffer.ByteBuf;
public interface MinecraftSessionHandler {
@@ -191,7 +196,27 @@ public interface MinecraftSessionHandler {
return false;
}
- default boolean handle(TitlePacket packet) {
+ default boolean handle(LegacyTitlePacket packet) {
+ return false;
+ }
+
+ default boolean handle(TitleTextPacket packet) {
+ return false;
+ }
+
+ default boolean handle(TitleSubtitlePacket packet) {
+ return false;
+ }
+
+ default boolean handle(TitleActionbarPacket packet) {
+ return false;
+ }
+
+ default boolean handle(TitleTimesPacket packet) {
+ return false;
+ }
+
+ default boolean handle(TitleClearPacket packet) {
return false;
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
index 8ac397500..0c2b402eb 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
@@ -53,7 +53,7 @@ import com.velocitypowered.proxy.protocol.packet.Respawn;
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequest;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse.Offer;
-import com.velocitypowered.proxy.protocol.packet.TitlePacket;
+import com.velocitypowered.proxy.protocol.packet.title.GenericTitlePacket;
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
@@ -400,7 +400,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
// Clear any title from the previous server.
if (player.getProtocolVersion().compareTo(MINECRAFT_1_8) >= 0) {
player.getConnection()
- .delayedWrite(TitlePacket.resetForProtocolVersion(player.getProtocolVersion()));
+ .delayedWrite(GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.RESET, player.getProtocolVersion()));
}
// Flush everything
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 602c002c1..1a1a0d444 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
@@ -66,7 +66,7 @@ import com.velocitypowered.proxy.protocol.packet.HeaderAndFooter;
import com.velocitypowered.proxy.protocol.packet.KeepAlive;
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
-import com.velocitypowered.proxy.protocol.packet.TitlePacket;
+import com.velocitypowered.proxy.protocol.packet.title.GenericTitlePacket;
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import com.velocitypowered.proxy.server.VelocityRegisteredServer;
import com.velocitypowered.proxy.tablist.VelocityTabList;
@@ -262,8 +262,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
if (position == MessagePosition.ACTION_BAR) {
if (getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0) {
// We can use the title packet instead.
- TitlePacket pkt = new TitlePacket();
- pkt.setAction(TitlePacket.SET_ACTION_BAR);
+ GenericTitlePacket pkt = GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.SET_ACTION_BAR, this.getProtocolVersion());
pkt.setComponent(net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE
.serialize(component));
connection.write(pkt);
@@ -307,8 +307,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
ProtocolVersion playerVersion = getProtocolVersion();
if (playerVersion.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0) {
// Use the title packet instead.
- TitlePacket pkt = new TitlePacket();
- pkt.setAction(TitlePacket.SET_ACTION_BAR);
+ GenericTitlePacket pkt = GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.SET_ACTION_BAR, playerVersion);
pkt.setComponent(ProtocolUtils.getJsonChatSerializer(playerVersion)
.serialize(message));
connection.write(pkt);
@@ -359,17 +359,18 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
GsonComponentSerializer serializer = ProtocolUtils.getJsonChatSerializer(this
.getProtocolVersion());
- TitlePacket titlePkt = new TitlePacket();
- titlePkt.setAction(TitlePacket.SET_TITLE);
+ GenericTitlePacket titlePkt = GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.SET_TITLE, this.getProtocolVersion());
titlePkt.setComponent(serializer.serialize(title.title()));
connection.delayedWrite(titlePkt);
- TitlePacket subtitlePkt = new TitlePacket();
- subtitlePkt.setAction(TitlePacket.SET_SUBTITLE);
+ GenericTitlePacket subtitlePkt = GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.SET_SUBTITLE, this.getProtocolVersion());
subtitlePkt.setComponent(serializer.serialize(title.subtitle()));
connection.delayedWrite(subtitlePkt);
- TitlePacket timesPkt = TitlePacket.timesForProtocolVersion(this.getProtocolVersion());
+ GenericTitlePacket timesPkt = GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.SET_TIMES, this.getProtocolVersion());
net.kyori.adventure.title.Title.Times times = title.times();
if (times != null) {
timesPkt.setFadeIn((int) DurationUtils.toTicks(times.fadeIn()));
@@ -385,14 +386,16 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
@Override
public void clearTitle() {
if (this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
- connection.write(TitlePacket.hideForProtocolVersion(this.getProtocolVersion()));
+ connection.write(GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.HIDE, this.getProtocolVersion()));
}
}
@Override
public void resetTitle() {
if (this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
- connection.write(TitlePacket.resetForProtocolVersion(this.getProtocolVersion()));
+ connection.write(GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.RESET, this.getProtocolVersion()));
}
}
@@ -487,20 +490,23 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
ProtocolVersion protocolVersion = connection.getProtocolVersion();
if (title.equals(Titles.reset())) {
- connection.write(TitlePacket.resetForProtocolVersion(protocolVersion));
+ connection.write(GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.RESET, protocolVersion));
} else if (title.equals(Titles.hide())) {
- connection.write(TitlePacket.hideForProtocolVersion(protocolVersion));
+ connection.write(GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.HIDE, protocolVersion));
} else if (title instanceof TextTitle) {
TextTitle tt = (TextTitle) title;
if (tt.isResetBeforeSend()) {
- connection.delayedWrite(TitlePacket.resetForProtocolVersion(protocolVersion));
+ connection.delayedWrite(GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.RESET, protocolVersion));
}
Optional titleText = tt.getTitle();
if (titleText.isPresent()) {
- TitlePacket titlePkt = new TitlePacket();
- titlePkt.setAction(TitlePacket.SET_TITLE);
+ GenericTitlePacket titlePkt = GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.SET_TITLE, protocolVersion);
titlePkt.setComponent(net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE
.serialize(titleText.get()));
connection.delayedWrite(titlePkt);
@@ -508,15 +514,16 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
Optional subtitleText = tt.getSubtitle();
if (subtitleText.isPresent()) {
- TitlePacket titlePkt = new TitlePacket();
- titlePkt.setAction(TitlePacket.SET_SUBTITLE);
+ GenericTitlePacket titlePkt = GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.SET_SUBTITLE, protocolVersion);
titlePkt.setComponent(net.kyori.text.serializer.gson.GsonComponentSerializer.INSTANCE
.serialize(subtitleText.get()));
connection.delayedWrite(titlePkt);
}
if (tt.areTimesSet()) {
- TitlePacket timesPkt = TitlePacket.timesForProtocolVersion(protocolVersion);
+ GenericTitlePacket timesPkt = GenericTitlePacket.constructTitlePacket(
+ GenericTitlePacket.ActionType.SET_TIMES, protocolVersion);
timesPkt.setFadeIn(tt.getFadeIn());
timesPkt.setStay(tt.getStay());
timesPkt.setFadeOut(tt.getFadeOut());
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
index c3c25d91c..6baa55046 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
@@ -25,6 +25,7 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_15;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_2;
+import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_4;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_17;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_7_2;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
@@ -61,7 +62,12 @@ import com.velocitypowered.proxy.protocol.packet.StatusRequest;
import com.velocitypowered.proxy.protocol.packet.StatusResponse;
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequest;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse;
-import com.velocitypowered.proxy.protocol.packet.TitlePacket;
+import com.velocitypowered.proxy.protocol.packet.title.LegacyTitlePacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleActionbarPacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleClearPacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleSubtitlePacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleTextPacket;
+import com.velocitypowered.proxy.protocol.packet.title.TitleTimesPacket;
import io.netty.util.collection.IntObjectHashMap;
import io.netty.util.collection.IntObjectMap;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
@@ -162,13 +168,13 @@ public enum StateRegistry {
map(0x11, MINECRAFT_1_15, false),
map(0x10, MINECRAFT_1_16, false),
map(0x0F, MINECRAFT_1_16_2, false),
- map(0x10, MINECRAFT_1_17, false));
+ map(0x11, MINECRAFT_1_17, false));
clientbound.register(AvailableCommands.class, AvailableCommands::new,
map(0x11, MINECRAFT_1_13, false),
map(0x12, MINECRAFT_1_15, false),
map(0x11, MINECRAFT_1_16, false),
map(0x10, MINECRAFT_1_16_2, false),
- map(0x11, MINECRAFT_1_17, false));
+ map(0x12, MINECRAFT_1_17, false));
clientbound.register(PluginMessage.class, PluginMessage::new,
map(0x3F, MINECRAFT_1_7_2, false),
map(0x18, MINECRAFT_1_9, false),
@@ -177,7 +183,7 @@ public enum StateRegistry {
map(0x19, MINECRAFT_1_15, false),
map(0x18, MINECRAFT_1_16, false),
map(0x17, MINECRAFT_1_16_2, false),
- map(0x18, MINECRAFT_1_17, false));
+ map(0x19, MINECRAFT_1_17, false));
clientbound.register(Disconnect.class, Disconnect::new,
map(0x40, MINECRAFT_1_7_2, false),
map(0x1A, MINECRAFT_1_9, false),
@@ -186,7 +192,7 @@ public enum StateRegistry {
map(0x1B, MINECRAFT_1_15, false),
map(0x1A, MINECRAFT_1_16, false),
map(0x19, MINECRAFT_1_16_2, false),
- map(0x1A, MINECRAFT_1_17, false));
+ map(0x1B, MINECRAFT_1_17, false));
clientbound.register(KeepAlive.class, KeepAlive::new,
map(0x00, MINECRAFT_1_7_2, false),
map(0x1F, MINECRAFT_1_9, false),
@@ -195,7 +201,7 @@ public enum StateRegistry {
map(0x21, MINECRAFT_1_15, false),
map(0x20, MINECRAFT_1_16, false),
map(0x1F, MINECRAFT_1_16_2, false),
- map(0x20, MINECRAFT_1_17, false));
+ map(0x22, MINECRAFT_1_17, false));
clientbound.register(JoinGame.class, JoinGame::new,
map(0x01, MINECRAFT_1_7_2, false),
map(0x23, MINECRAFT_1_9, false),
@@ -204,7 +210,7 @@ public enum StateRegistry {
map(0x26, MINECRAFT_1_15, false),
map(0x25, MINECRAFT_1_16, false),
map(0x24, MINECRAFT_1_16_2, false),
- map(0x25, MINECRAFT_1_17, false));
+ map(0x27, MINECRAFT_1_17, false));
clientbound.register(Respawn.class, Respawn::new,
map(0x07, MINECRAFT_1_7_2, true),
map(0x33, MINECRAFT_1_9, true),
@@ -215,7 +221,7 @@ public enum StateRegistry {
map(0x3B, MINECRAFT_1_15, true),
map(0x3A, MINECRAFT_1_16, true),
map(0x39, MINECRAFT_1_16_2, true),
- map(0x3A, MINECRAFT_1_17, true));
+ map(0x3D, MINECRAFT_1_17, true));
clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new,
map(0x48, MINECRAFT_1_8, true),
map(0x32, MINECRAFT_1_9, true),
@@ -226,7 +232,7 @@ public enum StateRegistry {
map(0x3A, MINECRAFT_1_15, true),
map(0x39, MINECRAFT_1_16, true),
map(0x38, MINECRAFT_1_16_2, true),
- map(0x39, MINECRAFT_1_17, true));
+ map(0x3C, MINECRAFT_1_17, true));
clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new,
map(0x47, MINECRAFT_1_8, true),
map(0x48, MINECRAFT_1_9, true),
@@ -237,8 +243,8 @@ public enum StateRegistry {
map(0x53, MINECRAFT_1_14, true),
map(0x54, MINECRAFT_1_15, true),
map(0x53, MINECRAFT_1_16, true),
- map(0x54, MINECRAFT_1_17, true));
- clientbound.register(TitlePacket.class, TitlePacket::new,
+ map(0x5E, MINECRAFT_1_17, true));
+ clientbound.register(LegacyTitlePacket.class, LegacyTitlePacket::new,
map(0x45, MINECRAFT_1_8, true),
map(0x45, MINECRAFT_1_9, true),
map(0x47, MINECRAFT_1_12, true),
@@ -246,8 +252,17 @@ public enum StateRegistry {
map(0x4B, MINECRAFT_1_13, true),
map(0x4F, MINECRAFT_1_14, true),
map(0x50, MINECRAFT_1_15, true),
- map(0x4F, MINECRAFT_1_16, true),
- map(0x50, MINECRAFT_1_17, true));
+ map(0x4F, MINECRAFT_1_16, MINECRAFT_1_16_4, true));
+ clientbound.register(TitleSubtitlePacket.class, TitleSubtitlePacket::new, // TODO: fix
+ map(0x57, MINECRAFT_1_17, true));
+ clientbound.register(TitleTextPacket.class, TitleTextPacket::new, // TODO: fix
+ map(0x5A, MINECRAFT_1_17, true));
+ clientbound.register(TitleActionbarPacket.class, TitleActionbarPacket::new, // TODO: fix
+ map(0x41, MINECRAFT_1_17, true));
+ clientbound.register(TitleTimesPacket.class, TitleTimesPacket::new, // TODO: fix
+ map(0x59, MINECRAFT_1_17, true));
+ clientbound.register(TitleClearPacket.class, TitleClearPacket::new, // TODO: fix
+ map(0x10, MINECRAFT_1_17, true));
clientbound.register(PlayerListItem.class, PlayerListItem::new,
map(0x38, MINECRAFT_1_7_2, false),
map(0x2D, MINECRAFT_1_9, false),
@@ -257,7 +272,7 @@ public enum StateRegistry {
map(0x34, MINECRAFT_1_15, false),
map(0x33, MINECRAFT_1_16, false),
map(0x32, MINECRAFT_1_16_2, false),
- map(0x33, MINECRAFT_1_17, false));
+ map(0x36, MINECRAFT_1_17, false));
}
},
LOGIN {
@@ -325,8 +340,20 @@ public enum StateRegistry {
for (int i = 0; i < mappings.length; i++) {
PacketMapping current = mappings[i];
PacketMapping next = (i + 1 < mappings.length) ? mappings[i + 1] : current;
+
ProtocolVersion from = current.protocolVersion;
- ProtocolVersion to = current == next ? getLast(SUPPORTED_VERSIONS) : next.protocolVersion;
+ ProtocolVersion lastValid = current.lastValidProtocolVersion;
+ if (lastValid != null) {
+ if (next != current) {
+ throw new IllegalArgumentException("Cannot add a mapping after last valid mapping");
+ }
+ if (from.compareTo(lastValid) > 0) {
+ throw new IllegalArgumentException(
+ "Last mapping version cannot be higher than highest mapping version");
+ }
+ }
+ ProtocolVersion to = current == next ? lastValid != null
+ ? lastValid : getLast(SUPPORTED_VERSIONS) : next.protocolVersion;
if (from.compareTo(to) >= 0 && from != getLast(SUPPORTED_VERSIONS)) {
throw new IllegalArgumentException(String.format(
@@ -414,10 +441,13 @@ public enum StateRegistry {
private final int id;
private final ProtocolVersion protocolVersion;
private final boolean encodeOnly;
+ private final @Nullable ProtocolVersion lastValidProtocolVersion;
- PacketMapping(int id, ProtocolVersion protocolVersion, boolean packetDecoding) {
+ PacketMapping(int id, ProtocolVersion protocolVersion,
+ ProtocolVersion lastValidProtocolVersion, boolean packetDecoding) {
this.id = id;
this.protocolVersion = protocolVersion;
+ this.lastValidProtocolVersion = lastValidProtocolVersion;
this.encodeOnly = packetDecoding;
}
@@ -459,7 +489,21 @@ public enum StateRegistry {
* @return PacketMapping with the provided arguments
*/
private static PacketMapping map(int id, ProtocolVersion version, boolean encodeOnly) {
- return new PacketMapping(id, version, encodeOnly);
+ return map(id, version, null, encodeOnly);
+ }
+
+ /**
+ * Creates a PacketMapping using the provided arguments.
+ *
+ * @param id Packet Id
+ * @param version Protocol version
+ * @param encodeOnly When true packet decoding will be disabled
+ * @param lastValidProtocolVersion Last version this Mapping is valid at
+ * @return PacketMapping with the provided arguments
+ */
+ private static PacketMapping map(int id, ProtocolVersion version,
+ ProtocolVersion lastValidProtocolVersion, boolean encodeOnly) {
+ return new PacketMapping(id, version, lastValidProtocolVersion, encodeOnly);
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TitlePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TitlePacket.java
deleted file mode 100644
index 49fe876df..000000000
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/TitlePacket.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2018 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 .
- */
-
-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 io.netty.buffer.ByteBuf;
-import org.checkerframework.checker.nullness.qual.Nullable;
-
-public class TitlePacket implements MinecraftPacket {
-
- public static final int SET_TITLE = 0;
- public static final int SET_SUBTITLE = 1;
- public static final int SET_ACTION_BAR = 2;
- public static final int SET_TIMES = 3;
- public static final int SET_TIMES_OLD = 2;
- public static final int HIDE = 4;
- public static final int HIDE_OLD = 3;
- public static final int RESET = 5;
- public static final int RESET_OLD = 4;
-
- private int action;
- private @Nullable String component;
- private int fadeIn;
- private int stay;
- private int fadeOut;
-
- @Override
- public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
- throw new UnsupportedOperationException(); // encode only
- }
-
- @Override
- public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
- ProtocolUtils.writeVarInt(buf, action);
- if (version.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0) {
- // 1.11+ shifted the action enum by 1 to handle the action bar
- switch (action) {
- case SET_TITLE:
- case SET_SUBTITLE:
- case SET_ACTION_BAR:
- if (component == null) {
- throw new IllegalStateException("No component found for " + action);
- }
- ProtocolUtils.writeString(buf, component);
- break;
- case SET_TIMES:
- buf.writeInt(fadeIn);
- buf.writeInt(stay);
- buf.writeInt(fadeOut);
- break;
- case HIDE:
- case RESET:
- break;
- default:
- throw new UnsupportedOperationException("Unknown action " + action);
- }
- } else {
- switch (action) {
- case SET_TITLE:
- case SET_SUBTITLE:
- if (component == null) {
- throw new IllegalStateException("No component found for " + action);
- }
- ProtocolUtils.writeString(buf, component);
- break;
- case SET_TIMES_OLD:
- buf.writeInt(fadeIn);
- buf.writeInt(stay);
- buf.writeInt(fadeOut);
- break;
- case HIDE_OLD:
- case RESET_OLD:
- break;
- default:
- throw new UnsupportedOperationException("Unknown action " + action);
- }
- }
- }
-
- public int getAction() {
- return action;
- }
-
- public void setAction(int action) {
- this.action = action;
- }
-
- public @Nullable String getComponent() {
- return component;
- }
-
- public void setComponent(@Nullable String component) {
- this.component = component;
- }
-
- public int getFadeIn() {
- return fadeIn;
- }
-
- public void setFadeIn(int fadeIn) {
- this.fadeIn = fadeIn;
- }
-
- public int getStay() {
- return stay;
- }
-
- public void setStay(int stay) {
- this.stay = stay;
- }
-
- public int getFadeOut() {
- return fadeOut;
- }
-
- public void setFadeOut(int fadeOut) {
- this.fadeOut = fadeOut;
- }
-
- public static TitlePacket hideForProtocolVersion(ProtocolVersion version) {
- TitlePacket packet = new TitlePacket();
- packet.setAction(version.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0 ? TitlePacket.HIDE
- : TitlePacket.HIDE_OLD);
- return packet;
- }
-
- public static TitlePacket resetForProtocolVersion(ProtocolVersion version) {
- TitlePacket packet = new TitlePacket();
- packet.setAction(version.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0 ? TitlePacket.RESET
- : TitlePacket.RESET_OLD);
- return packet;
- }
-
- public static TitlePacket timesForProtocolVersion(ProtocolVersion version) {
- TitlePacket packet = new TitlePacket();
- packet.setAction(version.compareTo(ProtocolVersion.MINECRAFT_1_11) >= 0 ? TitlePacket.SET_TIMES
- : TitlePacket.SET_TIMES_OLD);
- return packet;
- }
-
- @Override
- public String toString() {
- return "TitlePacket{"
- + "action=" + action
- + ", component='" + component + '\''
- + ", fadeIn=" + fadeIn
- + ", stay=" + stay
- + ", fadeOut=" + fadeOut
- + '}';
- }
-
- @Override
- public boolean handle(MinecraftSessionHandler handler) {
- return handler.handle(this);
- }
-}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/GenericTitlePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/GenericTitlePacket.java
new file mode 100644
index 000000000..38c890c03
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/GenericTitlePacket.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2018 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 .
+ */
+
+package com.velocitypowered.proxy.protocol.packet.title;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import com.velocitypowered.proxy.protocol.MinecraftPacket;
+import com.velocitypowered.proxy.protocol.ProtocolUtils;
+import io.netty.buffer.ByteBuf;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public abstract class GenericTitlePacket implements MinecraftPacket {
+
+ public enum ActionType {
+ SET_TITLE(0),
+ SET_SUBTITLE(1),
+ SET_ACTION_BAR(2),
+ SET_TIMES(3),
+ HIDE(4),
+ RESET(5);
+
+ private final int action;
+
+ ActionType(int action) {
+ this.action = action;
+ }
+
+ public int getAction(ProtocolVersion version) {
+ return version.compareTo(ProtocolVersion.MINECRAFT_1_11) < 0
+ ? action > 2 ? action - 1 : action : action;
+ }
+ }
+
+
+ private ActionType action;
+
+ protected void setAction(ActionType action) {
+ this.action = action;
+ }
+
+ public final ActionType getAction() {
+ return action;
+ }
+
+ public String getComponent() {
+ throw new UnsupportedOperationException("Invalid function for this TitlePacket ActionType");
+ }
+
+ public void setComponent(String component) {
+ throw new UnsupportedOperationException("Invalid function for this TitlePacket ActionType");
+ }
+
+ public int getFadeIn() {
+ throw new UnsupportedOperationException("Invalid function for this TitlePacket ActionType");
+ }
+
+ public void setFadeIn(int fadeIn) {
+ throw new UnsupportedOperationException("Invalid function for this TitlePacket ActionType");
+ }
+
+ public int getStay() {
+ throw new UnsupportedOperationException("Invalid function for this TitlePacket ActionType");
+ }
+
+ public void setStay(int stay) {
+ throw new UnsupportedOperationException("Invalid function for this TitlePacket ActionType");
+ }
+
+ public int getFadeOut() {
+ throw new UnsupportedOperationException("Invalid function for this TitlePacket ActionType");
+ }
+
+ public void setFadeOut(int fadeOut) {
+ throw new UnsupportedOperationException("Invalid function for this TitlePacket ActionType");
+ }
+
+
+
+ @Override
+ public final void decode(ByteBuf buf, ProtocolUtils.Direction direction,
+ ProtocolVersion version) {
+ throw new UnsupportedOperationException(); // encode only
+ }
+
+ /**
+ * Creates a version and type dependent TitlePacket.
+ *
+ * @param type Action the packet should invoke
+ * @param version Protocol version of the target player
+ * @return GenericTitlePacket instance that follows the invoker type/version
+ */
+ public static GenericTitlePacket constructTitlePacket(ActionType type, ProtocolVersion version) {
+ GenericTitlePacket packet = null;
+ if (version.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) {
+ switch (type) {
+ case SET_ACTION_BAR:
+ packet = new TitleActionbarPacket();
+ break;
+ case SET_SUBTITLE:
+ packet = new TitleSubtitlePacket();
+ break;
+ case SET_TIMES:
+ packet = new TitleTimesPacket();
+ break;
+ case SET_TITLE:
+ packet = new TitleTextPacket();
+ break;
+ case HIDE:
+ case RESET:
+ packet = new TitleClearPacket();
+ break;
+ default:
+ throw new IllegalArgumentException("Invalid ActionType");
+ }
+ } else {
+ packet = new LegacyTitlePacket();
+ }
+ packet.setAction(type);
+ return packet;
+ }
+
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/LegacyTitlePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/LegacyTitlePacket.java
new file mode 100644
index 000000000..7b25325e6
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/LegacyTitlePacket.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2018 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 .
+ */
+
+package com.velocitypowered.proxy.protocol.packet.title;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
+import com.velocitypowered.proxy.protocol.ProtocolUtils;
+import io.netty.buffer.ByteBuf;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public class LegacyTitlePacket extends GenericTitlePacket {
+
+ private @Nullable String component;
+ private int fadeIn;
+ private int stay;
+ private int fadeOut;
+
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
+ if (version.compareTo(ProtocolVersion.MINECRAFT_1_11) < 0
+ && getAction() == ActionType.SET_ACTION_BAR) {
+ throw new IllegalStateException("Action bars are only supported on 1.11 and newer");
+ }
+ ProtocolUtils.writeVarInt(buf, getAction().getAction(version));
+
+ switch (getAction()) {
+ case SET_TITLE:
+ case SET_SUBTITLE:
+ case SET_ACTION_BAR:
+ if (component == null) {
+ throw new IllegalStateException("No component found for " + getAction());
+ }
+ ProtocolUtils.writeString(buf, component);
+ break;
+ case SET_TIMES:
+ buf.writeInt(fadeIn);
+ buf.writeInt(stay);
+ buf.writeInt(fadeOut);
+ break;
+ case HIDE:
+ case RESET:
+ break;
+ default:
+ throw new UnsupportedOperationException("Unknown action " + getAction());
+ }
+
+ }
+
+ @Override
+ public void setAction(ActionType action) {
+ super.setAction(action);
+ }
+
+ @Override
+ public @Nullable String getComponent() {
+ return component;
+ }
+
+ @Override
+ public void setComponent(@Nullable String component) {
+ this.component = component;
+ }
+
+ @Override
+ public int getFadeIn() {
+ return fadeIn;
+ }
+
+ @Override
+ public void setFadeIn(int fadeIn) {
+ this.fadeIn = fadeIn;
+ }
+
+ @Override
+ public int getStay() {
+ return stay;
+ }
+
+ @Override
+ public void setStay(int stay) {
+ this.stay = stay;
+ }
+
+ @Override
+ public int getFadeOut() {
+ return fadeOut;
+ }
+
+ @Override
+ public void setFadeOut(int fadeOut) {
+ this.fadeOut = fadeOut;
+ }
+
+ @Override
+ public String toString() {
+ return "GenericTitlePacket{"
+ + "action=" + getAction()
+ + ", component='" + component + '\''
+ + ", fadeIn=" + fadeIn
+ + ", stay=" + stay
+ + ", fadeOut=" + fadeOut
+ + '}';
+ }
+
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleActionbarPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleActionbarPacket.java
new file mode 100644
index 000000000..e875ae3cd
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleActionbarPacket.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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 .
+ */
+
+package com.velocitypowered.proxy.protocol.packet.title;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
+import com.velocitypowered.proxy.protocol.ProtocolUtils;
+import io.netty.buffer.ByteBuf;
+
+public class TitleActionbarPacket extends GenericTitlePacket {
+
+ private String component;
+
+ public TitleActionbarPacket() {
+ setAction(ActionType.SET_TITLE);
+ }
+
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
+ ProtocolUtils.writeString(buf, component);
+ }
+
+ @Override
+ public String getComponent() {
+ return component;
+ }
+
+ @Override
+ public void setComponent(String component) {
+ this.component = component;
+ }
+
+ @Override
+ public String toString() {
+ return "TitleActionbarPacket{"
+ + ", component='" + component + '\''
+ + '}';
+ }
+
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java
new file mode 100644
index 000000000..8ee0289ab
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 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 .
+ */
+
+package com.velocitypowered.proxy.protocol.packet.title;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
+import com.velocitypowered.proxy.protocol.ProtocolUtils;
+import io.netty.buffer.ByteBuf;
+
+public class TitleClearPacket extends GenericTitlePacket {
+
+ private boolean resetTimes;
+
+ public TitleClearPacket() {
+ setAction(ActionType.HIDE);
+ }
+
+ @Override
+ public void setAction(ActionType action) {
+ if (action != ActionType.HIDE && action != ActionType.RESET) {
+ throw new IllegalArgumentException("TitleClearPacket only accepts CLEAR and RESET actions");
+ }
+ super.setAction(action);
+ }
+
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
+ buf.writeBoolean(getAction() == ActionType.RESET);
+ }
+
+ @Override
+ public String toString() {
+ return "TitleClearPacket{"
+ + ", reset=" + resetTimes
+ + '}';
+ }
+
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleSubtitlePacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleSubtitlePacket.java
new file mode 100644
index 000000000..1640862f7
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleSubtitlePacket.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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 .
+ */
+
+package com.velocitypowered.proxy.protocol.packet.title;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
+import com.velocitypowered.proxy.protocol.ProtocolUtils;
+import io.netty.buffer.ByteBuf;
+
+public class TitleSubtitlePacket extends GenericTitlePacket {
+
+ private String component;
+
+ public TitleSubtitlePacket() {
+ setAction(ActionType.SET_SUBTITLE);
+ }
+
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
+ ProtocolUtils.writeString(buf, component);
+ }
+
+ @Override
+ public String getComponent() {
+ return component;
+ }
+
+ @Override
+ public void setComponent(String component) {
+ this.component = component;
+ }
+
+ @Override
+ public String toString() {
+ return "TitleSubtitlePacket{"
+ + ", component='" + component + '\''
+ + '}';
+ }
+
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTextPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTextPacket.java
new file mode 100644
index 000000000..135eb27e4
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTextPacket.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 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 .
+ */
+
+package com.velocitypowered.proxy.protocol.packet.title;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
+import com.velocitypowered.proxy.protocol.ProtocolUtils;
+import io.netty.buffer.ByteBuf;
+
+public class TitleTextPacket extends GenericTitlePacket {
+
+ private String component;
+
+ public TitleTextPacket() {
+ setAction(ActionType.SET_TITLE);
+ }
+
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
+ ProtocolUtils.writeString(buf, component);
+ }
+
+ @Override
+ public String getComponent() {
+ return component;
+ }
+
+ @Override
+ public void setComponent(String component) {
+ this.component = component;
+ }
+
+ @Override
+ public String toString() {
+ return "TitleTextPacket{"
+ + ", component='" + component + '\''
+ + '}';
+ }
+
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTimesPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTimesPacket.java
new file mode 100644
index 000000000..7450caccd
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleTimesPacket.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2018 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 .
+ */
+
+package com.velocitypowered.proxy.protocol.packet.title;
+
+import com.velocitypowered.api.network.ProtocolVersion;
+import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
+import com.velocitypowered.proxy.protocol.ProtocolUtils;
+import io.netty.buffer.ByteBuf;
+
+public class TitleTimesPacket extends GenericTitlePacket {
+
+ private int fadeIn;
+ private int stay;
+ private int fadeOut;
+
+ public TitleTimesPacket() {
+ setAction(ActionType.SET_TIMES);
+ }
+
+ @Override
+ public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
+ buf.writeInt(fadeIn);
+ buf.writeInt(stay);
+ buf.writeInt(fadeOut);
+ }
+
+ @Override
+ public int getFadeIn() {
+ return fadeIn;
+ }
+
+ @Override
+ public void setFadeIn(int fadeIn) {
+ this.fadeIn = fadeIn;
+ }
+
+ @Override
+ public int getStay() {
+ return stay;
+ }
+
+ @Override
+ public void setStay(int stay) {
+ this.stay = stay;
+ }
+
+ @Override
+ public int getFadeOut() {
+ return fadeOut;
+ }
+
+ @Override
+ public void setFadeOut(int fadeOut) {
+ this.fadeOut = fadeOut;
+ }
+
+ @Override
+ public String toString() {
+ return "TitleTimesPacket{"
+ + ", fadeIn=" + fadeIn
+ + ", stay=" + stay
+ + ", fadeOut=" + fadeOut
+ + '}';
+ }
+
+ @Override
+ public boolean handle(MinecraftSessionHandler handler) {
+ return handler.handle(this);
+ }
+}
diff --git a/proxy/src/test/java/com/velocitypowered/proxy/protocol/PacketRegistryTest.java b/proxy/src/test/java/com/velocitypowered/proxy/protocol/PacketRegistryTest.java
index 1780d14ac..b2f6e857a 100644
--- a/proxy/src/test/java/com/velocitypowered/proxy/protocol/PacketRegistryTest.java
+++ b/proxy/src/test/java/com/velocitypowered/proxy/protocol/PacketRegistryTest.java
@@ -23,7 +23,11 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12_1;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_12_2;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
+import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14_2;
+import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_15;
+import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
+import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_2;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -43,8 +47,9 @@ class PacketRegistryTest {
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
ProtocolUtils.Direction.CLIENTBOUND);
registry.register(Handshake.class, Handshake::new,
- new StateRegistry.PacketMapping(0x01, MINECRAFT_1_8, false),
- new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, false));
+ new StateRegistry.PacketMapping(0x01, MINECRAFT_1_8, null, false),
+ new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, null, false),
+ new StateRegistry.PacketMapping(0x00, MINECRAFT_1_15, MINECRAFT_1_16, false));
return registry;
}
@@ -73,6 +78,8 @@ class PacketRegistryTest {
"Registry did not return the correct packet ID");
assertNull(registry.getProtocolRegistry(MINECRAFT_1_14_2).createPacket(0x01),
"Registry should return a null");
+ assertNull(registry.getProtocolRegistry(MINECRAFT_1_16_2).createPacket(0),
+ "Registry should return null");
}
@Test
@@ -91,12 +98,19 @@ class PacketRegistryTest {
ProtocolUtils.Direction.CLIENTBOUND);
assertThrows(IllegalArgumentException.class,
() -> registry.register(Handshake.class, Handshake::new,
- new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, false),
- new StateRegistry.PacketMapping(0x00, MINECRAFT_1_8, false)));
+ new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, null, false),
+ new StateRegistry.PacketMapping(0x00, MINECRAFT_1_8, null, false)));
assertThrows(IllegalArgumentException.class,
() -> registry.register(Handshake.class, Handshake::new,
- new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, false),
- new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, false)));
+ new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, null, false),
+ new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, null, false)));
+ assertThrows(IllegalArgumentException.class,
+ () -> registry.register(Handshake.class, Handshake::new,
+ new StateRegistry.PacketMapping(0x01, MINECRAFT_1_13, MINECRAFT_1_8, false)));
+ assertThrows(IllegalArgumentException.class,
+ () -> registry.register(Handshake.class, Handshake::new,
+ new StateRegistry.PacketMapping(0x01, MINECRAFT_1_8, MINECRAFT_1_14, false),
+ new StateRegistry.PacketMapping(0x00, MINECRAFT_1_16, null, false)));
}
@Test
@@ -104,13 +118,13 @@ class PacketRegistryTest {
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
ProtocolUtils.Direction.CLIENTBOUND);
registry.register(Handshake.class, Handshake::new,
- new StateRegistry.PacketMapping(0x00, MINECRAFT_1_8, false));
+ new StateRegistry.PacketMapping(0x00, MINECRAFT_1_8, null, false));
assertThrows(IllegalArgumentException.class,
() -> registry.register(Handshake.class, Handshake::new,
- new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12, false)));
+ new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12, null, false)));
assertThrows(IllegalArgumentException.class,
() -> registry.register(StatusPing.class, StatusPing::new,
- new StateRegistry.PacketMapping(0x00, MINECRAFT_1_13, false)));
+ new StateRegistry.PacketMapping(0x00, MINECRAFT_1_13, null, false)));
}
@Test
@@ -118,9 +132,9 @@ class PacketRegistryTest {
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
ProtocolUtils.Direction.CLIENTBOUND);
assertDoesNotThrow(() -> registry.register(Handshake.class, Handshake::new,
- new StateRegistry.PacketMapping(0x00, MINECRAFT_1_8, false),
+ new StateRegistry.PacketMapping(0x00, MINECRAFT_1_8, null, false),
new StateRegistry.PacketMapping(0x01, getLast(ProtocolVersion.SUPPORTED_VERSIONS),
- false)));
+ null, false)));
}
@Test
@@ -128,9 +142,9 @@ class PacketRegistryTest {
StateRegistry.PacketRegistry registry = new StateRegistry.PacketRegistry(
ProtocolUtils.Direction.CLIENTBOUND);
registry.register(Handshake.class, Handshake::new,
- new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, false),
- new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12_1, false),
- new StateRegistry.PacketMapping(0x02, MINECRAFT_1_13, false));
+ new StateRegistry.PacketMapping(0x00, MINECRAFT_1_12, null, false),
+ new StateRegistry.PacketMapping(0x01, MINECRAFT_1_12_1, null, false),
+ new StateRegistry.PacketMapping(0x02, MINECRAFT_1_13, null, false));
assertEquals(Handshake.class,
registry.getProtocolRegistry(MINECRAFT_1_12).createPacket(0x00).getClass());
assertEquals(Handshake.class,
From 6207647aae96021a113e30c2b0acef83c3d0b728 Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Thu, 25 Feb 2021 14:49:29 +0100
Subject: [PATCH 13/30] Remove leftovers
---
.../velocitypowered/proxy/protocol/StateRegistry.java | 10 +++++-----
.../proxy/protocol/packet/title/TitleClearPacket.java | 4 +---
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
index 6baa55046..243239eb0 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
@@ -253,15 +253,15 @@ public enum StateRegistry {
map(0x4F, MINECRAFT_1_14, true),
map(0x50, MINECRAFT_1_15, true),
map(0x4F, MINECRAFT_1_16, MINECRAFT_1_16_4, true));
- clientbound.register(TitleSubtitlePacket.class, TitleSubtitlePacket::new, // TODO: fix
+ clientbound.register(TitleSubtitlePacket.class, TitleSubtitlePacket::new,
map(0x57, MINECRAFT_1_17, true));
- clientbound.register(TitleTextPacket.class, TitleTextPacket::new, // TODO: fix
+ clientbound.register(TitleTextPacket.class, TitleTextPacket::new,
map(0x5A, MINECRAFT_1_17, true));
- clientbound.register(TitleActionbarPacket.class, TitleActionbarPacket::new, // TODO: fix
+ clientbound.register(TitleActionbarPacket.class, TitleActionbarPacket::new,
map(0x41, MINECRAFT_1_17, true));
- clientbound.register(TitleTimesPacket.class, TitleTimesPacket::new, // TODO: fix
+ clientbound.register(TitleTimesPacket.class, TitleTimesPacket::new,
map(0x59, MINECRAFT_1_17, true));
- clientbound.register(TitleClearPacket.class, TitleClearPacket::new, // TODO: fix
+ clientbound.register(TitleClearPacket.class, TitleClearPacket::new,
map(0x10, MINECRAFT_1_17, true));
clientbound.register(PlayerListItem.class, PlayerListItem::new,
map(0x38, MINECRAFT_1_7_2, false),
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java
index 8ee0289ab..626abb517 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/title/TitleClearPacket.java
@@ -24,8 +24,6 @@ import io.netty.buffer.ByteBuf;
public class TitleClearPacket extends GenericTitlePacket {
- private boolean resetTimes;
-
public TitleClearPacket() {
setAction(ActionType.HIDE);
}
@@ -46,7 +44,7 @@ public class TitleClearPacket extends GenericTitlePacket {
@Override
public String toString() {
return "TitleClearPacket{"
- + ", reset=" + resetTimes
+ + ", resetTimes=" + (getAction() == ActionType.RESET)
+ '}';
}
From 581303a54c9263b05191f629f9c9c574bb873443 Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Thu, 11 Mar 2021 09:53:55 +0100
Subject: [PATCH 14/30] Snaphot 21w10a
---
.../api/network/ProtocolVersion.java | 2 +-
.../proxy/protocol/StateRegistry.java | 31 ++++++++++---------
2 files changed, 18 insertions(+), 15 deletions(-)
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 0149970e6..13d2c8124 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 16, "1.17"); // Snapshot: 21w08a, future protocol: 755
+ MINECRAFT_1_17(-1, 18, "1.17"); // Snapshot: 21w10a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
index 243239eb0..213e15222 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
@@ -131,7 +131,8 @@ public enum StateRegistry {
map(0x0A, MINECRAFT_1_12, false),
map(0x09, MINECRAFT_1_12_1, false),
map(0x0A, MINECRAFT_1_13, false),
- map(0x0B, MINECRAFT_1_14, false));
+ map(0x0B, MINECRAFT_1_14, false),
+ map(0x0A, MINECRAFT_1_17, false));
serverbound.register(KeepAlive.class, KeepAlive::new,
map(0x00, MINECRAFT_1_7_2, false),
map(0x0B, MINECRAFT_1_9, false),
@@ -139,7 +140,8 @@ public enum StateRegistry {
map(0x0B, MINECRAFT_1_12_1, false),
map(0x0E, MINECRAFT_1_13, false),
map(0x0F, MINECRAFT_1_14, false),
- map(0x10, MINECRAFT_1_16, false));
+ map(0x10, MINECRAFT_1_16, false),
+ map(0x0F, MINECRAFT_1_17, false));
serverbound.register(ResourcePackResponse.class, ResourcePackResponse::new,
map(0x19, MINECRAFT_1_8, false),
map(0x16, MINECRAFT_1_9, false),
@@ -147,7 +149,8 @@ public enum StateRegistry {
map(0x1D, MINECRAFT_1_13, false),
map(0x1F, MINECRAFT_1_14, false),
map(0x20, MINECRAFT_1_16, false),
- map(0x21, MINECRAFT_1_16_2, false));
+ map(0x21, MINECRAFT_1_16_2, false),
+ map(0x20, MINECRAFT_1_17, false));
clientbound.register(BossBar.class, BossBar::new,
map(0x0C, MINECRAFT_1_9, false),
@@ -183,7 +186,7 @@ public enum StateRegistry {
map(0x19, MINECRAFT_1_15, false),
map(0x18, MINECRAFT_1_16, false),
map(0x17, MINECRAFT_1_16_2, false),
- map(0x19, MINECRAFT_1_17, false));
+ map(0x18, MINECRAFT_1_17, false));
clientbound.register(Disconnect.class, Disconnect::new,
map(0x40, MINECRAFT_1_7_2, false),
map(0x1A, MINECRAFT_1_9, false),
@@ -192,7 +195,7 @@ public enum StateRegistry {
map(0x1B, MINECRAFT_1_15, false),
map(0x1A, MINECRAFT_1_16, false),
map(0x19, MINECRAFT_1_16_2, false),
- map(0x1B, MINECRAFT_1_17, false));
+ map(0x1A, MINECRAFT_1_17, false));
clientbound.register(KeepAlive.class, KeepAlive::new,
map(0x00, MINECRAFT_1_7_2, false),
map(0x1F, MINECRAFT_1_9, false),
@@ -201,7 +204,7 @@ public enum StateRegistry {
map(0x21, MINECRAFT_1_15, false),
map(0x20, MINECRAFT_1_16, false),
map(0x1F, MINECRAFT_1_16_2, false),
- map(0x22, MINECRAFT_1_17, false));
+ map(0x21, MINECRAFT_1_17, false));
clientbound.register(JoinGame.class, JoinGame::new,
map(0x01, MINECRAFT_1_7_2, false),
map(0x23, MINECRAFT_1_9, false),
@@ -210,7 +213,7 @@ public enum StateRegistry {
map(0x26, MINECRAFT_1_15, false),
map(0x25, MINECRAFT_1_16, false),
map(0x24, MINECRAFT_1_16_2, false),
- map(0x27, MINECRAFT_1_17, false));
+ map(0x26, MINECRAFT_1_17, false));
clientbound.register(Respawn.class, Respawn::new,
map(0x07, MINECRAFT_1_7_2, true),
map(0x33, MINECRAFT_1_9, true),
@@ -221,7 +224,7 @@ public enum StateRegistry {
map(0x3B, MINECRAFT_1_15, true),
map(0x3A, MINECRAFT_1_16, true),
map(0x39, MINECRAFT_1_16_2, true),
- map(0x3D, MINECRAFT_1_17, true));
+ map(0x3C, MINECRAFT_1_17, true));
clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new,
map(0x48, MINECRAFT_1_8, true),
map(0x32, MINECRAFT_1_9, true),
@@ -232,7 +235,7 @@ public enum StateRegistry {
map(0x3A, MINECRAFT_1_15, true),
map(0x39, MINECRAFT_1_16, true),
map(0x38, MINECRAFT_1_16_2, true),
- map(0x3C, MINECRAFT_1_17, true));
+ map(0x3B, MINECRAFT_1_17, true));
clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new,
map(0x47, MINECRAFT_1_8, true),
map(0x48, MINECRAFT_1_9, true),
@@ -243,7 +246,7 @@ public enum StateRegistry {
map(0x53, MINECRAFT_1_14, true),
map(0x54, MINECRAFT_1_15, true),
map(0x53, MINECRAFT_1_16, true),
- map(0x5E, MINECRAFT_1_17, true));
+ map(0x5D, MINECRAFT_1_17, true));
clientbound.register(LegacyTitlePacket.class, LegacyTitlePacket::new,
map(0x45, MINECRAFT_1_8, true),
map(0x45, MINECRAFT_1_9, true),
@@ -254,11 +257,11 @@ public enum StateRegistry {
map(0x50, MINECRAFT_1_15, true),
map(0x4F, MINECRAFT_1_16, MINECRAFT_1_16_4, true));
clientbound.register(TitleSubtitlePacket.class, TitleSubtitlePacket::new,
- map(0x57, MINECRAFT_1_17, true));
+ map(0x56, MINECRAFT_1_17, true));
clientbound.register(TitleTextPacket.class, TitleTextPacket::new,
- map(0x5A, MINECRAFT_1_17, true));
+ map(0x58, MINECRAFT_1_17, true));
clientbound.register(TitleActionbarPacket.class, TitleActionbarPacket::new,
- map(0x41, MINECRAFT_1_17, true));
+ map(0x40, MINECRAFT_1_17, true));
clientbound.register(TitleTimesPacket.class, TitleTimesPacket::new,
map(0x59, MINECRAFT_1_17, true));
clientbound.register(TitleClearPacket.class, TitleClearPacket::new,
@@ -272,7 +275,7 @@ public enum StateRegistry {
map(0x34, MINECRAFT_1_15, false),
map(0x33, MINECRAFT_1_16, false),
map(0x32, MINECRAFT_1_16_2, false),
- map(0x36, MINECRAFT_1_17, false));
+ map(0x35, MINECRAFT_1_17, false));
}
},
LOGIN {
From f6e023bf60b6f119c4b380c214121cf884035645 Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Wed, 17 Mar 2021 17:08:31 +0100
Subject: [PATCH 15/30] Snapshot 21w11a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 13d2c8124..1fbebd5c6 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 18, "1.17"); // Snapshot: 21w10a, future protocol: 755
+ MINECRAFT_1_17(-1, 19, "1.17"); // Snapshot: 21w11a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 625fa9b0ada6b656d713e828619ac083099b1d87 Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Wed, 31 Mar 2021 20:22:46 +0200
Subject: [PATCH 16/30] Snapshot 21w13a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 1fbebd5c6..cc4b641a1 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 19, "1.17"); // Snapshot: 21w11a, future protocol: 755
+ MINECRAFT_1_17(-1, 20, "1.17"); // Snapshot: 21w13a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 22202094958dc3a5a807f1e17b13ebc01a39f72b Mon Sep 17 00:00:00 2001
From: "Five (Xer)"
Date: Wed, 14 Apr 2021 19:35:40 +0200
Subject: [PATCH 17/30] Snapshot 21w14a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 cc4b641a1..5d843d88d 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 20, "1.17"); // Snapshot: 21w13a, future protocol: 755
+ MINECRAFT_1_17(-1, 21, "1.17"); // Snapshot: 21w14a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 8def411b2b99bf952d7f857196a4095c409ec9fd Mon Sep 17 00:00:00 2001
From: FivePB
Date: Thu, 13 May 2021 17:06:27 +0200
Subject: [PATCH 18/30] Snapshot 21w15a
---
.../player/PlayerResourcePackStatusEvent.java | 61 ++++++++
.../api/network/ProtocolVersion.java | 2 +-
.../com/velocitypowered/api/proxy/Player.java | 54 ++++---
.../api/proxy/ProxyServer.java | 21 +++
.../api/proxy/player/ResourcePackInfo.java | 120 +++++++++++++++
.../velocitypowered/proxy/VelocityServer.java | 7 +
.../backend/BackendPlaySessionHandler.java | 19 +++
.../client/ClientPlaySessionHandler.java | 7 +-
.../connection/client/ConnectedPlayer.java | 139 ++++++++++++++++--
.../player/VelocityResourcePackInfo.java | 110 ++++++++++++++
.../proxy/protocol/StateRegistry.java | 20 +--
.../protocol/packet/ResourcePackRequest.java | 24 +++
.../protocol/packet/ResourcePackResponse.java | 4 +
13 files changed, 540 insertions(+), 48 deletions(-)
create mode 100644 api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java
create mode 100644 proxy/src/main/java/com/velocitypowered/proxy/connection/player/VelocityResourcePackInfo.java
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java
index 5bffcce89..a490b6791 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java
@@ -8,7 +8,11 @@
package com.velocitypowered.api.event.player;
import com.google.common.base.Preconditions;
+import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.Player;
+import com.velocitypowered.api.proxy.player.ResourcePackInfo;
+import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
+import org.checkerframework.checker.nullness.qual.Nullable;
/**
* This event is fired when the status of a resource pack sent to the player by the server is
@@ -18,10 +22,29 @@ public class PlayerResourcePackStatusEvent {
private final Player player;
private final Status status;
+ private final @MonotonicNonNull ResourcePackInfo packInfo;
+ private boolean overwriteKick;
+
+ /**
+ * Instates this event.
+ * @deprecated Use {@link PlayerResourcePackStatusEvent#PlayerResourcePackStatusEvent
+ * (Player, Status, ResourcePackInfo)} instead.
+ */
+ @Deprecated
public PlayerResourcePackStatusEvent(Player player, Status status) {
this.player = Preconditions.checkNotNull(player, "player");
this.status = Preconditions.checkNotNull(status, "status");
+ this.packInfo = null;
+ }
+
+ /**
+ * Instates this event.
+ */
+ public PlayerResourcePackStatusEvent(Player player, Status status, ResourcePackInfo packInfo) {
+ this.player = Preconditions.checkNotNull(player, "player");
+ this.status = Preconditions.checkNotNull(status, "status");
+ this.packInfo = packInfo;
}
/**
@@ -42,11 +65,49 @@ public class PlayerResourcePackStatusEvent {
return status;
}
+ /**
+ * Returns the {@link ResourcePackInfo} this response is for.
+ *
+ * @return the resource-pack info or null if no request was recorded
+ */
+ @Nullable
+ public ResourcePackInfo getPackInfo() {
+ return packInfo;
+ }
+
+ /**
+ * Gets whether or not to override the kick resulting from
+ * {@link ResourcePackInfo#getShouldForce()} being true.
+ *
+ * @return whether or not to overwrite the result
+ */
+ public boolean isOverwriteKick() {
+ return overwriteKick;
+ }
+
+ /**
+ * Set to true to prevent {@link ResourcePackInfo#getShouldForce()}
+ * from kicking the player.
+ * Overwriting this kick is only possible on versions older than 1.17,
+ * as the client or server will enforce this regardless. Cancelling the resulting
+ * kick-events will not prevent the player from disconnecting from the proxy.
+ *
+ * @param overwriteKick whether or not to cancel the kick
+ * @throws IllegalArgumentException if the player version is 1.17 or newer
+ */
+ public void setOverwriteKick(boolean overwriteKick) {
+ Preconditions.checkArgument(player.getProtocolVersion()
+ .compareTo(ProtocolVersion.MINECRAFT_1_17) < 0,
+ "overwriteKick is not supported on 1.17 or newer");
+ this.overwriteKick = overwriteKick;
+ }
+
@Override
public String toString() {
return "PlayerResourcePackStatusEvent{"
+ "player=" + player
+ ", status=" + status
+ + ", packInfo=" + packInfo
+ '}';
}
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 5d843d88d..10b3595f6 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 21, "1.17"); // Snapshot: 21w14a, future protocol: 755
+ MINECRAFT_1_17(-1, 22, "1.17"); // Snapshot: 21w15a, future protocol: 755
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 5fb68d4c9..d22f0caf2 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java
@@ -13,6 +13,7 @@ import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
import com.velocitypowered.api.proxy.messages.ChannelMessageSink;
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
import com.velocitypowered.api.proxy.player.PlayerSettings;
+import com.velocitypowered.api.proxy.player.ResourcePackInfo;
import com.velocitypowered.api.proxy.player.TabList;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.util.GameProfile;
@@ -25,6 +26,7 @@ import java.util.UUID;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.text.Component;
+import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Represents a player who is connected to the proxy.
@@ -215,7 +217,9 @@ public interface Player extends CommandSource, Identified, InboundConnection,
* sent resource pack, subscribe to {@link PlayerResourcePackStatusEvent}.
*
* @param url the URL for the resource pack
+ * @deprecated Use {@link #sendResourcePackOffer(ResourcePackInfo)} instead
*/
+ @Deprecated
void sendResourcePack(String url);
/**
@@ -225,10 +229,37 @@ public interface Player extends CommandSource, Identified, InboundConnection,
*
* @param url the URL for the resource pack
* @param hash the SHA-1 hash value for the resource pack
+ * @deprecated Use {@link #sendResourcePackOffer(ResourcePackInfo)} instead
*/
- default void sendResourcePack(String url, byte[] hash) {
- sendResourcePack(url, hash, false);
- }
+ @Deprecated
+ void sendResourcePack(String url, byte[] hash);
+
+ /**
+ * Queues and sends a new Resource-pack offer to the player.
+ * To monitor the status of the sent resource pack, subscribe to
+ * {@link PlayerResourcePackStatusEvent}.
+ *
+ * @param packInfo the resource-pack in question
+ */
+ void sendResourcePackOffer(ResourcePackInfo packInfo);
+
+ /**
+ * Gets the {@link ResourcePackInfo} of the currently applied
+ * resource-pack or null if none.
+ *
+ * @return the applied resource pack
+ */
+ @Nullable
+ ResourcePackInfo getAppliedResourcePack();
+
+ /**
+ * Gets the {@link ResourcePackInfo} of the currently accepted
+ * and currently downloading resource-pack or null if none.
+ *
+ * @return the pending resource pack
+ */
+ @Nullable
+ ResourcePackInfo getPendingResourcePack();
/**
* Note that this method does not send a plugin message to the server the player
@@ -241,21 +272,4 @@ 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 Only in 1.17+ or newer: If true shows the pack as required to play,
- * and removes the decline option. Declining it anyway will disconnect the user.
- */
- void sendResourcePack(String url, byte[] hash, boolean isRequired);
-
}
-
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/ProxyServer.java b/api/src/main/java/com/velocitypowered/api/proxy/ProxyServer.java
index 073cd3bb7..bd3430a13 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/ProxyServer.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/ProxyServer.java
@@ -13,6 +13,7 @@ import com.velocitypowered.api.event.EventManager;
import com.velocitypowered.api.plugin.PluginManager;
import com.velocitypowered.api.proxy.config.ProxyConfig;
import com.velocitypowered.api.proxy.messages.ChannelRegistrar;
+import com.velocitypowered.api.proxy.player.ResourcePackInfo;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerInfo;
import com.velocitypowered.api.scheduler.Scheduler;
@@ -217,4 +218,24 @@ public interface ProxyServer extends Audience {
@NonNull
BossBar createBossBar(net.kyori.text.Component title, @NonNull BossBarColor color,
@NonNull BossBarOverlay overlay, float progress);
+
+ /**
+ * Creates a builder to build a {@link ResourcePackInfo} instance for use with
+ * {@link com.velocitypowered.api.proxy.Player#sendResourcePackOffer(ResourcePackInfo)}.
+ *
+ * Note: The resource-pack location should always:
+ * - Use HTTPS with a valid certificate.
+ * - Be in a crawler-accessible location. Having it behind Cloudflare or Cloudfront
+ * may cause issues in downloading.
+ * - Be in location with appropriate bandwidth so the download does not time out or fail.
+ *
+ * Do also make sure that the resource pack is in the correct format for the version
+ * of the client. It is also highly recommended to always provide the resource-pack SHA-1 hash
+ * of the resource pack with {@link ResourcePackInfo.Builder#setHash(byte[])}
+ * whenever possible to save bandwidth.
+ *
+ * @param url The url where the resource pack can be found
+ * @return a ResourcePackInfo builder
+ */
+ ResourcePackInfo.Builder createResourcePackBuilder(String url);
}
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java b/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java
new file mode 100644
index 000000000..067dd26ba
--- /dev/null
+++ b/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2018 Velocity Contributors
+ *
+ * The Velocity API is licensed under the terms of the MIT License. For more details,
+ * reference the LICENSE file in the api top-level directory.
+ */
+
+package com.velocitypowered.api.proxy.player;
+
+import net.kyori.adventure.text.Component;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public interface ResourcePackInfo {
+
+ /**
+ * Gets the link the resource-pack can be found at.
+ *
+ * @return the location of the resource-pack
+ */
+ String getUrl();
+
+ /**
+ * Gets the {@link Component} that is displayed on the resource-pack prompt.
+ * This is only displayed if the client version is 1.17 or newer.
+ *
+ * @return the prompt if present or null otherwise
+ */
+ @Nullable
+ Component getPrompt();
+
+ /**
+ * Gets whether or not the acceptance of the resource-pack is enforced.
+ * See {@link Builder#setShouldForce(boolean)} for more information.
+ *
+ * @return whether or not to force usage of this resource-pack
+ */
+ boolean getShouldForce();
+
+ /**
+ * Gets the SHA-1 hash of the resource-pack
+ * See {@link Builder#setHash(byte[])} for more information.
+ *
+ * @return the hash if present or null otherwise
+ */
+ @Nullable
+ byte[] getHash();
+
+ /**
+ * Gets the {@link Origin} of the resource-pack.
+ *
+ * @return the origin of the resource pack
+ */
+ Origin getOrigin();
+
+ interface Builder {
+
+ /**
+ * Sets the resource-pack as required to play on the network.
+ * This feature was introduced in 1.17.
+ * Setting this to true has one of two effects:
+ * If the client is on 1.17 or newer:
+ * - The resource-pack prompt will display without a decline button
+ * - Accept or disconnect are the only available options but players may still press escape.
+ * - Forces the resource-pack offer prompt to display even if the player has
+ * previously declined or disabled resource packs
+ * - The player will be disconnected from the network if they close/skip the prompt.
+ * If the client is on a version older than 1.17:
+ * - If the player accepts the resource pack or has previously accepted a resource-pack
+ * then nothing else will happen.
+ * - If the player declines the resource pack or has previously declined a resource-pack
+ * the player will be disconnected from the network
+ *
+ * @param shouldForce whether or not to force the client to accept the resource pack
+ */
+ Builder setShouldForce(boolean shouldForce);
+
+ /**
+ * Sets the SHA-1 hash of the provided resource pack.
+ * Note: It is recommended to always set this hash.
+ * If this hash is not set/ not present then the client will always download
+ * the resource pack even if it may still be cached. By having this hash present,
+ * the client will check first whether or not a resource pack by this hash is cached
+ * before downloading.
+ *
+ * @param hash the SHA-1 hash of the resource-pack
+ */
+ Builder setHash(@Nullable byte[] hash);
+
+ /**
+ * Sets a {@link Component} to display on the download prompt.
+ * This will only display if the client version is 1.17 or newer.
+ *
+ * @param prompt the component to display
+ */
+ Builder setPrompt(@Nullable Component prompt);
+
+ /**
+ * Builds the {@link ResourcePackInfo} from the provided info for use with
+ * {@link com.velocitypowered.api.proxy.Player#sendResourcePackOffer(ResourcePackInfo)}.
+ * Note: Some features may be version-dependent. Check before use.
+ *
+ * @return a ResourcePackInfo instance from the provided information
+ */
+ ResourcePackInfo build();
+ }
+
+ /**
+ * Represents the origin of the resource-pack.
+ */
+ enum Origin {
+ /**
+ * Resource-pack originated from the downstream server.
+ */
+ DOWNSTREAM_SERVER,
+ /**
+ * The player declined to download the resource pack.
+ */
+ PLUGIN_ON_PROXY
+ }
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
index 63b3b7550..725e8403b 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java
@@ -30,6 +30,7 @@ import com.velocitypowered.api.plugin.PluginContainer;
import com.velocitypowered.api.plugin.PluginManager;
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ProxyServer;
+import com.velocitypowered.api.proxy.player.ResourcePackInfo;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerInfo;
import com.velocitypowered.api.util.Favicon;
@@ -45,6 +46,7 @@ import com.velocitypowered.proxy.command.builtin.ShutdownCommand;
import com.velocitypowered.proxy.command.builtin.VelocityCommand;
import com.velocitypowered.proxy.config.VelocityConfiguration;
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
+import com.velocitypowered.proxy.connection.player.VelocityResourcePackInfo;
import com.velocitypowered.proxy.console.VelocityConsole;
import com.velocitypowered.proxy.network.ConnectionManager;
import com.velocitypowered.proxy.plugin.VelocityEventManager;
@@ -682,4 +684,9 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
return version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0 ? POST_1_16_PING_SERIALIZER
: PRE_1_16_PING_SERIALIZER;
}
+
+ @Override
+ public ResourcePackInfo.Builder createResourcePackBuilder(String url) {
+ return new VelocityResourcePackInfo.BuilderImpl(url);
+ }
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java
index b3c7133cf..f42a6c085 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/backend/BackendPlaySessionHandler.java
@@ -19,6 +19,7 @@ package com.velocitypowered.proxy.connection.backend;
import static com.velocitypowered.proxy.connection.backend.BungeeCordMessageResponder.getBungeeCordChannel;
+import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.mojang.brigadier.tree.CommandNode;
@@ -28,10 +29,12 @@ import com.velocitypowered.api.event.command.PlayerAvailableCommandsEvent;
import com.velocitypowered.api.event.connection.PluginMessageEvent;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
+import com.velocitypowered.api.proxy.player.ResourcePackInfo;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
import com.velocitypowered.proxy.connection.client.ClientPlaySessionHandler;
+import com.velocitypowered.proxy.connection.player.VelocityResourcePackInfo;
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
import com.velocitypowered.proxy.protocol.MinecraftPacket;
import com.velocitypowered.proxy.protocol.packet.AvailableCommands;
@@ -40,6 +43,7 @@ import com.velocitypowered.proxy.protocol.packet.Disconnect;
import com.velocitypowered.proxy.protocol.packet.KeepAlive;
import com.velocitypowered.proxy.protocol.packet.PlayerListItem;
import com.velocitypowered.proxy.protocol.packet.PluginMessage;
+import com.velocitypowered.proxy.protocol.packet.ResourcePackRequest;
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponse;
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
import io.netty.buffer.ByteBuf;
@@ -128,6 +132,21 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
return false; // forward
}
+ @Override
+ public boolean handle(ResourcePackRequest packet) {
+ ResourcePackInfo.Builder builder = new VelocityResourcePackInfo.BuilderImpl(
+ Preconditions.checkNotNull(packet.getUrl()))
+ .setPrompt(packet.getPrompt())
+ .setShouldForce(packet.isRequired());
+ // Why SpotBugs decides that this is unsafe I have no idea;
+ if (packet.getHash() != null && !Preconditions.checkNotNull(packet.getHash()).isEmpty()) {
+ builder.setHash(ByteBufUtil.decodeHexDump(packet.getHash()));
+ }
+
+ serverConn.getPlayer().queueResourcePack(builder.build());
+ return true;
+ }
+
@Override
public boolean handle(PluginMessage packet) {
if (bungeecordMessageResponder.process(packet)) {
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
index 0c2b402eb..7c8729610 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java
@@ -33,6 +33,7 @@ import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
+import com.velocitypowered.api.proxy.player.ResourcePackInfo;
import com.velocitypowered.proxy.VelocityServer;
import com.velocitypowered.proxy.connection.ConnectionTypes;
import com.velocitypowered.proxy.connection.MinecraftConnection;
@@ -72,6 +73,7 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
@@ -283,9 +285,8 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
@Override
public boolean handle(ResourcePackResponse packet) {
- server.getEventManager().fireAndForget(new PlayerResourcePackStatusEvent(player,
- packet.getStatus()));
- return false;
+ return player.onResourcePackResponse(packet.getStatus(),
+ ByteBufUtil.decodeHexDump(packet.getHash()));
}
@Override
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 1a1a0d444..459a7ea26 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
@@ -31,6 +31,7 @@ import com.velocitypowered.api.event.player.KickedFromServerEvent.Notify;
import com.velocitypowered.api.event.player.KickedFromServerEvent.RedirectPlayer;
import com.velocitypowered.api.event.player.KickedFromServerEvent.ServerKickResult;
import com.velocitypowered.api.event.player.PlayerModInfoEvent;
+import com.velocitypowered.api.event.player.PlayerResourcePackStatusEvent;
import com.velocitypowered.api.event.player.PlayerSettingsChangedEvent;
import com.velocitypowered.api.event.player.ServerPreConnectEvent;
import com.velocitypowered.api.network.ProtocolVersion;
@@ -42,6 +43,7 @@ import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.ServerConnection;
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
import com.velocitypowered.api.proxy.player.PlayerSettings;
+import com.velocitypowered.api.proxy.player.ResourcePackInfo;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.api.util.MessagePosition;
@@ -55,6 +57,7 @@ import com.velocitypowered.proxy.connection.MinecraftConnection;
import com.velocitypowered.proxy.connection.MinecraftConnectionAssociation;
import com.velocitypowered.proxy.connection.backend.VelocityServerConnection;
import com.velocitypowered.proxy.connection.forge.legacy.LegacyForgeConstants;
+import com.velocitypowered.proxy.connection.player.VelocityResourcePackInfo;
import com.velocitypowered.proxy.connection.util.ConnectionMessages;
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
@@ -76,12 +79,14 @@ import com.velocitypowered.proxy.util.collect.CappedSet;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import java.net.InetSocketAddress;
+import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
+import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
@@ -133,6 +138,10 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
private final Collection knownChannels;
private final CompletableFuture teardownFuture = new CompletableFuture<>();
private @MonotonicNonNull List serversToTry = null;
+ private @MonotonicNonNull Boolean previousResourceResponse;
+ private final Queue outstandingResourcePacks = new ArrayDeque<>();
+ private @Nullable ResourcePackInfo pendingResourcePack;
+ private @Nullable ResourcePackInfo appliedResourcePack;
ConnectedPlayer(VelocityServer server, GameProfile profile, MinecraftConnection connection,
@Nullable InetSocketAddress virtualHost, boolean onlineMode) {
@@ -871,31 +880,133 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
}
@Override
+ @Deprecated
public void sendResourcePack(String url) {
- Preconditions.checkNotNull(url, "url");
+ sendResourcePackOffer(new VelocityResourcePackInfo.BuilderImpl(url).build());
+ }
+ @Override
+ @Deprecated
+ public void sendResourcePack(String url, byte[] hash) {
+ sendResourcePackOffer(new VelocityResourcePackInfo.BuilderImpl(url).setHash(hash).build());
+ }
+
+ @Override
+ public void sendResourcePackOffer(ResourcePackInfo packInfo) {
if (this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
+ Preconditions.checkNotNull(packInfo, "packInfo");
+ queueResourcePack(packInfo);
+ }
+ }
+
+ /**
+ * Queues a resource-pack for sending to the player and sends it
+ * immediately if the queue is empty.
+ */
+ public void queueResourcePack(ResourcePackInfo info) {
+ outstandingResourcePacks.add(info);
+ if (outstandingResourcePacks.size() == 1) {
+ tickResourcePackQueue();
+ }
+ }
+
+ private void tickResourcePackQueue() {
+ ResourcePackInfo queued = outstandingResourcePacks.peek();
+
+ if (queued != null) {
+ // Check if the player declined a resource pack once already
+ if (previousResourceResponse != null && !previousResourceResponse) {
+ // If that happened we can flush the queue right away.
+ // Unless its 1.17+ and forced it will come back denied anyway
+ while (!outstandingResourcePacks.isEmpty()) {
+ queued = outstandingResourcePacks.peek();
+ if (queued.getShouldForce() && getProtocolVersion()
+ .compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) {
+ break;
+ }
+ onResourcePackResponse(PlayerResourcePackStatusEvent.Status.DECLINED, new byte[0]);
+ queued = null;
+ }
+ if (queued == null) {
+ // Exit as the queue was cleared
+ return;
+ }
+ }
+
ResourcePackRequest request = new ResourcePackRequest();
- request.setUrl(url);
- request.setHash("");
- request.setRequired(false);
+ request.setUrl(queued.getUrl());
+ if (queued.getHash() != null) {
+ request.setHash(ByteBufUtil.hexDump(queued.getHash()));
+ } else {
+ request.setHash("");
+ }
+ request.setRequired(queued.getShouldForce());
+ request.setPrompt(queued.getPrompt());
+
connection.write(request);
}
}
@Override
- 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");
+ public @Nullable ResourcePackInfo getAppliedResourcePack() {
+ return appliedResourcePack;
+ }
- if (this.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_8) >= 0) {
- ResourcePackRequest request = new ResourcePackRequest();
- request.setUrl(url);
- request.setHash(ByteBufUtil.hexDump(hash));
- request.setRequired(isRequired);
- connection.write(request);
+ @Override
+ public @Nullable ResourcePackInfo getPendingResourcePack() {
+ return pendingResourcePack;
+ }
+
+ /**
+ * Processes a client response to a sent resource-pack.
+ */
+ public boolean onResourcePackResponse(PlayerResourcePackStatusEvent.Status status,
+ @Nullable byte[] hash) {
+
+ final boolean peek = status == PlayerResourcePackStatusEvent.Status.ACCEPTED;
+ final ResourcePackInfo queued = peek
+ ? outstandingResourcePacks.peek() : outstandingResourcePacks.poll();
+
+ server.getEventManager().fire(new PlayerResourcePackStatusEvent(this, status, queued))
+ .thenAcceptAsync(event -> {
+ if (event.getStatus() == PlayerResourcePackStatusEvent.Status.DECLINED
+ && event.getPackInfo() != null && event.getPackInfo().getShouldForce()
+ && (!event.isOverwriteKick() || event.getPlayer()
+ .getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0)
+ ) {
+ event.getPlayer().disconnect(Component
+ .translatable("multiplayer.requiredTexturePrompt.disconnect"));
+ }
+ });
+
+
+ switch (status) {
+ case ACCEPTED:
+ previousResourceResponse = true;
+ pendingResourcePack = queued;
+ break;
+ case DECLINED:
+ previousResourceResponse = false;
+ break;
+ case SUCCESSFUL:
+ appliedResourcePack = queued;
+ pendingResourcePack = null;
+ break;
+ case FAILED_DOWNLOAD:
+ pendingResourcePack = null;
+ break;
+ default:
+ break;
}
+
+ if (!peek) {
+ CompletableFuture.supplyAsync(() -> {
+ tickResourcePackQueue();
+ return true;
+ });
+ }
+
+ return queued != null && queued.getOrigin() == ResourcePackInfo.Origin.DOWNSTREAM_SERVER;
}
/**
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/connection/player/VelocityResourcePackInfo.java b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/VelocityResourcePackInfo.java
new file mode 100644
index 000000000..250e9b3aa
--- /dev/null
+++ b/proxy/src/main/java/com/velocitypowered/proxy/connection/player/VelocityResourcePackInfo.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2018 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 .
+ */
+
+package com.velocitypowered.proxy.connection.player;
+
+import com.google.common.base.Preconditions;
+import com.velocitypowered.api.proxy.player.ResourcePackInfo;
+import net.kyori.adventure.text.Component;
+import org.checkerframework.checker.nullness.qual.Nullable;
+
+public final class VelocityResourcePackInfo implements ResourcePackInfo {
+ private final String url;
+ private final @Nullable byte[] hash;
+ private final boolean shouldForce;
+ private final @Nullable Component prompt; // 1.17+ only
+ private final Origin origin;
+
+ private VelocityResourcePackInfo(String url, @Nullable byte[] hash, boolean shouldForce,
+ @Nullable Component prompt, Origin origin) {
+ this.url = url;
+ this.hash = hash;
+ this.shouldForce = shouldForce;
+ this.prompt = prompt;
+ this.origin = origin;
+ }
+
+ @Override
+ public String getUrl() {
+ return url;
+ }
+
+ @Override
+ public @Nullable Component getPrompt() {
+ return prompt;
+ }
+
+ @Override
+ public boolean getShouldForce() {
+ return shouldForce;
+ }
+
+ @Override
+ public @Nullable byte[] getHash() {
+ return hash == null ? null : hash.clone(); // Thanks spotbugs, very helpful.
+ }
+
+ @Override
+ public Origin getOrigin() {
+ return origin;
+ }
+
+ public static final class BuilderImpl implements ResourcePackInfo.Builder {
+ private final String url;
+ private boolean shouldForce;
+ private @Nullable byte[] hash;
+ private @Nullable Component prompt;
+ private Origin origin = Origin.PLUGIN_ON_PROXY;
+
+ public BuilderImpl(String url) {
+ this.url = Preconditions.checkNotNull(url, "url");
+ }
+
+ @Override
+ public BuilderImpl setShouldForce(boolean shouldForce) {
+ this.shouldForce = shouldForce;
+ return this;
+ }
+
+ @Override
+ public BuilderImpl setHash(@Nullable byte[] hash) {
+ if (hash != null) {
+ Preconditions.checkArgument(hash.length == 20, "Hash length is not 20");
+ this.hash = hash.clone(); // Thanks spotbugs, very helpful.
+ } else {
+ this.hash = null;
+ }
+ return this;
+ }
+
+ @Override
+ public BuilderImpl setPrompt(@Nullable Component prompt) {
+ this.prompt = prompt;
+ return this;
+ }
+
+ @Override
+ public ResourcePackInfo build() {
+ return new VelocityResourcePackInfo(url, hash, shouldForce, prompt, origin);
+ }
+
+ public void setOrigin(Origin origin) {
+ this.origin = origin;
+ }
+ }
+
+}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
index 213e15222..b56cb8f02 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
@@ -226,16 +226,16 @@ public enum StateRegistry {
map(0x39, MINECRAFT_1_16_2, true),
map(0x3C, MINECRAFT_1_17, true));
clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new,
- map(0x48, MINECRAFT_1_8, true),
- map(0x32, MINECRAFT_1_9, true),
- map(0x33, MINECRAFT_1_12, true),
- map(0x34, MINECRAFT_1_12_1, true),
- map(0x37, MINECRAFT_1_13, true),
- map(0x39, MINECRAFT_1_14, true),
- map(0x3A, MINECRAFT_1_15, true),
- map(0x39, MINECRAFT_1_16, true),
- map(0x38, MINECRAFT_1_16_2, true),
- map(0x3B, MINECRAFT_1_17, true));
+ map(0x48, MINECRAFT_1_8, false),
+ map(0x32, MINECRAFT_1_9, false),
+ map(0x33, MINECRAFT_1_12, false),
+ map(0x34, MINECRAFT_1_12_1, false),
+ map(0x37, MINECRAFT_1_13, false),
+ map(0x39, MINECRAFT_1_14, false),
+ map(0x3A, MINECRAFT_1_15, false),
+ map(0x39, MINECRAFT_1_16, false),
+ map(0x38, MINECRAFT_1_16_2, false),
+ map(0x3B, MINECRAFT_1_17, false));
clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new,
map(0x47, MINECRAFT_1_8, true),
map(0x48, MINECRAFT_1_9, true),
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 c2115970d..d17505560 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
@@ -23,6 +23,8 @@ 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 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.Nullable;
@@ -31,6 +33,7 @@ public class ResourcePackRequest implements MinecraftPacket {
private @MonotonicNonNull String url;
private @MonotonicNonNull String hash;
private boolean isRequired; // 1.17+
+ private @Nullable Component prompt; // 1.17+
public @Nullable String getUrl() {
return url;
@@ -56,12 +59,25 @@ public class ResourcePackRequest implements MinecraftPacket {
isRequired = required;
}
+ public @Nullable Component getPrompt() {
+ return prompt;
+ }
+
+ public void setPrompt(Component prompt) {
+ this.prompt = prompt;
+ }
+
@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();
+ if (buf.readBoolean()) {
+ this.prompt = GsonComponentSerializer.gson().deserialize(ProtocolUtils.readString(buf));
+ } else {
+ this.prompt = null;
+ }
}
}
@@ -74,6 +90,12 @@ public class ResourcePackRequest implements MinecraftPacket {
ProtocolUtils.writeString(buf, hash);
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_17) >= 0) {
buf.writeBoolean(isRequired);
+ if (prompt != null) {
+ buf.writeBoolean(true);
+ ProtocolUtils.writeString(buf, GsonComponentSerializer.gson().serialize(prompt));
+ } else {
+ buf.writeBoolean(false);
+ }
}
}
@@ -87,6 +109,8 @@ public class ResourcePackRequest implements MinecraftPacket {
return "ResourcePackRequest{"
+ "url='" + url + '\''
+ ", hash='" + hash + '\''
+ + ", isRequired=" + isRequired
+ + ", prompt='" + prompt + '\''
+ '}';
}
}
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackResponse.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackResponse.java
index 245e2f501..3269ff0d5 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackResponse.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/packet/ResourcePackResponse.java
@@ -38,6 +38,10 @@ public class ResourcePackResponse implements MinecraftPacket {
return status;
}
+ public String getHash() {
+ return hash;
+ }
+
@Override
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
if (protocolVersion.compareTo(ProtocolVersion.MINECRAFT_1_9_4) <= 0) {
From be1848f8e72962b53af6b1cfc83c1b0ccf795f6c Mon Sep 17 00:00:00 2001
From: FivePB
Date: Thu, 13 May 2021 17:09:50 +0200
Subject: [PATCH 19/30] Snapshot 21w16a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 10b3595f6..b93fdbf39 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 22, "1.17"); // Snapshot: 21w15a, future protocol: 755
+ MINECRAFT_1_17(-1, 23, "1.17"); // Snapshot: 21w16a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 00f81a3fd70842b2285327abbf640e7e17c7b083 Mon Sep 17 00:00:00 2001
From: FivePB
Date: Thu, 13 May 2021 17:12:37 +0200
Subject: [PATCH 20/30] Snapshot 21w17a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 b93fdbf39..120f55334 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 23, "1.17"); // Snapshot: 21w16a, future protocol: 755
+ MINECRAFT_1_17(-1, 25, "1.17"); // Snapshot: 21w17a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 6eb2432e8865618642f980109621d2ee6507f3cf Mon Sep 17 00:00:00 2001
From: FivePB
Date: Thu, 13 May 2021 17:13:08 +0200
Subject: [PATCH 21/30] Snapshot 21w18a
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 120f55334..80316d298 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 25, "1.17"); // Snapshot: 21w17a, future protocol: 755
+ MINECRAFT_1_17(-1, 26, "1.17"); // Snapshot: 21w18a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 18466bb59586bc37598a60f9a10b8e659010777f Mon Sep 17 00:00:00 2001
From: FivePB
Date: Thu, 13 May 2021 17:24:51 +0200
Subject: [PATCH 22/30] Snapshot 21w19a
---
.../api/network/ProtocolVersion.java | 2 +-
.../proxy/protocol/StateRegistry.java | 21 +++++++++----------
2 files changed, 11 insertions(+), 12 deletions(-)
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 80316d298..dc17efb23 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 26, "1.17"); // Snapshot: 21w18a, future protocol: 755
+ MINECRAFT_1_17(-1, 27, "1.17"); // Snapshot: 21w19a, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
diff --git a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
index b56cb8f02..8e787539f 100644
--- a/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
+++ b/proxy/src/main/java/com/velocitypowered/proxy/protocol/StateRegistry.java
@@ -149,8 +149,7 @@ public enum StateRegistry {
map(0x1D, MINECRAFT_1_13, false),
map(0x1F, MINECRAFT_1_14, false),
map(0x20, MINECRAFT_1_16, false),
- map(0x21, MINECRAFT_1_16_2, false),
- map(0x20, MINECRAFT_1_17, false));
+ map(0x21, MINECRAFT_1_16_2, false));
clientbound.register(BossBar.class, BossBar::new,
map(0x0C, MINECRAFT_1_9, false),
@@ -224,7 +223,7 @@ public enum StateRegistry {
map(0x3B, MINECRAFT_1_15, true),
map(0x3A, MINECRAFT_1_16, true),
map(0x39, MINECRAFT_1_16_2, true),
- map(0x3C, MINECRAFT_1_17, true));
+ map(0x3D, MINECRAFT_1_17, true));
clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new,
map(0x48, MINECRAFT_1_8, false),
map(0x32, MINECRAFT_1_9, false),
@@ -235,7 +234,7 @@ public enum StateRegistry {
map(0x3A, MINECRAFT_1_15, false),
map(0x39, MINECRAFT_1_16, false),
map(0x38, MINECRAFT_1_16_2, false),
- map(0x3B, MINECRAFT_1_17, false));
+ map(0x3C, MINECRAFT_1_17, false));
clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new,
map(0x47, MINECRAFT_1_8, true),
map(0x48, MINECRAFT_1_9, true),
@@ -246,7 +245,7 @@ public enum StateRegistry {
map(0x53, MINECRAFT_1_14, true),
map(0x54, MINECRAFT_1_15, true),
map(0x53, MINECRAFT_1_16, true),
- map(0x5D, MINECRAFT_1_17, true));
+ map(0x5E, MINECRAFT_1_17, true));
clientbound.register(LegacyTitlePacket.class, LegacyTitlePacket::new,
map(0x45, MINECRAFT_1_8, true),
map(0x45, MINECRAFT_1_9, true),
@@ -257,13 +256,13 @@ public enum StateRegistry {
map(0x50, MINECRAFT_1_15, true),
map(0x4F, MINECRAFT_1_16, MINECRAFT_1_16_4, true));
clientbound.register(TitleSubtitlePacket.class, TitleSubtitlePacket::new,
- map(0x56, MINECRAFT_1_17, true));
+ map(0x57, MINECRAFT_1_17, true));
clientbound.register(TitleTextPacket.class, TitleTextPacket::new,
- map(0x58, MINECRAFT_1_17, true));
- clientbound.register(TitleActionbarPacket.class, TitleActionbarPacket::new,
- map(0x40, MINECRAFT_1_17, true));
- clientbound.register(TitleTimesPacket.class, TitleTimesPacket::new,
map(0x59, MINECRAFT_1_17, true));
+ clientbound.register(TitleActionbarPacket.class, TitleActionbarPacket::new,
+ map(0x41, MINECRAFT_1_17, true));
+ clientbound.register(TitleTimesPacket.class, TitleTimesPacket::new,
+ map(0x5A, MINECRAFT_1_17, true));
clientbound.register(TitleClearPacket.class, TitleClearPacket::new,
map(0x10, MINECRAFT_1_17, true));
clientbound.register(PlayerListItem.class, PlayerListItem::new,
@@ -275,7 +274,7 @@ public enum StateRegistry {
map(0x34, MINECRAFT_1_15, false),
map(0x33, MINECRAFT_1_16, false),
map(0x32, MINECRAFT_1_16_2, false),
- map(0x35, MINECRAFT_1_17, false));
+ map(0x36, MINECRAFT_1_17, false));
}
},
LOGIN {
From 10bfd8685e2d242006f45558139ddeb0b353d259 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn
Date: Thu, 27 May 2021 11:02:07 -0400
Subject: [PATCH 23/30] Minecraft 1.17-pre1
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 dc17efb23..f67431c33 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 27, "1.17"); // Snapshot: 21w19a, future protocol: 755
+ MINECRAFT_1_17(-1, 29, "1.17"); // Snapshot: 1.17-pre1, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From c161a3859c52f65f21852f029ef940c6aaccc34c Mon Sep 17 00:00:00 2001
From: Andrew Steinborn
Date: Mon, 31 May 2021 12:47:13 -0400
Subject: [PATCH 24/30] 1.17-pre2
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 f67431c33..d01e82938 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 29, "1.17"); // Snapshot: 1.17-pre1, future protocol: 755
+ MINECRAFT_1_17(-1, 30, "1.17"); // Snapshot: 1.17-pre2, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From f67dc3ffc8c4fe0f59d1e46b8842982af833000c Mon Sep 17 00:00:00 2001
From: Andrew Steinborn
Date: Tue, 1 Jun 2021 13:36:28 -0400
Subject: [PATCH 25/30] Minecraft 1.17-pre3
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 d01e82938..09a3dc4c4 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 30, "1.17"); // Snapshot: 1.17-pre2, future protocol: 755
+ MINECRAFT_1_17(-1, 31, "1.17"); // Snapshot: 1.17-pre3, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 3eb64855d3164c313c19e3b91ddb221d19882a23 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn
Date: Thu, 3 Jun 2021 02:50:16 -0400
Subject: [PATCH 26/30] Minecraft 1.17-pre4
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 09a3dc4c4..f57938558 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 31, "1.17"); // Snapshot: 1.17-pre3, future protocol: 755
+ MINECRAFT_1_17(-1, 32, "1.17"); // Snapshot: 1.17-pre4, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 100eedf1023f742b9d73c5c00cb1489e7401713f Mon Sep 17 00:00:00 2001
From: Andrew Steinborn
Date: Thu, 3 Jun 2021 14:40:06 -0400
Subject: [PATCH 27/30] Minecraft 1.17-pre5
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 f57938558..68f62749f 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 32, "1.17"); // Snapshot: 1.17-pre4, future protocol: 755
+ MINECRAFT_1_17(-1, 33, "1.17"); // Snapshot: 1.17-pre5, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From df21105701c4fb7f8f55ab8a50aad08c1f321d41 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn
Date: Fri, 4 Jun 2021 17:48:45 -0400
Subject: [PATCH 28/30] Minecraft 1.17-rc1
---
.../java/com/velocitypowered/api/network/ProtocolVersion.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 68f62749f..20662ab66 100644
--- a/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
+++ b/api/src/main/java/com/velocitypowered/api/network/ProtocolVersion.java
@@ -54,7 +54,7 @@ public enum ProtocolVersion {
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_17(-1, 33, "1.17"); // Snapshot: 1.17-pre5, future protocol: 755
+ MINECRAFT_1_17(-1, 34, "1.17"); // Snapshot: 1.17-rc1, future protocol: 755
private static final int SNAPSHOT_BIT = 30;
From 59b29a075e0abe4e9aeca393975a1cfbead35ee9 Mon Sep 17 00:00:00 2001
From: FivePB
Date: Sat, 5 Jun 2021 16:07:24 +0200
Subject: [PATCH 29/30] Improve new Resource-pack API
---
.../java/com/velocitypowered/api/proxy/Player.java | 11 +++++++----
.../com/velocitypowered/api/proxy/ProxyServer.java | 10 ++++++----
.../api/proxy/player/ResourcePackInfo.java | 2 +-
.../proxy/connection/client/ConnectedPlayer.java | 3 +--
4 files changed, 15 insertions(+), 11 deletions(-)
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 d22f0caf2..51d966044 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/Player.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/Player.java
@@ -238,6 +238,8 @@ public interface Player extends CommandSource, Identified, InboundConnection,
* Queues and sends a new Resource-pack offer to the player.
* To monitor the status of the sent resource pack, subscribe to
* {@link PlayerResourcePackStatusEvent}.
+ * To create a {@link ResourcePackInfo} use the
+ * {@link ProxyServer#createResourcePackBuilder(String)} builder.
*
* @param packInfo the resource-pack in question
*/
@@ -247,16 +249,17 @@ public interface Player extends CommandSource, Identified, InboundConnection,
* Gets the {@link ResourcePackInfo} of the currently applied
* resource-pack or null if none.
*
- * @return the applied resource pack
+ * @return the applied resource pack or null if none.
*/
@Nullable
ResourcePackInfo getAppliedResourcePack();
/**
- * Gets the {@link ResourcePackInfo} of the currently accepted
- * and currently downloading resource-pack or null if none.
+ * Gets the {@link ResourcePackInfo} of the resource pack
+ * the user is currently downloading or is currently
+ * prompted to install or null if none.
*
- * @return the pending resource pack
+ * @return the pending resource pack or null if none
*/
@Nullable
ResourcePackInfo getPendingResourcePack();
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/ProxyServer.java b/api/src/main/java/com/velocitypowered/api/proxy/ProxyServer.java
index bd3430a13..6f2e518f6 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/ProxyServer.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/ProxyServer.java
@@ -225,14 +225,16 @@ public interface ProxyServer extends Audience {
*
* Note: The resource-pack location should always:
* - Use HTTPS with a valid certificate.
- * - Be in a crawler-accessible location. Having it behind Cloudflare or Cloudfront
- * may cause issues in downloading.
- * - Be in location with appropriate bandwidth so the download does not time out or fail.
+ * - Be in a crawler-accessible location. Having it behind Cloudflare or other DoS/Bot/crawler
+ * protection may cause issues in downloading.
+ * - Be on a web-server with enough bandwidth and reliable connection
+ * so the download does not time out or fail.
*
* Do also make sure that the resource pack is in the correct format for the version
* of the client. It is also highly recommended to always provide the resource-pack SHA-1 hash
* of the resource pack with {@link ResourcePackInfo.Builder#setHash(byte[])}
- * whenever possible to save bandwidth.
+ * whenever possible to save bandwidth. If a hash is present the client will first check
+ * if it already has a resource pack by that hash cached.
*
* @param url The url where the resource pack can be found
* @return a ResourcePackInfo builder
diff --git a/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java b/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java
index 067dd26ba..4643dd422 100644
--- a/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java
+++ b/api/src/main/java/com/velocitypowered/api/proxy/player/ResourcePackInfo.java
@@ -113,7 +113,7 @@ public interface ResourcePackInfo {
*/
DOWNSTREAM_SERVER,
/**
- * The player declined to download the resource pack.
+ * The resource-pack originated from a plugin on this proxy.
*/
PLUGIN_ON_PROXY
}
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 459a7ea26..26ba80c24 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
@@ -1000,9 +1000,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
}
if (!peek) {
- CompletableFuture.supplyAsync(() -> {
+ connection.eventLoop().execute(() -> {
tickResourcePackQueue();
- return true;
});
}
From 43b72ff8260b23b3e3f6c01036ab11c717da14ab Mon Sep 17 00:00:00 2001
From: Andrew Steinborn
Date: Sun, 6 Jun 2021 00:20:47 +0000
Subject: [PATCH 30/30] Apply some spelling fixes from code review
Co-authored-by: Hugo Manrique
---
.../api/event/player/PlayerResourcePackStatusEvent.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java b/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java
index a490b6791..bfd7a5ea5 100644
--- a/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java
+++ b/api/src/main/java/com/velocitypowered/api/event/player/PlayerResourcePackStatusEvent.java
@@ -27,7 +27,7 @@ public class PlayerResourcePackStatusEvent {
/**
- * Instates this event.
+ * Instantiates this event.
* @deprecated Use {@link PlayerResourcePackStatusEvent#PlayerResourcePackStatusEvent
* (Player, Status, ResourcePackInfo)} instead.
*/
@@ -39,7 +39,7 @@ public class PlayerResourcePackStatusEvent {
}
/**
- * Instates this event.
+ * Instantiates this event.
*/
public PlayerResourcePackStatusEvent(Player player, Status status, ResourcePackInfo packInfo) {
this.player = Preconditions.checkNotNull(player, "player");