Add Cookie API (#1313)
This commit is contained in:
@@ -22,6 +22,8 @@ import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.BundleDelimiterPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundStoreCookiePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
||||
@@ -45,6 +47,7 @@ import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerDataPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerboundCookieResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
||||
@@ -339,4 +342,16 @@ public interface MinecraftSessionHandler {
|
||||
default boolean handle(KnownPacksPacket packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean handle(ClientboundStoreCookiePacket packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean handle(ClientboundCookieRequestPacket packet) {
|
||||
return false;
|
||||
}
|
||||
|
||||
default boolean handle(ServerboundCookieResponsePacket packet) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,8 @@ import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.event.command.PlayerAvailableCommandsEvent;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||
import com.velocitypowered.api.event.connection.PreTransferEvent;
|
||||
import com.velocitypowered.api.event.player.CookieRequestEvent;
|
||||
import com.velocitypowered.api.event.player.CookieStoreEvent;
|
||||
import com.velocitypowered.api.event.player.PlayerResourcePackStatusEvent;
|
||||
import com.velocitypowered.api.event.player.ServerResourcePackSendEvent;
|
||||
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
|
||||
@@ -48,6 +50,8 @@ import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.BundleDelimiterPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundStoreCookiePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.LegacyPlayerListItemPacket;
|
||||
@@ -70,6 +74,7 @@ import io.netty.channel.Channel;
|
||||
import io.netty.handler.timeout.ReadTimeoutException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.regex.Pattern;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -390,6 +395,39 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ClientboundStoreCookiePacket packet) {
|
||||
server.getEventManager()
|
||||
.fire(new CookieStoreEvent(serverConn.getPlayer(), packet.getKey(), packet.getPayload()))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
final Key resultedKey = event.getResult().getKey() == null
|
||||
? event.getOriginalKey() : event.getResult().getKey();
|
||||
final byte[] resultedData = event.getResult().getData() == null
|
||||
? event.getOriginalData() : event.getResult().getData();
|
||||
|
||||
playerConnection.write(new ClientboundStoreCookiePacket(resultedKey, resultedData));
|
||||
}
|
||||
}, playerConnection.eventLoop());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ClientboundCookieRequestPacket packet) {
|
||||
server.getEventManager().fire(new CookieRequestEvent(serverConn.getPlayer(), packet.getKey()))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
final Key resultedKey = event.getResult().getKey() == null
|
||||
? event.getOriginalKey() : event.getResult().getKey();
|
||||
|
||||
playerConnection.write(new ClientboundCookieRequestPacket(resultedKey));
|
||||
}
|
||||
}, playerConnection.eventLoop());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleGeneric(MinecraftPacket packet) {
|
||||
if (packet instanceof PluginMessagePacket) {
|
||||
|
@@ -18,6 +18,8 @@
|
||||
package com.velocitypowered.proxy.connection.backend;
|
||||
|
||||
import com.velocitypowered.api.event.connection.PreTransferEvent;
|
||||
import com.velocitypowered.api.event.player.CookieRequestEvent;
|
||||
import com.velocitypowered.api.event.player.CookieStoreEvent;
|
||||
import com.velocitypowered.api.event.player.PlayerResourcePackStatusEvent;
|
||||
import com.velocitypowered.api.event.player.ServerResourcePackSendEvent;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
@@ -34,6 +36,8 @@ import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundStoreCookiePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
@@ -48,6 +52,7 @@ import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -251,6 +256,40 @@ public class ConfigSessionHandler implements MinecraftSessionHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ClientboundStoreCookiePacket packet) {
|
||||
server.getEventManager()
|
||||
.fire(new CookieStoreEvent(serverConn.getPlayer(), packet.getKey(), packet.getPayload()))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
final Key resultedKey = event.getResult().getKey() == null
|
||||
? event.getOriginalKey() : event.getResult().getKey();
|
||||
final byte[] resultedData = event.getResult().getData() == null
|
||||
? event.getOriginalData() : event.getResult().getData();
|
||||
|
||||
serverConn.getPlayer().getConnection()
|
||||
.write(new ClientboundStoreCookiePacket(resultedKey, resultedData));
|
||||
}
|
||||
}, serverConn.ensureConnected().eventLoop());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ClientboundCookieRequestPacket packet) {
|
||||
server.getEventManager().fire(new CookieRequestEvent(serverConn.getPlayer(), packet.getKey()))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
final Key resultedKey = event.getResult().getKey() == null
|
||||
? event.getOriginalKey() : event.getResult().getKey();
|
||||
|
||||
serverConn.getPlayer().getConnection().write(new ClientboundCookieRequestPacket(resultedKey));
|
||||
}
|
||||
}, serverConn.ensureConnected().eventLoop());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnected() {
|
||||
resultFuture.completeExceptionally(
|
||||
|
@@ -17,6 +17,7 @@
|
||||
|
||||
package com.velocitypowered.proxy.connection.backend;
|
||||
|
||||
import com.velocitypowered.api.event.player.CookieRequestEvent;
|
||||
import com.velocitypowered.api.event.player.ServerLoginPluginMessageEvent;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
@@ -31,6 +32,8 @@ import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults;
|
||||
import com.velocitypowered.proxy.connection.util.ConnectionRequestResults.Impl;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundStoreCookiePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginAcknowledgedPacket;
|
||||
@@ -43,6 +46,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -174,6 +178,26 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ClientboundStoreCookiePacket packet) {
|
||||
throw new IllegalStateException("Can only store cookie in CONFIGURATION or PLAY protocol");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ClientboundCookieRequestPacket packet) {
|
||||
server.getEventManager().fire(new CookieRequestEvent(serverConn.getPlayer(), packet.getKey()))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
final Key resultedKey = event.getResult().getKey() == null
|
||||
? event.getOriginalKey() : event.getResult().getKey();
|
||||
|
||||
serverConn.getPlayer().getConnection().write(new ClientboundCookieRequestPacket(resultedKey));
|
||||
}
|
||||
}, serverConn.ensureConnected().eventLoop());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exception(Throwable throwable) {
|
||||
resultFuture.completeExceptionally(throwable);
|
||||
|
@@ -24,6 +24,7 @@ import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||
import com.velocitypowered.api.event.connection.LoginEvent;
|
||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||
import com.velocitypowered.api.event.permission.PermissionsSetupEvent;
|
||||
import com.velocitypowered.api.event.player.CookieReceiveEvent;
|
||||
import com.velocitypowered.api.event.player.GameProfileRequestEvent;
|
||||
import com.velocitypowered.api.event.player.PlayerChooseInitialServerEvent;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
@@ -41,6 +42,7 @@ import com.velocitypowered.proxy.crypto.IdentifiedKeyImpl;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.packet.LoginAcknowledgedPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerboundCookieResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.Objects;
|
||||
@@ -188,6 +190,24 @@ public class AuthSessionHandler implements MinecraftSessionHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ServerboundCookieResponsePacket packet) {
|
||||
server.getEventManager()
|
||||
.fire(new CookieReceiveEvent(connectedPlayer, packet.getKey(), packet.getPayload()))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
// The received cookie must have been requested by a proxy plugin in login phase,
|
||||
// because if a backend server requests a cookie in login phase, the client is already
|
||||
// in config phase. Therefore, the only way, we receive a CookieResponsePacket from a
|
||||
// client in login phase is when a proxy plugin requested a cookie in login phase.
|
||||
throw new IllegalStateException(
|
||||
"A cookie was requested by a proxy plugin in login phase but the response wasn't handled");
|
||||
}
|
||||
}, mcConnection.eventLoop());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void completeLoginProtocolPhaseAndInitialize(ConnectedPlayer player) {
|
||||
mcConnection.setAssociation(player);
|
||||
|
||||
|
@@ -17,6 +17,7 @@
|
||||
|
||||
package com.velocitypowered.proxy.connection.client;
|
||||
|
||||
import com.velocitypowered.api.event.player.CookieReceiveEvent;
|
||||
import com.velocitypowered.api.event.player.PlayerClientBrandEvent;
|
||||
import com.velocitypowered.proxy.VelocityServer;
|
||||
import com.velocitypowered.proxy.connection.MinecraftConnection;
|
||||
@@ -32,6 +33,7 @@ import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PingIdentifyPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerboundCookieResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.FinishedUpdatePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.config.KnownPacksPacket;
|
||||
import com.velocitypowered.proxy.protocol.util.PluginMessageUtil;
|
||||
@@ -39,6 +41,7 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -144,6 +147,28 @@ public class ClientConfigSessionHandler implements MinecraftSessionHandler {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ServerboundCookieResponsePacket packet) {
|
||||
server.getEventManager()
|
||||
.fire(new CookieReceiveEvent(player, packet.getKey(), packet.getPayload()))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
final VelocityServerConnection serverConnection = player.getConnectionInFlight();
|
||||
if (serverConnection != null) {
|
||||
final Key resultedKey = event.getResult().getKey() == null
|
||||
? event.getOriginalKey() : event.getResult().getKey();
|
||||
final byte[] resultedData = event.getResult().getData() == null
|
||||
? event.getOriginalData() : event.getResult().getData();
|
||||
|
||||
serverConnection.ensureConnected()
|
||||
.write(new ServerboundCookieResponsePacket(resultedKey, resultedData));
|
||||
}
|
||||
}
|
||||
}, player.getConnection().eventLoop());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleGeneric(MinecraftPacket packet) {
|
||||
VelocityServerConnection serverConnection = player.getConnectedServer();
|
||||
|
@@ -23,6 +23,7 @@ import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.brigadier.suggestion.Suggestion;
|
||||
import com.velocitypowered.api.command.VelocityBrigadierMessage;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||
import com.velocitypowered.api.event.player.CookieReceiveEvent;
|
||||
import com.velocitypowered.api.event.player.PlayerChannelRegisterEvent;
|
||||
import com.velocitypowered.api.event.player.PlayerClientBrandEvent;
|
||||
import com.velocitypowered.api.event.player.TabCompleteEvent;
|
||||
@@ -48,6 +49,7 @@ import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ResourcePackResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerboundCookieResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.TabCompleteResponsePacket.Offer;
|
||||
@@ -83,6 +85,7 @@ import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -418,6 +421,28 @@ public class ClientPlaySessionHandler implements MinecraftSessionHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(ServerboundCookieResponsePacket packet) {
|
||||
server.getEventManager()
|
||||
.fire(new CookieReceiveEvent(player, packet.getKey(), packet.getPayload()))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
final VelocityServerConnection serverConnection = player.getConnectedServer();
|
||||
if (serverConnection != null) {
|
||||
final Key resultedKey = event.getResult().getKey() == null
|
||||
? event.getOriginalKey() : event.getResult().getKey();
|
||||
final byte[] resultedData = event.getResult().getData() == null
|
||||
? event.getOriginalData() : event.getResult().getData();
|
||||
|
||||
serverConnection.ensureConnected()
|
||||
.write(new ServerboundCookieResponsePacket(resultedKey, resultedData));
|
||||
}
|
||||
}
|
||||
}, player.getConnection().eventLoop());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleGeneric(MinecraftPacket packet) {
|
||||
VelocityServerConnection serverConnection = player.getConnectedServer();
|
||||
|
@@ -27,6 +27,8 @@ import com.google.gson.JsonObject;
|
||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||
import com.velocitypowered.api.event.connection.DisconnectEvent.LoginStatus;
|
||||
import com.velocitypowered.api.event.connection.PreTransferEvent;
|
||||
import com.velocitypowered.api.event.player.CookieRequestEvent;
|
||||
import com.velocitypowered.api.event.player.CookieStoreEvent;
|
||||
import com.velocitypowered.api.event.player.KickedFromServerEvent;
|
||||
import com.velocitypowered.api.event.player.KickedFromServerEvent.DisconnectPlayer;
|
||||
import com.velocitypowered.api.event.player.KickedFromServerEvent.Notify;
|
||||
@@ -65,6 +67,8 @@ import com.velocitypowered.proxy.connection.util.VelocityInboundConnection;
|
||||
import com.velocitypowered.proxy.protocol.StateRegistry;
|
||||
import com.velocitypowered.proxy.protocol.netty.MinecraftEncoder;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundStoreCookiePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.HeaderAndFooterPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.KeepAlivePacket;
|
||||
@@ -105,6 +109,7 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
import net.kyori.adventure.audience.MessageType;
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.permission.PermissionChecker;
|
||||
import net.kyori.adventure.platform.facet.FacetPointers;
|
||||
import net.kyori.adventure.platform.facet.FacetPointers.Type;
|
||||
@@ -1008,6 +1013,50 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player,
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeCookie(final Key key, final byte[] data) {
|
||||
Preconditions.checkNotNull(key);
|
||||
Preconditions.checkNotNull(data);
|
||||
Preconditions.checkArgument(
|
||||
this.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_20_5),
|
||||
"Player version must be at least 1.20.5 to be able to store cookies");
|
||||
|
||||
if (connection.getState() != StateRegistry.PLAY
|
||||
&& connection.getState() != StateRegistry.CONFIG) {
|
||||
throw new IllegalStateException("Can only store cookie in CONFIGURATION or PLAY protocol");
|
||||
}
|
||||
|
||||
server.getEventManager().fire(new CookieStoreEvent(this, key, data))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
final Key resultedKey = event.getResult().getKey() == null
|
||||
? event.getOriginalKey() : event.getResult().getKey();
|
||||
final byte[] resultedData = event.getResult().getData() == null
|
||||
? event.getOriginalData() : event.getResult().getData();
|
||||
|
||||
connection.write(new ClientboundStoreCookiePacket(resultedKey, resultedData));
|
||||
}
|
||||
}, connection.eventLoop());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestCookie(final Key key) {
|
||||
Preconditions.checkNotNull(key);
|
||||
Preconditions.checkArgument(
|
||||
this.getProtocolVersion().noLessThan(ProtocolVersion.MINECRAFT_1_20_5),
|
||||
"Player version must be at least 1.20.5 to be able to retrieve cookies");
|
||||
|
||||
server.getEventManager().fire(new CookieRequestEvent(this, key))
|
||||
.thenAcceptAsync(event -> {
|
||||
if (event.getResult().isAllowed()) {
|
||||
final Key resultedKey = event.getResult().getKey() == null
|
||||
? event.getOriginalKey() : event.getResult().getKey();
|
||||
|
||||
connection.write(new ClientboundCookieRequestPacket(resultedKey));
|
||||
}
|
||||
}, connection.eventLoop());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addCustomChatCompletions(@NotNull Collection<String> completions) {
|
||||
Preconditions.checkNotNull(completions, "completions");
|
||||
|
@@ -52,6 +52,8 @@ import com.velocitypowered.proxy.protocol.packet.AvailableCommandsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.BossBarPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.BundleDelimiterPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientSettingsPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundCookieRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ClientboundStoreCookiePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.DisconnectPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.EncryptionRequestPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.EncryptionResponsePacket;
|
||||
@@ -73,6 +75,7 @@ import com.velocitypowered.proxy.protocol.packet.RespawnPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerDataPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerLoginSuccessPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.ServerboundCookieResponsePacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.SetCompressionPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusPingPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.StatusRequestPacket;
|
||||
@@ -146,6 +149,9 @@ public enum StateRegistry {
|
||||
serverbound.register(
|
||||
ClientSettingsPacket.class, ClientSettingsPacket::new,
|
||||
map(0x00, MINECRAFT_1_20_2, false));
|
||||
serverbound.register(
|
||||
ServerboundCookieResponsePacket.class, ServerboundCookieResponsePacket::new,
|
||||
map(0x01, MINECRAFT_1_20_5, false));
|
||||
serverbound.register(
|
||||
PluginMessagePacket.class, PluginMessagePacket::new,
|
||||
map(0x01, MINECRAFT_1_20_2, false),
|
||||
@@ -171,6 +177,9 @@ public enum StateRegistry {
|
||||
KnownPacksPacket::new,
|
||||
map(0x07, MINECRAFT_1_20_5, false));
|
||||
|
||||
clientbound.register(
|
||||
ClientboundCookieRequestPacket.class, ClientboundCookieRequestPacket::new,
|
||||
map(0x00, MINECRAFT_1_20_5, false));
|
||||
clientbound.register(
|
||||
PluginMessagePacket.class, PluginMessagePacket::new,
|
||||
map(0x00, MINECRAFT_1_20_2, false),
|
||||
@@ -202,6 +211,9 @@ public enum StateRegistry {
|
||||
map(0x06, MINECRAFT_1_20_2, false),
|
||||
map(0x07, MINECRAFT_1_20_3, false),
|
||||
map(0x09, MINECRAFT_1_20_5, false));
|
||||
clientbound.register(
|
||||
ClientboundStoreCookiePacket.class, ClientboundStoreCookiePacket::new,
|
||||
map(0x0A, MINECRAFT_1_20_5, false));
|
||||
clientbound.register(TransferPacket.class, TransferPacket::new,
|
||||
map(0x0B, MINECRAFT_1_20_5, false));
|
||||
clientbound.register(ActiveFeaturesPacket.class, ActiveFeaturesPacket::new,
|
||||
@@ -276,6 +288,9 @@ public enum StateRegistry {
|
||||
map(0x08, MINECRAFT_1_19_4, false),
|
||||
map(0x09, MINECRAFT_1_20_2, false),
|
||||
map(0x0A, MINECRAFT_1_20_5, false));
|
||||
serverbound.register(
|
||||
ServerboundCookieResponsePacket.class, ServerboundCookieResponsePacket::new,
|
||||
map(0x11, MINECRAFT_1_20_5, false));
|
||||
serverbound.register(
|
||||
PluginMessagePacket.class,
|
||||
PluginMessagePacket::new,
|
||||
@@ -374,6 +389,9 @@ public enum StateRegistry {
|
||||
map(0x0E, MINECRAFT_1_19_3, false),
|
||||
map(0x10, MINECRAFT_1_19_4, false),
|
||||
map(0x11, MINECRAFT_1_20_2, false));
|
||||
clientbound.register(
|
||||
ClientboundCookieRequestPacket.class, ClientboundCookieRequestPacket::new,
|
||||
map(0x16, MINECRAFT_1_20_5, false));
|
||||
clientbound.register(
|
||||
PluginMessagePacket.class,
|
||||
PluginMessagePacket::new,
|
||||
@@ -595,6 +613,9 @@ public enum StateRegistry {
|
||||
map(0x3A, MINECRAFT_1_19_4, false),
|
||||
map(0x3C, MINECRAFT_1_20_2, false),
|
||||
map(0x3E, MINECRAFT_1_20_5, false));
|
||||
clientbound.register(
|
||||
ClientboundStoreCookiePacket.class, ClientboundStoreCookiePacket::new,
|
||||
map(0x6B, MINECRAFT_1_20_5, false));
|
||||
clientbound.register(
|
||||
SystemChatPacket.class,
|
||||
SystemChatPacket::new,
|
||||
@@ -654,6 +675,9 @@ public enum StateRegistry {
|
||||
serverbound.register(
|
||||
LoginAcknowledgedPacket.class, LoginAcknowledgedPacket::new,
|
||||
map(0x03, MINECRAFT_1_20_2, false));
|
||||
serverbound.register(
|
||||
ServerboundCookieResponsePacket.class, ServerboundCookieResponsePacket::new,
|
||||
map(0x04, MINECRAFT_1_20_5, false));
|
||||
|
||||
clientbound.register(
|
||||
DisconnectPacket.class, () -> new DisconnectPacket(this),
|
||||
@@ -671,6 +695,9 @@ public enum StateRegistry {
|
||||
LoginPluginMessagePacket.class,
|
||||
LoginPluginMessagePacket::new,
|
||||
map(0x04, MINECRAFT_1_13, false));
|
||||
clientbound.register(
|
||||
ClientboundCookieRequestPacket.class, ClientboundCookieRequestPacket::new,
|
||||
map(0x05, MINECRAFT_1_20_5, false));
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Velocity Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.proxy.protocol.packet;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.kyori.adventure.key.Key;
|
||||
|
||||
public class ClientboundCookieRequestPacket implements MinecraftPacket {
|
||||
|
||||
private Key key;
|
||||
|
||||
public Key getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public ClientboundCookieRequestPacket() {
|
||||
}
|
||||
|
||||
public ClientboundCookieRequestPacket(final Key key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
||||
this.key = ProtocolUtils.readKey(buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
||||
ProtocolUtils.writeKey(buf, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
return handler.handle(this);
|
||||
}
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Velocity Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.proxy.protocol.packet;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.kyori.adventure.key.Key;
|
||||
|
||||
public class ClientboundStoreCookiePacket implements MinecraftPacket {
|
||||
|
||||
private Key key;
|
||||
private byte[] payload;
|
||||
|
||||
public Key getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public byte[] getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public ClientboundStoreCookiePacket() {
|
||||
}
|
||||
|
||||
public ClientboundStoreCookiePacket(final Key key, final byte[] payload) {
|
||||
this.key = key;
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
||||
this.key = ProtocolUtils.readKey(buf);
|
||||
this.payload = ProtocolUtils.readByteArray(buf, 5120);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
||||
ProtocolUtils.writeKey(buf, key);
|
||||
ProtocolUtils.writeByteArray(buf, payload);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
return handler.handle(this);
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Velocity Contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.proxy.protocol.packet;
|
||||
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.proxy.connection.MinecraftSessionHandler;
|
||||
import com.velocitypowered.proxy.protocol.MinecraftPacket;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils;
|
||||
import com.velocitypowered.proxy.protocol.ProtocolUtils.Direction;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public class ServerboundCookieResponsePacket implements MinecraftPacket {
|
||||
|
||||
private Key key;
|
||||
private byte @Nullable [] payload;
|
||||
|
||||
public Key getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public byte @Nullable [] getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public ServerboundCookieResponsePacket() {
|
||||
}
|
||||
|
||||
public ServerboundCookieResponsePacket(final Key key, final byte @Nullable [] payload) {
|
||||
this.key = key;
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
||||
this.key = ProtocolUtils.readKey(buf);
|
||||
if (buf.readBoolean()) {
|
||||
this.payload = ProtocolUtils.readByteArray(buf, 5120);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuf buf, Direction direction, ProtocolVersion protocolVersion) {
|
||||
ProtocolUtils.writeKey(buf, key);
|
||||
final boolean hasPayload = payload != null && payload.length > 0;
|
||||
buf.writeBoolean(hasPayload);
|
||||
if (hasPayload) {
|
||||
ProtocolUtils.writeByteArray(buf, payload);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(MinecraftSessionHandler handler) {
|
||||
return handler.handle(this);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user