@@ -57,7 +57,8 @@ public enum ProtocolVersion {
|
||||
MINECRAFT_1_17(755, "1.17"),
|
||||
MINECRAFT_1_17_1(756, "1.17.1"),
|
||||
MINECRAFT_1_18(757, "1.18", "1.18.1"),
|
||||
MINECRAFT_1_18_2(758, "1.18.2");
|
||||
MINECRAFT_1_18_2(758, "1.18.2"),
|
||||
MINECRAFT_1_19(759, "1.19");
|
||||
|
||||
private static final int SNAPSHOT_BIT = 30;
|
||||
|
||||
|
@@ -7,6 +7,7 @@
|
||||
|
||||
package com.velocitypowered.api.proxy;
|
||||
|
||||
import com.velocitypowered.api.proxy.crypto.KeyIdentifiable;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
@@ -14,7 +15,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
* Allows the server to communicate with a client logging into the proxy using login plugin
|
||||
* messages.
|
||||
*/
|
||||
public interface LoginPhaseConnection extends InboundConnection {
|
||||
public interface LoginPhaseConnection extends InboundConnection, KeyIdentifiable {
|
||||
void sendLoginPluginMessage(ChannelIdentifier identifier, byte[] contents,
|
||||
MessageConsumer consumer);
|
||||
|
||||
|
@@ -9,6 +9,7 @@ package com.velocitypowered.api.proxy;
|
||||
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.event.player.PlayerResourcePackStatusEvent;
|
||||
import com.velocitypowered.api.proxy.crypto.KeyIdentifiable;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSink;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||
@@ -37,7 +38,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* Represents a player who is connected to the proxy.
|
||||
*/
|
||||
public interface Player extends CommandSource, Identified, InboundConnection,
|
||||
ChannelMessageSource, ChannelMessageSink, HoverEventSource<HoverEvent.ShowEntity>, Keyed {
|
||||
ChannelMessageSource, ChannelMessageSink, HoverEventSource<HoverEvent.ShowEntity>, Keyed, KeyIdentifiable {
|
||||
|
||||
/**
|
||||
* Returns the player's current username.
|
||||
|
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.crypto;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
/**
|
||||
* Represents session-server cross-signed dated RSA public key.
|
||||
*/
|
||||
public interface IdentifiedKey extends KeySigned {
|
||||
|
||||
/**
|
||||
* Returns RSA public key.
|
||||
* Note: this key is at least 2048 bits but may be larger.
|
||||
*
|
||||
* @return the RSA public key in question
|
||||
*/
|
||||
PublicKey getSignedPublicKey();
|
||||
|
||||
|
||||
/**
|
||||
* Validates a signature against this public key.
|
||||
* @param signature the signature data
|
||||
* @param toVerify the signed data
|
||||
*
|
||||
* @return validity of the signature
|
||||
*/
|
||||
boolean verifyDataSignature(byte[] signature, byte[]... toVerify);
|
||||
|
||||
}
|
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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.crypto;
|
||||
|
||||
/**
|
||||
* Identifies a type with a public RSA signature.
|
||||
*/
|
||||
public interface KeyIdentifiable {
|
||||
|
||||
/**
|
||||
* Returns the timed identified key of the object context.
|
||||
* <p>Only available in 1.19 and newer</p>
|
||||
* @return the key or null if not available
|
||||
*/
|
||||
IdentifiedKey getIdentifiedKey();
|
||||
}
|
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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.crypto;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.time.Instant;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
public interface KeySigned {
|
||||
|
||||
/**
|
||||
* Returns the key used to sign the object.
|
||||
*
|
||||
* @return the key
|
||||
*/
|
||||
PublicKey getSigner();
|
||||
|
||||
/**
|
||||
* Returns the expiry time point of the key.
|
||||
* Note: this limit is arbitrary. RSA keys don't expire,
|
||||
* but the signature of this key as provided by the session
|
||||
* server will expire.
|
||||
*
|
||||
* @return the expiry time point
|
||||
*/
|
||||
Instant getExpiryTemporal();
|
||||
|
||||
|
||||
/**
|
||||
* Check if the signature has expired.
|
||||
*
|
||||
* @return true if proxy time is after expiry time
|
||||
*/
|
||||
default boolean hasExpired() {
|
||||
return Instant.now().isAfter(getExpiryTemporal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the signature of the signed object.
|
||||
*
|
||||
* @return an RSA signature
|
||||
*/
|
||||
@Nullable
|
||||
byte[] getSignature();
|
||||
|
||||
/**
|
||||
* Validates the signature, expiry temporal and key against the
|
||||
* signer public key. Note: This will **not** check for
|
||||
* expiry. You can check for expiry with {@link KeySigned#hasExpired()}.
|
||||
* <p>DOES NOT WORK YET FOR MESSAGES AND COMMANDS!</p>
|
||||
*
|
||||
* @return validity of the signature
|
||||
*/
|
||||
@Beta
|
||||
default boolean isSignatureValid() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the signature salt or null if not salted.
|
||||
*
|
||||
* @return signature salt or null
|
||||
*/
|
||||
default byte[] getSalt() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.crypto;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface SignedMessage extends KeySigned {
|
||||
|
||||
/**
|
||||
* Returns the signed message.
|
||||
*
|
||||
* @return the message
|
||||
*/
|
||||
String getMessage();
|
||||
|
||||
/**
|
||||
* Returns the signers UUID.
|
||||
*
|
||||
* @return the uuid
|
||||
*/
|
||||
UUID getSignerUuid();
|
||||
|
||||
/**
|
||||
* If true the signature of this message applies to a stylized component instead.
|
||||
*
|
||||
* @return signature signs preview
|
||||
*/
|
||||
boolean isPreviewSigned();
|
||||
|
||||
}
|
@@ -8,6 +8,7 @@
|
||||
package com.velocitypowered.api.proxy.player;
|
||||
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.crypto.IdentifiedKey;
|
||||
import com.velocitypowered.api.util.GameProfile;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
@@ -80,4 +81,19 @@ public interface TabList {
|
||||
@Deprecated
|
||||
TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency,
|
||||
int gameMode);
|
||||
|
||||
/**
|
||||
* Builds a tab list entry.
|
||||
*
|
||||
* @deprecated Internal usage. Use {@link TabListEntry.Builder} instead.
|
||||
* @param profile profile
|
||||
* @param displayName display name
|
||||
* @param latency latency
|
||||
* @param gameMode game mode
|
||||
* @param key the player key
|
||||
* @return entry
|
||||
*/
|
||||
@Deprecated
|
||||
TabListEntry buildEntry(GameProfile profile, @Nullable Component displayName, int latency,
|
||||
int gameMode, @Nullable IdentifiedKey key);
|
||||
}
|
||||
|
@@ -7,6 +7,8 @@
|
||||
|
||||
package com.velocitypowered.api.proxy.player;
|
||||
|
||||
import com.velocitypowered.api.proxy.crypto.IdentifiedKey;
|
||||
import com.velocitypowered.api.proxy.crypto.KeyIdentifiable;
|
||||
import com.velocitypowered.api.util.GameProfile;
|
||||
import java.util.Optional;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@@ -15,7 +17,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
/**
|
||||
* Represents a single entry in a {@link TabList}.
|
||||
*/
|
||||
public interface TabListEntry {
|
||||
public interface TabListEntry extends KeyIdentifiable {
|
||||
|
||||
/**
|
||||
* Returns the parent {@link TabList} of this {@code this} {@link TabListEntry}.
|
||||
@@ -125,6 +127,8 @@ public interface TabListEntry {
|
||||
private int latency = 0;
|
||||
private int gameMode = 0;
|
||||
|
||||
private @Nullable IdentifiedKey playerKey;
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
||||
@@ -152,6 +156,18 @@ public interface TabListEntry {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link IdentifiedKey} of the {@link TabListEntry}.
|
||||
*
|
||||
* @param playerKey key to set
|
||||
* @return {@code this}, for chaining
|
||||
* @see TabListEntry#getIdentifiedKey()
|
||||
*/
|
||||
public Builder playerKey(IdentifiedKey playerKey) {
|
||||
this.playerKey = playerKey;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the displayed name of the {@link TabListEntry}.
|
||||
*
|
||||
@@ -200,7 +216,7 @@ public interface TabListEntry {
|
||||
if (profile == null) {
|
||||
throw new IllegalStateException("The GameProfile must be set when building a TabListEntry");
|
||||
}
|
||||
return tabList.buildEntry(profile, displayName, latency, gameMode);
|
||||
return tabList.buildEntry(profile, displayName, latency, gameMode, playerKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user