Convert Velocity buildscripts to Kotlin DSL (#918)
Spiritually indebted to #518 and @alexstaeding. There's a minor break - we're going up to 3.2.0-SNAPSHOT as the API now compiles against Java 11. But this is more academic in practice.
This commit is contained in:
119
api/build.gradle
119
api/build.gradle
@@ -1,119 +0,0 @@
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'maven-publish'
|
||||
id 'checkstyle'
|
||||
}
|
||||
|
||||
apply plugin: 'org.cadixdev.licenser'
|
||||
apply from: '../gradle/checkstyle.gradle'
|
||||
apply from: '../gradle/publish.gradle'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
license {
|
||||
header = project.file('HEADER.txt')
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
ap {
|
||||
compileClasspath += main.compileClasspath + main.output
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api 'com.google.code.gson:gson:2.9.0'
|
||||
api "com.google.guava:guava:${guavaVersion}"
|
||||
|
||||
// DEPRECATED: Will be removed in Velocity Polymer
|
||||
api 'com.moandjiezana.toml:toml4j:0.7.2'
|
||||
|
||||
api(platform("net.kyori:adventure-bom:${adventureVersion}"))
|
||||
api("net.kyori:adventure-api")
|
||||
api("net.kyori:adventure-text-serializer-gson")
|
||||
api("net.kyori:adventure-text-serializer-legacy")
|
||||
api("net.kyori:adventure-text-serializer-plain")
|
||||
api("net.kyori:adventure-text-minimessage")
|
||||
|
||||
api "org.slf4j:slf4j-api:${slf4jVersion}"
|
||||
api 'com.google.inject:guice:5.0.1'
|
||||
api "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
|
||||
api 'com.velocitypowered:velocity-brigadier:1.0.0-SNAPSHOT'
|
||||
|
||||
api "org.spongepowered:configurate-hocon:${configurateVersion}"
|
||||
api "org.spongepowered:configurate-yaml:${configurateVersion}"
|
||||
api "org.spongepowered:configurate-gson:${configurateVersion}"
|
||||
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar) {
|
||||
classifier 'javadoc'
|
||||
from javadoc
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
classifier 'sources'
|
||||
from sourceSets.main.allSource
|
||||
from sourceSets.ap.output
|
||||
}
|
||||
|
||||
jar {
|
||||
from sourceSets.ap.output
|
||||
manifest {
|
||||
attributes 'Automatic-Module-Name': 'com.velocitypowered.api'
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
from sourceSets.ap.output
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives javadocJar
|
||||
archives shadowJar
|
||||
archives sourcesJar
|
||||
}
|
||||
|
||||
javadoc {
|
||||
options.encoding = 'UTF-8'
|
||||
options.charSet = 'UTF-8'
|
||||
options.source = '8'
|
||||
options.links(
|
||||
'https://www.slf4j.org/apidocs/',
|
||||
'https://guava.dev/releases/25.1-jre/api/docs/',
|
||||
'https://google.github.io/guice/api-docs/5.0.1/javadoc/',
|
||||
'https://docs.oracle.com/en/java/javase/11/docs/api//',
|
||||
"https://jd.adventure.kyori.net/api/${adventureVersion}/"
|
||||
)
|
||||
|
||||
// Disable the crazy super-strict doclint tool in Java 8
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
|
||||
// Mark sources as Java 8 source compatible
|
||||
options.source = '8'
|
||||
|
||||
// Remove 'undefined' from seach paths when generating javadoc for a non-modular project (JDK-8215291)
|
||||
if (JavaVersion.current() >= JavaVersion.VERSION_1_9 && JavaVersion.current() < JavaVersion.VERSION_12) {
|
||||
options.addBooleanOption('-no-module-directories', true)
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
from components.java
|
||||
|
||||
artifact sourcesJar
|
||||
artifact javadocJar
|
||||
}
|
||||
}
|
||||
}
|
80
api/build.gradle.kts
Normal file
80
api/build.gradle.kts
Normal file
@@ -0,0 +1,80 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
license {
|
||||
header(project.file("HEADER.txt"))
|
||||
}
|
||||
|
||||
java {
|
||||
withJavadocJar()
|
||||
withSourcesJar()
|
||||
|
||||
sourceSets["main"].java {
|
||||
srcDir("src/ap/java")
|
||||
}
|
||||
}
|
||||
|
||||
val gsonVersion: String by project.extra
|
||||
val guiceVersion: String by project.extra
|
||||
val guavaVersion: String by project.extra
|
||||
val adventureVersion: String by project.extra
|
||||
val slf4jVersion: String by project.extra
|
||||
val checkerFrameworkVersion: String by project.extra
|
||||
val configurateVersion: String by project.extra
|
||||
|
||||
dependencies {
|
||||
api("com.google.code.gson:gson:$gsonVersion")
|
||||
api("com.google.guava:guava:$guavaVersion")
|
||||
|
||||
// DEPRECATED: Will be removed in Velocity Polymer
|
||||
api("com.moandjiezana.toml:toml4j:0.7.2")
|
||||
|
||||
api(platform("net.kyori:adventure-bom:${adventureVersion}"))
|
||||
api("net.kyori:adventure-api")
|
||||
api("net.kyori:adventure-text-serializer-gson")
|
||||
api("net.kyori:adventure-text-serializer-legacy")
|
||||
api("net.kyori:adventure-text-serializer-plain")
|
||||
api("net.kyori:adventure-text-minimessage")
|
||||
|
||||
api("org.slf4j:slf4j-api:$slf4jVersion")
|
||||
api("com.google.inject:guice:$guiceVersion")
|
||||
api("org.checkerframework:checker-qual:${checkerFrameworkVersion}")
|
||||
api("com.velocitypowered:velocity-brigadier:1.0.0-SNAPSHOT")
|
||||
|
||||
api("org.spongepowered:configurate-hocon:${configurateVersion}")
|
||||
api("org.spongepowered:configurate-yaml:${configurateVersion}")
|
||||
api("org.spongepowered:configurate-gson:${configurateVersion}")
|
||||
}
|
||||
|
||||
tasks {
|
||||
jar {
|
||||
manifest {
|
||||
attributes["Automatic-Module-Name"] = "com.velocitypowered.api"
|
||||
}
|
||||
}
|
||||
withType<Javadoc> {
|
||||
exclude("com/velocitypowered/api/plugin/ap/**")
|
||||
|
||||
val o = options as StandardJavadocDocletOptions
|
||||
o.encoding = "UTF-8"
|
||||
o.source = "8"
|
||||
|
||||
o.links(
|
||||
"https://www.slf4j.org/apidocs/",
|
||||
"https://guava.dev/releases/$guavaVersion/api/docs/",
|
||||
"https://google.github.io/guice/api-docs/$guiceVersion/javadoc/",
|
||||
"https://docs.oracle.com/en/java/javase/11/docs/api/",
|
||||
"https://jd.adventure.kyori.net/api/$adventureVersion/"
|
||||
)
|
||||
|
||||
// Disable the crazy super-strict doclint tool in Java 8
|
||||
o.addStringOption("Xdoclint:none", "-quiet")
|
||||
|
||||
// Remove "undefined" from search paths when generating javadoc for a non-modular project (JDK-8215291)
|
||||
if (JavaVersion.current() >= JavaVersion.VERSION_1_9 && JavaVersion.current() < JavaVersion.VERSION_12) {
|
||||
o.addBooleanOption("-no-module-directories", true)
|
||||
}
|
||||
}
|
||||
}
|
@@ -27,6 +27,9 @@ import javax.tools.Diagnostic;
|
||||
import javax.tools.FileObject;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
/**
|
||||
* Annotation processor for Velocity.
|
||||
*/
|
||||
@SupportedAnnotationTypes({"com.velocitypowered.api.plugin.Plugin"})
|
||||
public class PluginAnnotationProcessor extends AbstractProcessor {
|
||||
|
||||
|
@@ -19,6 +19,9 @@ import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Serialized version of {@link com.velocitypowered.api.plugin.PluginDescription}.
|
||||
*/
|
||||
public final class SerializedPluginDescription {
|
||||
|
||||
public static final Pattern ID_PATTERN = Pattern.compile("[a-z][a-z0-9-_]{0,63}");
|
||||
@@ -130,6 +133,9 @@ public final class SerializedPluginDescription {
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a dependency.
|
||||
*/
|
||||
public static final class Dependency {
|
||||
|
||||
private final String id;
|
||||
|
@@ -84,6 +84,7 @@ public interface CommandManager {
|
||||
|
||||
/**
|
||||
* Retrieves the {@link CommandMeta} from the specified command alias, if registered.
|
||||
*
|
||||
* @param alias the command alias to lookup
|
||||
* @return an {@link CommandMeta} of the alias
|
||||
*/
|
||||
|
@@ -29,6 +29,7 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
||||
|
||||
/**
|
||||
* Constructs a CommandExecuteEvent.
|
||||
*
|
||||
* @param commandSource the source executing the command
|
||||
* @param command the command being executed without first slash
|
||||
*/
|
||||
@@ -43,7 +44,8 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the original command being executed without first slash.
|
||||
* Gets the original command being executed without the first slash.
|
||||
*
|
||||
* @return the original command being executed
|
||||
*/
|
||||
public String getCommand() {
|
||||
@@ -108,6 +110,7 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
||||
|
||||
/**
|
||||
* Allows the command to be sent, without modification.
|
||||
*
|
||||
* @return the allowed result
|
||||
*/
|
||||
public static CommandResult allowed() {
|
||||
@@ -116,6 +119,7 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
||||
|
||||
/**
|
||||
* Prevents the command from being executed.
|
||||
*
|
||||
* @return the denied result
|
||||
*/
|
||||
public static CommandResult denied() {
|
||||
@@ -123,7 +127,9 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevents the command from being executed, but forward command to server.
|
||||
* Forwards the command to server instead of executing it on the proxy. This is the
|
||||
* default behavior when a command is not registered on Velocity.
|
||||
*
|
||||
* @return the forward result
|
||||
*/
|
||||
public static CommandResult forwardToServer() {
|
||||
@@ -132,6 +138,7 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
||||
|
||||
/**
|
||||
* Prevents the command from being executed on proxy, but forward command to server.
|
||||
*
|
||||
* @param newCommand the command without first slash to use instead
|
||||
* @return a result with a new command being forwarded to server
|
||||
*/
|
||||
@@ -141,7 +148,9 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the command to be executed, but silently replaced old command with another.
|
||||
* Allows the command to be executed, but silently replaces the command with a different
|
||||
* command.
|
||||
*
|
||||
* @param newCommand the command to use instead without first slash
|
||||
* @return a result with a new command
|
||||
*/
|
||||
|
@@ -29,6 +29,7 @@ public class PlayerAvailableCommandsEvent {
|
||||
|
||||
/**
|
||||
* Constructs an available commands event.
|
||||
*
|
||||
* @param player the targeted player
|
||||
* @param rootNode the Brigadier root node
|
||||
*/
|
||||
|
@@ -51,6 +51,9 @@ public final class DisconnectEvent {
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* The status of the connection when the player disconnected.
|
||||
*/
|
||||
public enum LoginStatus {
|
||||
|
||||
SUCCESSFUL_LOGIN,
|
||||
|
@@ -37,6 +37,7 @@ public final class PreLoginEvent implements ResultedEvent<PreLoginEvent.PreLogin
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param connection the connection logging into the proxy
|
||||
* @param username the player's username
|
||||
*/
|
||||
|
@@ -35,6 +35,7 @@ public final class GameProfileRequestEvent {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param connection the connection connecting to the proxy
|
||||
* @param originalProfile the original {@link GameProfile} for the user
|
||||
* @param onlineMode whether or not the user connected in online or offline mode
|
||||
|
@@ -35,6 +35,7 @@ public final class KickedFromServerEvent implements
|
||||
|
||||
/**
|
||||
* Creates a {@code KickedFromServerEvent} instance.
|
||||
*
|
||||
* @param player the player affected
|
||||
* @param server the server the player disconnected from
|
||||
* @param originalReason the reason for being kicked, optional
|
||||
|
@@ -28,6 +28,7 @@ public final class PlayerChatEvent implements ResultedEvent<PlayerChatEvent.Chat
|
||||
|
||||
/**
|
||||
* Constructs a PlayerChatEvent.
|
||||
*
|
||||
* @param player the player sending the message
|
||||
* @param message the message being sent
|
||||
*/
|
||||
@@ -96,6 +97,7 @@ public final class PlayerChatEvent implements ResultedEvent<PlayerChatEvent.Chat
|
||||
|
||||
/**
|
||||
* Allows the message to be sent, without modification.
|
||||
*
|
||||
* @return the allowed result
|
||||
*/
|
||||
public static ChatResult allowed() {
|
||||
@@ -104,6 +106,7 @@ public final class PlayerChatEvent implements ResultedEvent<PlayerChatEvent.Chat
|
||||
|
||||
/**
|
||||
* Prevents the message from being sent.
|
||||
*
|
||||
* @return the denied result
|
||||
*/
|
||||
public static ChatResult denied() {
|
||||
@@ -111,7 +114,8 @@ public final class PlayerChatEvent implements ResultedEvent<PlayerChatEvent.Chat
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the message to be sent, but silently replaced with another.
|
||||
* Allows the message to be sent, but silently replaces it with another.
|
||||
*
|
||||
* @param message the message to use instead
|
||||
* @return a result with a new message
|
||||
*/
|
||||
|
@@ -28,6 +28,7 @@ public class PlayerChooseInitialServerEvent {
|
||||
|
||||
/**
|
||||
* Constructs a PlayerChooseInitialServerEvent.
|
||||
*
|
||||
* @param player the player that was connected
|
||||
* @param initialServer the initial server selected, may be {@code null}
|
||||
*/
|
||||
@@ -46,9 +47,10 @@ public class PlayerChooseInitialServerEvent {
|
||||
|
||||
/**
|
||||
* Sets the new initial server.
|
||||
*
|
||||
* @param server the initial server the player should connect to
|
||||
*/
|
||||
public void setInitialServer(RegisteredServer server) {
|
||||
public void setInitialServer(@Nullable RegisteredServer server) {
|
||||
this.initialServer = server;
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,7 @@ public class PlayerResourcePackStatusEvent {
|
||||
|
||||
/**
|
||||
* Instantiates this event.
|
||||
*
|
||||
* @deprecated Use {@link PlayerResourcePackStatusEvent#PlayerResourcePackStatusEvent
|
||||
* (Player, Status, ResourcePackInfo)} instead.
|
||||
*/
|
||||
|
@@ -33,6 +33,7 @@ public final class ServerConnectedEvent {
|
||||
|
||||
/**
|
||||
* Constructs a ServerConnectedEvent.
|
||||
*
|
||||
* @param player the player that was connected
|
||||
* @param server the server the player was connected to
|
||||
* @param previousServer the server the player was previously connected to, null if none
|
||||
|
@@ -37,6 +37,7 @@ public class ServerLoginPluginMessageEvent implements ResultedEvent<ResponseResu
|
||||
|
||||
/**
|
||||
* Constructs a new {@code ServerLoginPluginMessageEvent}.
|
||||
*
|
||||
* @param connection the connection on which the plugin message was sent
|
||||
* @param identifier the channel identifier for the message sent
|
||||
* @param contents the contents of the message
|
||||
@@ -114,6 +115,9 @@ public class ServerLoginPluginMessageEvent implements ResultedEvent<ResponseResu
|
||||
+ '}';
|
||||
}
|
||||
|
||||
/**
|
||||
* The result class, containing a response to the login plugin message sent by the server.
|
||||
*/
|
||||
public static class ResponseResult implements ResultedEvent.Result {
|
||||
|
||||
private static final ResponseResult UNKNOWN = new ResponseResult(null);
|
||||
|
@@ -33,6 +33,7 @@ public final class ServerPreConnectEvent implements
|
||||
|
||||
/**
|
||||
* Creates the ServerPreConnectEvent.
|
||||
*
|
||||
* @param player the player who is connecting to a server
|
||||
* @param originalServer the server the player was trying to connect to
|
||||
*/
|
||||
@@ -43,6 +44,7 @@ public final class ServerPreConnectEvent implements
|
||||
|
||||
/**
|
||||
* Creates the ServerPreConnectEvent.
|
||||
*
|
||||
* @param player the player who is connecting to a server
|
||||
* @param originalServer the server the player was trying to connect to
|
||||
* @param previousServer the server the player ís connected to
|
||||
@@ -57,6 +59,7 @@ public final class ServerPreConnectEvent implements
|
||||
|
||||
/**
|
||||
* Returns the player connecting to the server.
|
||||
*
|
||||
* @return the player connecting to the server
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
@@ -77,6 +80,7 @@ public final class ServerPreConnectEvent implements
|
||||
* Returns the server that the player originally tried to connect to. To get the server the
|
||||
* player will connect to, see the {@link ServerResult} of this event. To get the server the
|
||||
* player is currently on when this event is fired, use {@link #getPreviousServer()}.
|
||||
*
|
||||
* @return the server that the player originally tried to connect to
|
||||
*/
|
||||
public RegisteredServer getOriginalServer() {
|
||||
@@ -88,6 +92,7 @@ public final class ServerPreConnectEvent implements
|
||||
* {@link Player#getCurrentServer()} as the current server might get reset after server kicks to
|
||||
* prevent connection issues. This is {@code null} if they were not connected to another server
|
||||
* beforehand (for instance, if the player has just joined the proxy).
|
||||
*
|
||||
* @return the server the player is currently connected to.
|
||||
*/
|
||||
public @Nullable RegisteredServer getPreviousServer() {
|
||||
@@ -137,6 +142,7 @@ public final class ServerPreConnectEvent implements
|
||||
* Returns a result that will prevent players from connecting to another server. If this result
|
||||
* is used, then {@link ConnectionRequestBuilder#connect()}'s result will have the status
|
||||
* {@link Status#CONNECTION_CANCELLED}.
|
||||
*
|
||||
* @return a result to deny conneections
|
||||
*/
|
||||
public static ServerResult denied() {
|
||||
@@ -145,6 +151,7 @@ public final class ServerPreConnectEvent implements
|
||||
|
||||
/**
|
||||
* Allows the player to connect to the specified server.
|
||||
*
|
||||
* @param server the new server to connect to
|
||||
* @return a result to allow the player to connect to the specified server
|
||||
*/
|
||||
|
@@ -29,6 +29,7 @@ public class TabCompleteEvent {
|
||||
|
||||
/**
|
||||
* Constructs a new TabCompleteEvent instance.
|
||||
*
|
||||
* @param player the player
|
||||
* @param partialMessage the partial message
|
||||
* @param suggestions the initial list of suggestions
|
||||
@@ -41,6 +42,7 @@ public class TabCompleteEvent {
|
||||
|
||||
/**
|
||||
* Returns the player requesting the tab completion.
|
||||
*
|
||||
* @return the requesting player
|
||||
*/
|
||||
public Player getPlayer() {
|
||||
@@ -49,6 +51,7 @@ public class TabCompleteEvent {
|
||||
|
||||
/**
|
||||
* Returns the message being partially completed.
|
||||
*
|
||||
* @return the partial message
|
||||
*/
|
||||
public String getPartialMessage() {
|
||||
@@ -57,6 +60,7 @@ public class TabCompleteEvent {
|
||||
|
||||
/**
|
||||
* Returns all the suggestions provided to the user, as a mutable list.
|
||||
*
|
||||
* @return the suggestions
|
||||
*/
|
||||
public List<String> getSuggestions() {
|
||||
|
@@ -7,6 +7,9 @@
|
||||
|
||||
package com.velocitypowered.api.plugin;
|
||||
|
||||
/**
|
||||
* Thrown if a JAR in the plugin directory does not look valid.
|
||||
*/
|
||||
public class InvalidPluginException extends Exception {
|
||||
|
||||
public InvalidPluginException() {
|
||||
|
@@ -27,6 +27,7 @@ public final class PluginDependency {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param id the plugin ID
|
||||
* @param version an optional version
|
||||
* @param optional whether or not this dependency is optional
|
||||
|
@@ -12,14 +12,33 @@ import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Allows the server to communicate with a client logging into the proxy using login plugin
|
||||
* messages.
|
||||
* Represents a connextion that is in the login phase. This is most useful in conjunction
|
||||
* for login plugin messages.
|
||||
*/
|
||||
public interface LoginPhaseConnection extends InboundConnection, KeyIdentifiable {
|
||||
|
||||
/**
|
||||
* Sends a login plugin message to the client, and provides a consumer to react to the
|
||||
* response to the client. The login process will not continue until there are no more
|
||||
* login plugin messages that require responses.
|
||||
*
|
||||
* @param identifier the channel identifier to use
|
||||
* @param contents the message to send
|
||||
* @param consumer the consumer that will respond to the message
|
||||
*/
|
||||
void sendLoginPluginMessage(ChannelIdentifier identifier, byte[] contents,
|
||||
MessageConsumer consumer);
|
||||
|
||||
/**
|
||||
* Consumes the message.
|
||||
*/
|
||||
interface MessageConsumer {
|
||||
|
||||
/**
|
||||
* Consumes the message and responds to it.
|
||||
*
|
||||
* @param responseBody the message from the client, if any
|
||||
*/
|
||||
void onMessageResponse(byte @Nullable [] responseBody);
|
||||
}
|
||||
}
|
||||
|
@@ -32,13 +32,17 @@ import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.HoverEvent;
|
||||
import net.kyori.adventure.text.event.HoverEventSource;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
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, KeyIdentifiable {
|
||||
public interface Player extends
|
||||
/* Fundamental Velocity interfaces */
|
||||
CommandSource, InboundConnection, ChannelMessageSource, ChannelMessageSink,
|
||||
/* Adventure-specific interfaces */
|
||||
Identified, HoverEventSource<HoverEvent.ShowEntity>, Keyed, KeyIdentifiable {
|
||||
|
||||
/**
|
||||
* Returns the player's current username.
|
||||
@@ -48,8 +52,8 @@ public interface Player extends CommandSource, Identified, InboundConnection,
|
||||
String getUsername();
|
||||
|
||||
/**
|
||||
* Returns the locale the proxy will use to send messages translated via the Adventure global translator.
|
||||
* By default, the value of {@link PlayerSettings#getLocale()} is used.
|
||||
* Returns the locale the proxy will use to send messages translated via the Adventure global
|
||||
* translator. By default, the value of {@link PlayerSettings#getLocale()} is used.
|
||||
*
|
||||
* <p>This can be {@code null} when the client has not yet connected to any server.</p>
|
||||
*
|
||||
|
@@ -30,6 +30,7 @@ public interface IdentifiedKey extends KeySigned {
|
||||
|
||||
/**
|
||||
* Validates a signature against this public key.
|
||||
*
|
||||
* @param signature the signature data
|
||||
* @param toVerify the signed data
|
||||
*
|
||||
@@ -53,6 +54,9 @@ public interface IdentifiedKey extends KeySigned {
|
||||
*/
|
||||
Revision getKeyRevision();
|
||||
|
||||
/**
|
||||
* The different versions of player keys, per Minecraft version.
|
||||
*/
|
||||
enum Revision {
|
||||
GENERIC_V1(ImmutableSet.of(), ImmutableSet.of(ProtocolVersion.MINECRAFT_1_19)),
|
||||
LINKED_V2(ImmutableSet.of(), ImmutableSet.of(ProtocolVersion.MINECRAFT_1_19_1));
|
||||
|
@@ -7,15 +7,18 @@
|
||||
|
||||
package com.velocitypowered.api.proxy.crypto;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* Returns the timed identified key of the object context. This is only available if the client
|
||||
* is running Minecraft 1.19 or newer.
|
||||
*
|
||||
* @return the key or null if not available
|
||||
*/
|
||||
IdentifiedKey getIdentifiedKey();
|
||||
@Nullable IdentifiedKey getIdentifiedKey();
|
||||
}
|
||||
|
@@ -12,6 +12,9 @@ import java.security.PublicKey;
|
||||
import java.time.Instant;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Represents the signature of a signed object.
|
||||
*/
|
||||
public interface KeySigned {
|
||||
|
||||
/**
|
||||
|
@@ -9,6 +9,9 @@ package com.velocitypowered.api.proxy.crypto;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A signed message.
|
||||
*/
|
||||
public interface SignedMessage extends KeySigned {
|
||||
|
||||
/**
|
||||
|
@@ -7,7 +7,8 @@
|
||||
|
||||
package com.velocitypowered.api.proxy.messages;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -49,13 +50,16 @@ public final class MinecraftChannelIdentifier implements ChannelIdentifier {
|
||||
* @return a new channel identifier
|
||||
*/
|
||||
public static MinecraftChannelIdentifier create(String namespace, String name) {
|
||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace is null or empty");
|
||||
Preconditions.checkArgument(name != null, "namespace is null or empty");
|
||||
Preconditions.checkArgument(VALID_IDENTIFIER_REGEX.matcher(namespace).matches(),
|
||||
"namespace is not valid, must match: %s got %s", VALID_IDENTIFIER_REGEX.toString(), namespace);
|
||||
Preconditions
|
||||
.checkArgument(VALID_IDENTIFIER_REGEX.matcher(name).matches(),
|
||||
"name is not valid, must match: %s got %s", VALID_IDENTIFIER_REGEX.toString(), name);
|
||||
checkArgument(!Strings.isNullOrEmpty(namespace), "namespace is null or empty");
|
||||
checkArgument(name != null, "namespace is null or empty");
|
||||
checkArgument(VALID_IDENTIFIER_REGEX.matcher(namespace).matches(),
|
||||
"namespace is not valid, must match: %s got %s",
|
||||
VALID_IDENTIFIER_REGEX.toString(),
|
||||
namespace);
|
||||
checkArgument(VALID_IDENTIFIER_REGEX.matcher(name).matches(),
|
||||
"name is not valid, must match: %s got %s",
|
||||
VALID_IDENTIFIER_REGEX.toString(),
|
||||
name);
|
||||
return new MinecraftChannelIdentifier(namespace, name);
|
||||
}
|
||||
|
||||
|
@@ -67,12 +67,18 @@ public interface PlayerSettings {
|
||||
*/
|
||||
boolean isClientListingAllowed();
|
||||
|
||||
/**
|
||||
* The client's current chat display mode.
|
||||
*/
|
||||
enum ChatMode {
|
||||
SHOWN,
|
||||
COMMANDS_ONLY,
|
||||
HIDDEN
|
||||
}
|
||||
|
||||
/**
|
||||
* The player's selected dominant hand.
|
||||
*/
|
||||
enum MainHand {
|
||||
LEFT,
|
||||
RIGHT
|
||||
|
@@ -10,6 +10,9 @@ package com.velocitypowered.api.proxy.player;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Represents the information for a resource pack to apply that can be sent to the client.
|
||||
*/
|
||||
public interface ResourcePackInfo {
|
||||
|
||||
/**
|
||||
@@ -75,12 +78,12 @@ public interface ResourcePackInfo {
|
||||
ResourcePackInfo.Builder asBuilder();
|
||||
|
||||
/**
|
||||
* Returns a copy of this {@link ResourcePackInfo} instance as a builder with the new URL as the pack URL so that
|
||||
* it can be modified.
|
||||
* Returns a copy of this {@link ResourcePackInfo} instance as a builder, using the new URL.
|
||||
* <p/>
|
||||
* It is <b>not</b> guaranteed that
|
||||
* {@code resourcePackInfo.asBuilder(resourcePackInfo.getUrl()).build().equals(resourcePackInfo)} is true.
|
||||
* That is due to the transient {@link ResourcePackInfo#getOrigin()} and
|
||||
* {@link ResourcePackInfo#getOriginalOrigin()} fields.
|
||||
* {@code resourcePackInfo.asBuilder(resourcePackInfo.getUrl()).build().equals(resourcePackInfo)}
|
||||
* is true, because the {@link ResourcePackInfo#getOrigin()} and
|
||||
* {@link ResourcePackInfo#getOriginalOrigin()} fields are transient.
|
||||
*
|
||||
* @param newUrl The new URL to use in the updated builder.
|
||||
*
|
||||
@@ -88,6 +91,9 @@ public interface ResourcePackInfo {
|
||||
*/
|
||||
ResourcePackInfo.Builder asBuilder(String newUrl);
|
||||
|
||||
/**
|
||||
* Builder for {@link ResourcePackInfo} instances.
|
||||
*/
|
||||
interface Builder {
|
||||
|
||||
/**
|
||||
|
@@ -10,6 +10,9 @@ package com.velocitypowered.api.proxy.player;
|
||||
import java.util.Objects;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Represents what, if any, extended parts of the skin this player has.
|
||||
*/
|
||||
public final class SkinParts {
|
||||
|
||||
private final byte bitmask;
|
||||
|
@@ -121,7 +121,7 @@ public interface TabListEntry extends KeyIdentifiable {
|
||||
TabListEntry setGameMode(int gameMode);
|
||||
|
||||
/**
|
||||
* Whether or not the entry is listed, when listed they will be visible to other players in the tab list.
|
||||
* Returns whether or not this player will be visible to other players in the tab list.
|
||||
*
|
||||
* @return Whether this entry is listed; only changeable in 1.19.3 and above
|
||||
*/
|
||||
@@ -193,7 +193,7 @@ public interface TabListEntry extends KeyIdentifiable {
|
||||
|
||||
/**
|
||||
* Sets the {@link IdentifiedKey} of the {@link TabListEntry}.
|
||||
* <p>This is only intended and only works for players currently <b>not</b> connected to this proxy.</p>
|
||||
* <p>This only works for players currently <b>not</b> connected to this proxy.</p>
|
||||
* <p>For any player currently connected to this proxy this will be filled automatically.</p>
|
||||
* <p>Will ignore mismatching key revisions data.</p>
|
||||
*
|
||||
|
@@ -245,6 +245,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Sets the hostname for the response.
|
||||
*
|
||||
* @param hostname the hostname to set
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@@ -255,6 +256,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Sets the game version for the response.
|
||||
*
|
||||
* @param gameVersion the game version to set
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@@ -265,6 +267,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Sets the map that will appear in the response.
|
||||
*
|
||||
* @param map the map to set
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@@ -275,6 +278,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Sets the players that are currently claimed to be online.
|
||||
*
|
||||
* @param currentPlayers a non-negative number representing all players online
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@@ -286,6 +290,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Sets the maximum number of players this server purportedly can hold.
|
||||
*
|
||||
* @param maxPlayers a non-negative number representing the maximum number of builders
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@@ -297,6 +302,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Sets the host where this proxy is running.
|
||||
*
|
||||
* @param proxyHost the host where the proxy is running
|
||||
* @return this instance, for chaining
|
||||
*/
|
||||
@@ -307,6 +313,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Sets the port where this proxy is running.
|
||||
*
|
||||
* @param proxyPort the port where the proxy is running
|
||||
* @return this instance, for chaining
|
||||
*/
|
||||
@@ -319,6 +326,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Adds the specified players to the player list.
|
||||
*
|
||||
* @param players the players to add
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@@ -329,6 +337,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Adds the specified players to the player list.
|
||||
*
|
||||
* @param players the players to add
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@@ -339,6 +348,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Removes all players from the builder. This does not affect {@link #getCurrentPlayers()}.
|
||||
*
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
public Builder clearPlayers() {
|
||||
@@ -348,6 +358,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Sets the proxy version.
|
||||
*
|
||||
* @param proxyVersion the proxy version to set
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@@ -358,6 +369,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Adds the specified plugins to the plugins list.
|
||||
*
|
||||
* @param plugins the plugins to add
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
@@ -368,6 +380,7 @@ public final class QueryResponse {
|
||||
|
||||
/**
|
||||
* Adds the specified plugins to the plugins list.
|
||||
*
|
||||
* @param plugins the plugins to add
|
||||
* @return this builder, for chaining
|
||||
*/
|
||||
|
@@ -191,6 +191,7 @@ public final class ServerPing {
|
||||
|
||||
/**
|
||||
* Uses the modified {@code mods} list in the response.
|
||||
*
|
||||
* @param mods the mods list to use
|
||||
* @return this build, for chaining
|
||||
*/
|
||||
@@ -240,6 +241,7 @@ public final class ServerPing {
|
||||
/**
|
||||
* Uses the information from this builder to create a new {@link ServerPing} instance. The
|
||||
* builder can be re-used after this event has been called.
|
||||
*
|
||||
* @return a new {@link ServerPing} instance
|
||||
*/
|
||||
public ServerPing build() {
|
||||
@@ -303,6 +305,12 @@ public final class ServerPing {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the version of the server sent to the client. A protocol version
|
||||
* that does not match the client's protocol version will show up on the server
|
||||
* list as an incompatible version, but the client will still permit the user
|
||||
* to connect to the server anyway.
|
||||
*/
|
||||
public static final class Version {
|
||||
|
||||
private final int protocol;
|
||||
@@ -310,6 +318,7 @@ public final class ServerPing {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param protocol the protocol version as an integer
|
||||
* @param name a friendly name for the protocol version
|
||||
*/
|
||||
@@ -352,6 +361,10 @@ public final class ServerPing {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents what the players the server purports to have online, its maximum capacity,
|
||||
* and a sample of players on the server.
|
||||
*/
|
||||
public static final class Players {
|
||||
|
||||
private final int online;
|
||||
@@ -360,6 +373,7 @@ public final class ServerPing {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param online the number of online players
|
||||
* @param max the maximum number of players
|
||||
* @param sample a sample of players on the server
|
||||
@@ -410,6 +424,9 @@ public final class ServerPing {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A player returned in the sample field of the server ping players field.
|
||||
*/
|
||||
public static final class SamplePlayer {
|
||||
|
||||
private final String name;
|
||||
|
@@ -7,6 +7,9 @@
|
||||
|
||||
package com.velocitypowered.api.scheduler;
|
||||
|
||||
/**
|
||||
* Enumerates all possible task statuses.
|
||||
*/
|
||||
public enum TaskStatus {
|
||||
/**
|
||||
* The task is scheduled and is currently running.
|
||||
|
@@ -24,6 +24,7 @@ public final class GameProfile {
|
||||
|
||||
/**
|
||||
* Creates a new Mojang game profile.
|
||||
*
|
||||
* @param id the UUID for the profile
|
||||
* @param name the profile's username
|
||||
* @param properties properties for the profile
|
||||
@@ -35,6 +36,7 @@ public final class GameProfile {
|
||||
|
||||
/**
|
||||
* Creates a new Mojang game profile.
|
||||
*
|
||||
* @param undashedId the undashed, Mojang-style UUID for the profile
|
||||
* @param name the profile's username
|
||||
* @param properties properties for the profile
|
||||
@@ -53,6 +55,7 @@ public final class GameProfile {
|
||||
|
||||
/**
|
||||
* Returns the undashed, Mojang-style UUID.
|
||||
*
|
||||
* @return the undashed UUID
|
||||
*/
|
||||
public String getUndashedId() {
|
||||
@@ -61,6 +64,7 @@ public final class GameProfile {
|
||||
|
||||
/**
|
||||
* Returns the UUID associated with this game profile.
|
||||
*
|
||||
* @return the UUID
|
||||
*/
|
||||
public UUID getId() {
|
||||
@@ -69,6 +73,7 @@ public final class GameProfile {
|
||||
|
||||
/**
|
||||
* Returns the username associated with this profile.
|
||||
*
|
||||
* @return the username
|
||||
*/
|
||||
public String getName() {
|
||||
@@ -77,6 +82,7 @@ public final class GameProfile {
|
||||
|
||||
/**
|
||||
* Returns an immutable list of profile properties associated with this profile.
|
||||
*
|
||||
* @return the properties associated with this profile
|
||||
*/
|
||||
public List<Property> getProperties() {
|
||||
@@ -183,6 +189,7 @@ public final class GameProfile {
|
||||
|
||||
/**
|
||||
* Creates a profile property entry.
|
||||
*
|
||||
* @param name the name of the property
|
||||
* @param value the value of the property
|
||||
* @param signature the Mojang signature for the property
|
||||
|
@@ -13,6 +13,9 @@ import com.google.gson.annotations.SerializedName;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents the information for a Forge mod list.
|
||||
*/
|
||||
public final class ModInfo {
|
||||
|
||||
public static final ModInfo DEFAULT = new ModInfo("FML", ImmutableList.of());
|
||||
@@ -20,6 +23,12 @@ public final class ModInfo {
|
||||
private final String type;
|
||||
private final List<Mod> modList;
|
||||
|
||||
/**
|
||||
* Constructs a new ModInfo instance.
|
||||
*
|
||||
* @param type the Forge server list version to use
|
||||
* @param modList the mods to present to the client
|
||||
*/
|
||||
public ModInfo(String type, List<Mod> modList) {
|
||||
this.type = Preconditions.checkNotNull(type, "type");
|
||||
this.modList = ImmutableList.copyOf(modList);
|
||||
@@ -58,6 +67,9 @@ public final class ModInfo {
|
||||
return Objects.hash(type, modList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a mod to send to the client.
|
||||
*/
|
||||
public static final class Mod {
|
||||
|
||||
@SerializedName("modid")
|
||||
|
59
build.gradle
59
build.gradle
@@ -1,59 +0,0 @@
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'com.github.johnrengelman.shadow' version '7.1.0' apply false
|
||||
id 'org.cadixdev.licenser' version '0.6.1' apply false
|
||||
}
|
||||
|
||||
allprojects {
|
||||
group 'com.velocitypowered'
|
||||
version '3.1.2-SNAPSHOT'
|
||||
|
||||
ext {
|
||||
// dependency versions
|
||||
adventureVersion = '4.12.0'
|
||||
junitVersion = '5.9.0'
|
||||
slf4jVersion = '1.7.30'
|
||||
log4jVersion = '2.19.0'
|
||||
nettyVersion = '4.1.86.Final'
|
||||
guavaVersion = '25.1-jre'
|
||||
checkerFrameworkVersion = '3.6.1'
|
||||
configurateVersion = '3.7.3'
|
||||
|
||||
getCurrentShortRevision = {
|
||||
new ByteArrayOutputStream().withStream { os ->
|
||||
exec {
|
||||
executable = "git"
|
||||
args = ["rev-parse", "HEAD"]
|
||||
standardOutput = os
|
||||
}
|
||||
return os.toString().trim().substring(0, 8)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
|
||||
// for kyoripowered dependencies
|
||||
maven {
|
||||
url 'https://oss.sonatype.org/content/groups/public/'
|
||||
}
|
||||
|
||||
// Velocity repo
|
||||
maven {
|
||||
url "https://nexus.velocitypowered.com/repository/maven-public/"
|
||||
}
|
||||
}
|
||||
|
||||
test {
|
||||
reports {
|
||||
junitXml.required = true
|
||||
}
|
||||
}
|
||||
}
|
47
build.gradle.kts
Normal file
47
build.gradle.kts
Normal file
@@ -0,0 +1,47 @@
|
||||
import com.velocitypowered.script.VelocityCheckstylePlugin
|
||||
import com.velocitypowered.script.VelocityPublishPlugin
|
||||
import org.cadixdev.gradle.licenser.Licenser
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
id("org.cadixdev.licenser") version "0.6.1"
|
||||
}
|
||||
|
||||
val junitVersion: String by project.extra
|
||||
|
||||
subprojects {
|
||||
group = "com.velocitypowered"
|
||||
version = "3.2.0-SNAPSHOT"
|
||||
|
||||
apply<JavaLibraryPlugin>()
|
||||
apply<Licenser>()
|
||||
|
||||
apply<VelocityCheckstylePlugin>()
|
||||
apply<VelocityPublishPlugin>()
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(11))
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
// kyoripowered
|
||||
maven("https://oss.sonatype.org/content/groups/public/")
|
||||
// velocity
|
||||
maven("https://nexus.velocitypowered.com/repository/maven-public/")
|
||||
}
|
||||
dependencies {
|
||||
testImplementation("org.junit.jupiter:junit-jupiter:$junitVersion")
|
||||
}
|
||||
|
||||
tasks {
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
reports {
|
||||
junitXml.required.set(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
27
buildSrc/build.gradle.kts
Normal file
27
buildSrc/build.gradle.kts
Normal file
@@ -0,0 +1,27 @@
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
checkstyle
|
||||
id("net.kyori.indra.publishing") version "2.0.6"
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://plugins.gradle.org/m2")
|
||||
}
|
||||
|
||||
gradlePlugin {
|
||||
plugins {
|
||||
register("set-manifest-impl-version") {
|
||||
id = "set-manifest-impl-version"
|
||||
implementationClass = "com.velocitypowered.script.SetManifestImplVersionPlugin"
|
||||
}
|
||||
register("velocity-checkstyle") {
|
||||
id = "velocity-checkstyle"
|
||||
implementationClass = "com.velocitypowered.script.VelocityCheckstylePlugin"
|
||||
}
|
||||
register("velocity-publish") {
|
||||
id = "velocity-publish"
|
||||
implementationClass = "com.velocitypowered.script.VelocityPublishPlugin"
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.script
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.jvm.tasks.Jar
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
class SetManifestImplVersionPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) = target.afterEvaluate { configure() }
|
||||
private fun Project.configure() {
|
||||
val currentShortRevision = ByteArrayOutputStream().use {
|
||||
exec {
|
||||
executable = "git"
|
||||
args = listOf("rev-parse", "HEAD")
|
||||
standardOutput = it
|
||||
}
|
||||
it.toString().trim().substring(0, 8)
|
||||
}
|
||||
tasks.withType<Jar> {
|
||||
manifest {
|
||||
val buildNumber = System.getenv("BUILD_NUMBER")
|
||||
var velocityHumanVersion: String
|
||||
if (project.version.toString().endsWith("-SNAPSHOT")) {
|
||||
if (buildNumber != null) {
|
||||
velocityHumanVersion = "${project.version} (git-$currentShortRevision-b$buildNumber)"
|
||||
} else {
|
||||
velocityHumanVersion = "${project.version} (git-$currentShortRevision)"
|
||||
}
|
||||
} else {
|
||||
velocityHumanVersion = archiveVersion.get()
|
||||
}
|
||||
attributes["Implementation-Version"] = velocityHumanVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.script
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.plugins.quality.CheckstyleExtension
|
||||
import org.gradle.api.plugins.quality.CheckstylePlugin
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
|
||||
class VelocityCheckstylePlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) = target.configure()
|
||||
private fun Project.configure() {
|
||||
apply<CheckstylePlugin>()
|
||||
extensions.configure<CheckstyleExtension> {
|
||||
configFile = project.rootProject.file("config/checkstyle/checkstyle.xml")
|
||||
maxErrors = 0
|
||||
maxWarnings = 0
|
||||
toolVersion = "10.6.0"
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.velocitypowered.script
|
||||
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.repositories.PasswordCredentials
|
||||
import org.gradle.api.plugins.JavaBasePlugin
|
||||
import org.gradle.api.plugins.JavaPluginExtension
|
||||
import org.gradle.api.publish.PublishingExtension
|
||||
import org.gradle.api.publish.maven.MavenPublication
|
||||
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
|
||||
import org.gradle.kotlin.dsl.apply
|
||||
import org.gradle.kotlin.dsl.configure
|
||||
import org.gradle.kotlin.dsl.create
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.getByType
|
||||
|
||||
class VelocityPublishPlugin : Plugin<Project> {
|
||||
override fun apply(target: Project) = target.afterEvaluate {
|
||||
if (target.name != "velocity-proxy") {
|
||||
configure()
|
||||
}
|
||||
}
|
||||
private fun Project.configure() {
|
||||
apply<JavaBasePlugin>()
|
||||
apply<MavenPublishPlugin>()
|
||||
extensions.configure<PublishingExtension> {
|
||||
repositories {
|
||||
maven {
|
||||
credentials(PasswordCredentials::class.java)
|
||||
|
||||
name = "paper"
|
||||
val base = "https://papermc.io/repo/repository/maven-"
|
||||
val releasesRepoUrl = "$base-releases/"
|
||||
val snapshotsRepoUrl = "$base-snapshots/"
|
||||
setUrl(if (version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl)
|
||||
}
|
||||
}
|
||||
publications {
|
||||
create<MavenPublication>("maven") {
|
||||
from(components["java"])
|
||||
pom {
|
||||
name.set("Velocity")
|
||||
description.set("The modern, next-generation Minecraft server proxy")
|
||||
url.set("https://www.velocitypowered.com")
|
||||
scm {
|
||||
url.set("https://github.com/PaperMC/Velocity")
|
||||
connection.set("scm:git:https://github.com/PaperMC/Velocity.git")
|
||||
developerConnection.set("scm:git:https://github.com/PaperMC/Velocity.git")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -16,10 +16,9 @@
|
||||
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
|
||||
-->
|
||||
|
||||
<!--
|
||||
Developer notes: Fix MissingJavadocMethod/Type RequireEmptyLineBeforeBlockTagGroup and CustomImportOrder
|
||||
-->
|
||||
<module name="Checker">
|
||||
<module name="SuppressWarningsFilter"/>
|
||||
|
||||
<property name="charset" value="UTF-8"/>
|
||||
|
||||
<property name="severity" value="warning"/>
|
||||
@@ -45,7 +44,7 @@
|
||||
|
||||
<module name="LineLength">
|
||||
<property name="fileExtensions" value="java"/>
|
||||
<property name="max" value="120"/>
|
||||
<property name="max" value="100"/>
|
||||
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||
</module>
|
||||
|
||||
@@ -105,13 +104,7 @@
|
||||
<property name="query" value="//RCURLY[parent::SLIST[count(./*)=1]
|
||||
or preceding-sibling::*[last()][self::LCURLY]]"/>
|
||||
</module>
|
||||
<module name="WhitespaceAfter">
|
||||
<property name="tokens"
|
||||
value="COMMA, SEMI, TYPECAST, LITERAL_IF, LITERAL_ELSE, LITERAL_RETURN,
|
||||
LITERAL_WHILE, LITERAL_DO, LITERAL_FOR, LITERAL_FINALLY, DO_WHILE, ELLIPSIS,
|
||||
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_CATCH, LAMBDA,
|
||||
LITERAL_YIELD, LITERAL_CASE"/>
|
||||
</module>
|
||||
<module name="WhitespaceAfter" />
|
||||
<module name="WhitespaceAround">
|
||||
<property name="allowEmptyConstructors" value="true"/>
|
||||
<property name="allowEmptyLambdas" value="true"/>
|
||||
@@ -261,7 +254,7 @@
|
||||
</module>
|
||||
<module name="AbbreviationAsWordInName">
|
||||
<property name="ignoreFinal" value="false"/>
|
||||
<property name="allowedAbbreviationLength" value="1"/>
|
||||
<property name="allowedAbbreviationLength" value="0"/>
|
||||
<property name="tokens"
|
||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,
|
||||
PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF, PATTERN_VARIABLE_DEF, RECORD_DEF,
|
||||
@@ -321,8 +314,7 @@
|
||||
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
|
||||
</module>
|
||||
<module name="JavadocParagraph"/>
|
||||
<!-- <module name="RequireEmptyLineBeforeBlockTagGroup"/>
|
||||
-->
|
||||
<module name="RequireEmptyLineBeforeBlockTagGroup"/>
|
||||
<module name="AtclauseOrder">
|
||||
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
|
||||
<property name="target"
|
||||
@@ -335,7 +327,7 @@
|
||||
<property name="allowedAnnotations" value="Override, Test"/>
|
||||
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, COMPACT_CTOR_DEF"/>
|
||||
</module>
|
||||
<!-- <module name="MissingJavadocMethod">
|
||||
<module name="MissingJavadocMethod">
|
||||
<property name="scope" value="public"/>
|
||||
<property name="minLineCount" value="2"/>
|
||||
<property name="allowedAnnotations" value="Override, Test"/>
|
||||
@@ -349,9 +341,8 @@
|
||||
RECORD_DEF, ANNOTATION_DEF"/>
|
||||
<property name="excludeScope" value="nothing"/>
|
||||
</module>
|
||||
-->
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9_]*$"/>
|
||||
<property name="format" value="^[a-z][a-z0-9]\w*$"/>
|
||||
<message key="name.invalidPattern"
|
||||
value="Method name ''{0}'' must match pattern ''{1}''."/>
|
||||
</module>
|
||||
@@ -368,5 +359,18 @@
|
||||
default="checkstyle-xpath-suppressions.xml" />
|
||||
<property name="optional" value="true"/>
|
||||
</module>
|
||||
<module name="SuppressWarningsHolder" />
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)" />
|
||||
<property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)" />
|
||||
<property name="checkFormat" value="$1" />
|
||||
</module>
|
||||
<module name="SuppressWithNearbyCommentFilter">
|
||||
<property name="commentFormat" value="CHECKSTYLE.SUPPRESS\: ([\w\|]+)"/>
|
||||
<!-- $1 refers to the first match group in the regex defined in commentFormat -->
|
||||
<property name="checkFormat" value="$1"/>
|
||||
<!-- The check is suppressed in the next line of code after the comment -->
|
||||
<property name="influenceFormat" value="1"/>
|
||||
</module>
|
||||
</module>
|
||||
</module>
|
||||
|
26
gradle.properties
Normal file
26
gradle.properties
Normal file
@@ -0,0 +1,26 @@
|
||||
# API dependencies.
|
||||
gsonVersion=2.9.0
|
||||
junitVersion=5.9.0
|
||||
slf4jVersion=1.7.30
|
||||
adventureVersion=4.12.0
|
||||
guavaVersion=25.1-jre
|
||||
checkerFrameworkVersion=3.6.1
|
||||
configurateVersion=3.7.3
|
||||
guiceVersion=5.0.1
|
||||
|
||||
# Proxy dependencies.
|
||||
log4jVersion=2.19.0
|
||||
nettyVersion=4.1.86.Final
|
||||
flareVersion=2.0.1
|
||||
asyncHttpClientVersion=2.12.3
|
||||
bstatsVersion=2.2.1
|
||||
caffeineVersion=3.1.1
|
||||
lmbdaVersion=2.0.0
|
||||
nightConfigVersion=3.6.4
|
||||
completableFuturesVersion=0.3.5
|
||||
adventureFacetVersion=4.1.2
|
||||
fastutilVersion=8.5.8
|
||||
disruptorVersion=3.4.4
|
||||
jansiVersion=3.21.0
|
||||
terminalConsoleAppenderVersion=1.3.0
|
||||
joptSimpleVersion=5.0.4
|
@@ -1,8 +0,0 @@
|
||||
checkstyle {
|
||||
toolVersion '10.3.1'
|
||||
configFile new File(project.rootDir, ['config', 'checkstyle', 'checkstyle.xml'].join(File.separator))
|
||||
|
||||
// The build should immediately fail if we have errors.
|
||||
maxErrors = 0
|
||||
maxWarnings = 0
|
||||
}
|
@@ -1,13 +0,0 @@
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
credentials(PasswordCredentials.class)
|
||||
|
||||
name = 'paper'
|
||||
def base = 'https://papermc.io/repo/repository/maven'
|
||||
def releasesRepoUrl = "$base-releases/"
|
||||
def snapshotsRepoUrl = "$base-snapshots/"
|
||||
url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,39 +0,0 @@
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'checkstyle'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
apply plugin: 'org.cadixdev.licenser'
|
||||
apply from: '../gradle/checkstyle.gradle'
|
||||
apply from: '../gradle/publish.gradle'
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
license {
|
||||
header = project.rootProject.file('HEADER.txt')
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "com.google.guava:guava:${guavaVersion}"
|
||||
implementation "io.netty:netty-handler:${nettyVersion}"
|
||||
implementation "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
|
||||
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
from components.java
|
||||
}
|
||||
}
|
||||
}
|
18
native/build.gradle.kts
Normal file
18
native/build.gradle.kts
Normal file
@@ -0,0 +1,18 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
`maven-publish`
|
||||
}
|
||||
|
||||
license {
|
||||
header(project.rootProject.file("HEADER.txt"))
|
||||
}
|
||||
|
||||
val guavaVersion: String by project.extra
|
||||
val nettyVersion: String by project.extra
|
||||
val checkerFrameworkVersion: String by project.extra
|
||||
|
||||
dependencies {
|
||||
implementation("com.google.guava:guava:${guavaVersion}")
|
||||
implementation("io.netty:netty-handler:${nettyVersion}")
|
||||
implementation("org.checkerframework:checker-qual:${checkerFrameworkVersion}")
|
||||
}
|
@@ -19,6 +19,9 @@ package com.velocitypowered.natives;
|
||||
|
||||
import com.velocitypowered.natives.util.BufferPreference;
|
||||
|
||||
/**
|
||||
* Generic interface for any Velocity native.
|
||||
*/
|
||||
public interface Native {
|
||||
BufferPreference preferredBufferType();
|
||||
}
|
||||
|
@@ -17,6 +17,9 @@
|
||||
|
||||
package com.velocitypowered.natives;
|
||||
|
||||
/**
|
||||
* Thrown when we cannot set up a variant of a native library.
|
||||
*/
|
||||
public class NativeSetupException extends RuntimeException {
|
||||
|
||||
public NativeSetupException() {
|
||||
|
@@ -28,6 +28,7 @@ class CompressorUtils {
|
||||
|
||||
/**
|
||||
* Ensures that the buffer does not go over {@code max}.
|
||||
*
|
||||
* @param buf the buffer for check
|
||||
* @param max the maximum size for the buffer
|
||||
* @throws DataFormatException if the buffer becomes too bug
|
||||
|
@@ -28,6 +28,9 @@ import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
|
||||
/**
|
||||
* Implements deflate compression by wrapping {@link Deflater} and {@link Inflater}.
|
||||
*/
|
||||
public class JavaVelocityCompressor implements VelocityCompressor {
|
||||
|
||||
public static final VelocityCompressorFactory FACTORY = JavaVelocityCompressor::new;
|
||||
|
@@ -22,6 +22,9 @@ import com.velocitypowered.natives.util.BufferPreference;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.zip.DataFormatException;
|
||||
|
||||
/**
|
||||
* Implements deflate compression using the {@code libdeflate} native C library.
|
||||
*/
|
||||
public class LibdeflateVelocityCompressor implements VelocityCompressor {
|
||||
|
||||
public static final VelocityCompressorFactory FACTORY = LibdeflateVelocityCompressor::new;
|
||||
|
@@ -17,6 +17,9 @@
|
||||
|
||||
package com.velocitypowered.natives.compression;
|
||||
|
||||
/**
|
||||
* Factory for {@link VelocityCompressor}.
|
||||
*/
|
||||
public interface VelocityCompressorFactory {
|
||||
|
||||
VelocityCompressor create(int level);
|
||||
|
@@ -26,6 +26,9 @@ import javax.crypto.SecretKey;
|
||||
import javax.crypto.ShortBufferException;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
|
||||
/**
|
||||
* Implements AES-CFB8 encryption/decryption using {@link Cipher}.
|
||||
*/
|
||||
public class JavaVelocityCipher implements VelocityCipher {
|
||||
|
||||
public static final VelocityCipherFactory FACTORY = new VelocityCipherFactory() {
|
||||
|
@@ -23,6 +23,9 @@ import io.netty.buffer.ByteBuf;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
/**
|
||||
* Implements AES-CFB8 encryption/decryption using a native library.
|
||||
*/
|
||||
public class NativeVelocityCipher implements VelocityCipher {
|
||||
|
||||
public static final VelocityCipherFactory FACTORY = new VelocityCipherFactory() {
|
||||
|
@@ -21,6 +21,15 @@ import com.velocitypowered.natives.Disposable;
|
||||
import com.velocitypowered.natives.Native;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* Implements an AES-CFB8 cipher that either encrypts or decrypts connection data.
|
||||
*/
|
||||
public interface VelocityCipher extends Disposable, Native {
|
||||
|
||||
/**
|
||||
* Encrypts the given {@link ByteBuf} in-place.
|
||||
*
|
||||
* @param source the buffer to encrypt
|
||||
*/
|
||||
void process(ByteBuf source);
|
||||
}
|
||||
|
@@ -20,6 +20,9 @@ package com.velocitypowered.natives.encryption;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.SecretKey;
|
||||
|
||||
/**
|
||||
* A factory interface for {@link VelocityCipher}.
|
||||
*/
|
||||
public interface VelocityCipherFactory {
|
||||
|
||||
VelocityCipher forEncryption(SecretKey key) throws GeneralSecurityException;
|
||||
|
@@ -17,6 +17,9 @@
|
||||
|
||||
package com.velocitypowered.natives.util;
|
||||
|
||||
/**
|
||||
* Emumerates Netty buffer preferences and requirements for use with Netty.
|
||||
*/
|
||||
public enum BufferPreference {
|
||||
/**
|
||||
* A heap buffer is required.
|
||||
|
@@ -21,6 +21,9 @@ import com.velocitypowered.natives.Native;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufAllocator;
|
||||
|
||||
/**
|
||||
* Additional utilities for {@link ByteBuf}.
|
||||
*/
|
||||
public class MoreByteBufUtils {
|
||||
private MoreByteBufUtils() {
|
||||
throw new AssertionError();
|
||||
|
@@ -22,6 +22,11 @@ import java.util.function.BooleanSupplier;
|
||||
import java.util.function.Supplier;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* A loader for native code.
|
||||
*
|
||||
* @param <T> the interface of the instance to load
|
||||
*/
|
||||
public final class NativeCodeLoader<T> implements Supplier<T> {
|
||||
|
||||
private final Variant<T> selected;
|
||||
|
@@ -21,6 +21,9 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import java.util.function.BooleanSupplier;
|
||||
|
||||
/**
|
||||
* Statically-computed constraints for native code.
|
||||
*/
|
||||
public class NativeConstraints {
|
||||
private static final boolean NATIVES_ENABLED = !Boolean.getBoolean("velocity.natives-disabled");
|
||||
private static final boolean IS_AMD64;
|
||||
|
@@ -31,6 +31,9 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
|
||||
/**
|
||||
* Enumerates all supported natives for Velocity.
|
||||
*/
|
||||
public class Natives {
|
||||
|
||||
private Natives() {
|
||||
|
@@ -1,162 +0,0 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer
|
||||
|
||||
plugins {
|
||||
id 'java'
|
||||
id 'checkstyle'
|
||||
}
|
||||
|
||||
apply plugin: 'org.cadixdev.licenser'
|
||||
apply from: '../gradle/checkstyle.gradle'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
|
||||
license {
|
||||
header = project.rootProject.file('HEADER.txt')
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
def buildNumber = System.getenv("BUILD_NUMBER") ?: "unknown"
|
||||
def version
|
||||
if (project.version.endsWith("-SNAPSHOT")) {
|
||||
version = "${project.version} (git-${project.ext.getCurrentShortRevision()}-b${buildNumber})"
|
||||
} else {
|
||||
version = "${project.version}"
|
||||
}
|
||||
|
||||
attributes 'Main-Class': 'com.velocitypowered.proxy.Velocity'
|
||||
attributes 'Implementation-Title': "Velocity"
|
||||
attributes 'Implementation-Version': version
|
||||
attributes 'Implementation-Vendor': "Velocity Contributors"
|
||||
attributes 'Multi-Release': 'true'
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
transform(Log4j2PluginsCacheFileTransformer)
|
||||
}
|
||||
|
||||
tasks.withType(Checkstyle) {
|
||||
exclude('**/com/velocitypowered/proxy/protocol/packet/*.java')
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Note: we depend on the API twice, first the main sourceset, and then the annotation processor.
|
||||
implementation project(':velocity-api')
|
||||
implementation project(':velocity-api').sourceSets.ap.output
|
||||
implementation project(':velocity-native')
|
||||
|
||||
implementation "io.netty:netty-codec:${nettyVersion}"
|
||||
implementation "io.netty:netty-codec-haproxy:${nettyVersion}"
|
||||
implementation "io.netty:netty-codec-http:${nettyVersion}"
|
||||
implementation "io.netty:netty-handler:${nettyVersion}"
|
||||
implementation "io.netty:netty-transport-native-epoll:${nettyVersion}"
|
||||
implementation "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-x86_64"
|
||||
implementation "io.netty:netty-transport-native-epoll:${nettyVersion}:linux-aarch_64"
|
||||
|
||||
implementation "org.apache.logging.log4j:log4j-api:${log4jVersion}"
|
||||
implementation "org.apache.logging.log4j:log4j-core:${log4jVersion}"
|
||||
implementation "org.apache.logging.log4j:log4j-slf4j-impl:${log4jVersion}"
|
||||
implementation "org.apache.logging.log4j:log4j-iostreams:${log4jVersion}"
|
||||
implementation "org.apache.logging.log4j:log4j-jul:${log4jVersion}"
|
||||
|
||||
implementation 'net.sf.jopt-simple:jopt-simple:5.0.4' // command-line options
|
||||
implementation 'net.minecrell:terminalconsoleappender:1.3.0'
|
||||
runtimeOnly 'org.jline:jline-terminal-jansi:3.21.0' // Needed for JLine
|
||||
runtimeOnly 'com.lmax:disruptor:3.4.4' // Async loggers
|
||||
|
||||
implementation 'it.unimi.dsi:fastutil-core:8.5.8'
|
||||
|
||||
implementation(platform("net.kyori:adventure-bom:${adventureVersion}"))
|
||||
implementation("net.kyori:adventure-nbt")
|
||||
implementation("net.kyori:adventure-platform-facet:4.1.2")
|
||||
|
||||
implementation 'org.asynchttpclient:async-http-client:2.12.3'
|
||||
|
||||
implementation 'com.spotify:completable-futures:0.3.5'
|
||||
|
||||
implementation 'com.electronwill.night-config:toml:3.6.4'
|
||||
|
||||
implementation 'org.bstats:bstats-base:2.2.1'
|
||||
implementation 'org.lanternpowered:lmbda:2.0.0'
|
||||
|
||||
implementation 'com.github.ben-manes.caffeine:caffeine:3.1.1'
|
||||
|
||||
implementation 'space.vectrix.flare:flare:2.0.1'
|
||||
implementation 'space.vectrix.flare:flare-fastutil:2.0.1'
|
||||
|
||||
compileOnly 'com.github.spotbugs:spotbugs-annotations:4.4.0'
|
||||
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
||||
testImplementation "org.junit.jupiter:junit-jupiter-engine:${junitVersion}"
|
||||
testImplementation "org.mockito:mockito-core:3.+"
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
// Exclude all the collection types we don't intend to use
|
||||
exclude 'it/unimi/dsi/fastutil/booleans/**'
|
||||
exclude 'it/unimi/dsi/fastutil/bytes/**'
|
||||
exclude 'it/unimi/dsi/fastutil/chars/**'
|
||||
exclude 'it/unimi/dsi/fastutil/doubles/**'
|
||||
exclude 'it/unimi/dsi/fastutil/floats/**'
|
||||
exclude 'it/unimi/dsi/fastutil/longs/**'
|
||||
exclude 'it/unimi/dsi/fastutil/shorts/**'
|
||||
|
||||
// Exclude the fastutil IO utilities - we don't use them.
|
||||
exclude 'it/unimi/dsi/fastutil/io/**'
|
||||
|
||||
// Exclude most of the int types - Object2IntMap have a values() method that returns an
|
||||
// IntCollection, and we need Int2ObjectMap
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2Boolean*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2Byte*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2Char*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2Double*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2Float*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2Int*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2Long*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2Short*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Int2Reference*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntAVL*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntArray*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*IntBi*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/Int*Pair'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntLinked*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntList*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntHeap*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntOpen*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntRB*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/IntSorted*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*Priority*'
|
||||
exclude 'it/unimi/dsi/fastutil/ints/*BigList*'
|
||||
|
||||
// Try to exclude everything BUT Object2Int{LinkedOpen,Open,CustomOpen}HashMap
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*ObjectArray*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*ObjectAVL*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object*Big*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Boolean*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Byte*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Char*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Double*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Float*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2IntArray*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2IntAVL*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2IntRB*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Long*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Object*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Reference*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Object2Short*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*ObjectRB*'
|
||||
exclude 'it/unimi/dsi/fastutil/objects/*Reference*'
|
||||
|
||||
// Exclude Checker Framework annotations
|
||||
exclude 'org/checkerframework/checker/**'
|
||||
|
||||
relocate 'org.bstats', 'com.velocitypowered.proxy.bstats'
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives shadowJar
|
||||
}
|
159
proxy/build.gradle.kts
Normal file
159
proxy/build.gradle.kts
Normal file
@@ -0,0 +1,159 @@
|
||||
import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer
|
||||
|
||||
plugins {
|
||||
application
|
||||
`set-manifest-impl-version`
|
||||
id("com.github.johnrengelman.shadow") version "7.1.0"
|
||||
}
|
||||
|
||||
license {
|
||||
header(project.rootProject.file("HEADER.txt"))
|
||||
}
|
||||
|
||||
application {
|
||||
mainClass.set("com.velocitypowered.proxy.Velocity")
|
||||
}
|
||||
|
||||
tasks {
|
||||
withType<Checkstyle> {
|
||||
exclude("**/com/velocitypowered/proxy/protocol/packet/**")
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes["Implementation-Title"] = "Velocity"
|
||||
attributes["Implementation-Vendor"] = "Velocity Contributors"
|
||||
attributes["Multi-Release"] = "true"
|
||||
}
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
transform(Log4j2PluginsCacheFileTransformer::class.java)
|
||||
|
||||
// Exclude all the collection types we don"t intend to use
|
||||
exclude("it/unimi/dsi/fastutil/booleans/**")
|
||||
exclude("it/unimi/dsi/fastutil/bytes/**")
|
||||
exclude("it/unimi/dsi/fastutil/chars/**")
|
||||
exclude("it/unimi/dsi/fastutil/doubles/**")
|
||||
exclude("it/unimi/dsi/fastutil/floats/**")
|
||||
exclude("it/unimi/dsi/fastutil/longs/**")
|
||||
exclude("it/unimi/dsi/fastutil/shorts/**")
|
||||
|
||||
// Exclude the fastutil IO utilities - we don"t use them.
|
||||
exclude("it/unimi/dsi/fastutil/io/**")
|
||||
|
||||
// Exclude most of the int types - Object2IntMap have a values() method that returns an
|
||||
// IntCollection, and we need Int2ObjectMap
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Int2Boolean*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Int2Byte*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Int2Char*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Int2Double*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Int2Float*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Int2Int*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Int2Long*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Int2Short*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Int2Reference*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/IntAVL*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/IntArray*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*IntBi*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/Int*Pair")
|
||||
exclude("it/unimi/dsi/fastutil/ints/IntLinked*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/IntList*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/IntHeap*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/IntOpen*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/IntRB*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/IntSorted*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*Priority*")
|
||||
exclude("it/unimi/dsi/fastutil/ints/*BigList*")
|
||||
|
||||
// Try to exclude everything BUT Object2Int{LinkedOpen,Open,CustomOpen}HashMap
|
||||
exclude("it/unimi/dsi/fastutil/objects/*ObjectArray*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*ObjectAVL*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object*Big*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2Boolean*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2Byte*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2Char*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2Double*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2Float*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2IntArray*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2IntAVL*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2IntRB*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2Long*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2Object*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2Reference*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Object2Short*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*ObjectRB*")
|
||||
exclude("it/unimi/dsi/fastutil/objects/*Reference*")
|
||||
|
||||
// Exclude Checker Framework annotations
|
||||
exclude("org/checkerframework/checker/**")
|
||||
|
||||
relocate("org.bstats", "com.velocitypowered.proxy.bstats")
|
||||
}
|
||||
}
|
||||
|
||||
val adventureVersion: String by project.extra
|
||||
val adventureFacetVersion: String by project.extra
|
||||
val asyncHttpClientVersion: String by project.extra
|
||||
val bstatsVersion: String by project.extra
|
||||
val caffeineVersion: String by project.extra
|
||||
val completableFuturesVersion: String by project.extra
|
||||
val disruptorVersion: String by project.extra
|
||||
val fastutilVersion: String by project.extra
|
||||
val flareVersion: String by project.extra
|
||||
val jansiVersion: String by project.extra
|
||||
val joptSimpleVersion: String by project.extra
|
||||
val lmbdaVersion: String by project.extra
|
||||
val log4jVersion: String by project.extra
|
||||
val nettyVersion: String by project.extra
|
||||
val nightConfigVersion: String by project.extra
|
||||
val semver4jVersion: String by project.extra
|
||||
val terminalConsoleAppenderVersion: String by project.extra
|
||||
|
||||
dependencies {
|
||||
implementation(project(":velocity-api"))
|
||||
implementation(project(":velocity-native"))
|
||||
|
||||
implementation("io.netty:netty-codec:${nettyVersion}")
|
||||
implementation("io.netty:netty-codec-haproxy:${nettyVersion}")
|
||||
implementation("io.netty:netty-codec-http:${nettyVersion}")
|
||||
implementation("io.netty:netty-handler:${nettyVersion}")
|
||||
implementation("io.netty:netty-transport-native-epoll:${nettyVersion}")
|
||||
implementation("io.netty:netty-transport-native-epoll:${nettyVersion}:linux-x86_64")
|
||||
implementation("io.netty:netty-transport-native-epoll:${nettyVersion}:linux-aarch_64")
|
||||
|
||||
implementation("org.apache.logging.log4j:log4j-api:${log4jVersion}")
|
||||
implementation("org.apache.logging.log4j:log4j-core:${log4jVersion}")
|
||||
implementation("org.apache.logging.log4j:log4j-slf4j-impl:${log4jVersion}")
|
||||
implementation("org.apache.logging.log4j:log4j-iostreams:${log4jVersion}")
|
||||
implementation("org.apache.logging.log4j:log4j-jul:${log4jVersion}")
|
||||
|
||||
implementation("net.sf.jopt-simple:jopt-simple:$joptSimpleVersion") // command-line options
|
||||
implementation("net.minecrell:terminalconsoleappender:$terminalConsoleAppenderVersion")
|
||||
runtimeOnly("org.jline:jline-terminal-jansi:$jansiVersion") // Needed for JLine
|
||||
runtimeOnly("com.lmax:disruptor:$disruptorVersion") // Async loggers
|
||||
|
||||
implementation("it.unimi.dsi:fastutil-core:$fastutilVersion")
|
||||
|
||||
implementation(platform("net.kyori:adventure-bom:$adventureVersion"))
|
||||
implementation("net.kyori:adventure-nbt")
|
||||
implementation("net.kyori:adventure-platform-facet:$adventureFacetVersion")
|
||||
|
||||
implementation("org.asynchttpclient:async-http-client:$asyncHttpClientVersion")
|
||||
|
||||
implementation("com.spotify:completable-futures:$completableFuturesVersion")
|
||||
|
||||
implementation("com.electronwill.night-config:toml:$nightConfigVersion")
|
||||
|
||||
implementation("org.bstats:bstats-base:$bstatsVersion")
|
||||
implementation("org.lanternpowered:lmbda:$lmbdaVersion")
|
||||
|
||||
implementation("com.github.ben-manes.caffeine:caffeine:$caffeineVersion")
|
||||
|
||||
implementation("space.vectrix.flare:flare:$flareVersion")
|
||||
implementation("space.vectrix.flare:flare-fastutil:$flareVersion")
|
||||
|
||||
compileOnly("com.github.spotbugs:spotbugs-annotations:4.4.0")
|
||||
|
||||
testImplementation("org.mockito:mockito-core:3.+")
|
||||
}
|
@@ -35,6 +35,9 @@ import org.bstats.charts.SingleLineChart;
|
||||
import org.bstats.config.MetricsConfig;
|
||||
import org.bstats.json.JsonObjectBuilder;
|
||||
|
||||
/**
|
||||
* Initializes bStats.
|
||||
*/
|
||||
public class Metrics {
|
||||
|
||||
private MetricsBase metricsBase;
|
||||
|
@@ -26,7 +26,11 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Holds parsed command line options.
|
||||
*/
|
||||
public final class ProxyOptions {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(ProxyOptions.class);
|
||||
private final boolean help;
|
||||
private final @Nullable Integer port;
|
||||
|
@@ -23,6 +23,10 @@ import java.text.DecimalFormat;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
/**
|
||||
* The main class. Responsible for parsing command line arguments and then launching the
|
||||
* proxy.
|
||||
*/
|
||||
public class Velocity {
|
||||
|
||||
private static final Logger logger;
|
||||
@@ -50,6 +54,7 @@ public class Velocity {
|
||||
|
||||
/**
|
||||
* Main method that the JVM will call when {@code java -jar velocity.jar} is executed.
|
||||
*
|
||||
* @param args the arguments to the proxy
|
||||
*/
|
||||
public static void main(String... args) {
|
||||
|
@@ -57,7 +57,7 @@ import com.velocitypowered.proxy.scheduler.VelocityScheduler;
|
||||
import com.velocitypowered.proxy.server.ServerMap;
|
||||
import com.velocitypowered.proxy.util.AddressUtil;
|
||||
import com.velocitypowered.proxy.util.ClosestLocaleMatcher;
|
||||
import com.velocitypowered.proxy.util.FileSystemUtils;
|
||||
import com.velocitypowered.proxy.util.ResourceUtils;
|
||||
import com.velocitypowered.proxy.util.VelocityChannelRegistrar;
|
||||
import com.velocitypowered.proxy.util.bossbar.AdventureBossBarManager;
|
||||
import com.velocitypowered.proxy.util.ratelimit.Ratelimiter;
|
||||
@@ -105,6 +105,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ProxyServer}.
|
||||
*/
|
||||
public class VelocityServer implements ProxyServer, ForwardingAudience {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(VelocityServer.class);
|
||||
@@ -250,7 +253,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
||||
.create(Key.key("velocity", "translations"));
|
||||
translationRegistry.defaultLocale(Locale.US);
|
||||
try {
|
||||
FileSystemUtils.visitResources(VelocityServer.class, path -> {
|
||||
ResourceUtils.visitResources(VelocityServer.class, path -> {
|
||||
logger.info("Loading localizations...");
|
||||
|
||||
final Path langPath = Path.of("lang");
|
||||
@@ -275,7 +278,6 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Files.walk(langPath).forEach(file -> {
|
||||
if (!Files.isRegularFile(file)) {
|
||||
return;
|
||||
@@ -468,7 +470,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
||||
}
|
||||
|
||||
/**
|
||||
* Shuts down the proxy, kicking players with the specified {@param reason}.
|
||||
* Shuts down the proxy, kicking players with the specified reason.
|
||||
*
|
||||
* @param explicitExit whether the user explicitly shut down the proxy
|
||||
* @param reason message to kick online players with
|
||||
@@ -580,6 +582,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
||||
|
||||
/**
|
||||
* Checks if the {@code connection} can be registered with the proxy.
|
||||
*
|
||||
* @param connection the connection to check
|
||||
* @return {@code true} if we can register the connection, {@code false} if not
|
||||
*/
|
||||
@@ -594,6 +597,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
||||
|
||||
/**
|
||||
* Attempts to register the {@code connection} with the proxy.
|
||||
*
|
||||
* @param connection the connection to register
|
||||
* @return {@code true} if we registered the connection, {@code false} if not
|
||||
*/
|
||||
|
@@ -32,9 +32,8 @@ import org.checkerframework.checker.lock.qual.GuardedBy;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Copies the nodes of a {@link RootCommandNode} to a possibly non-empty
|
||||
* destination {@link RootCommandNode}, respecting the requirements satisfied
|
||||
* by a given command source.
|
||||
* Copies the nodes of a {@link RootCommandNode} to a possibly non-empty destination
|
||||
* {@link RootCommandNode}, respecting the requirements satisfied by a given command source.
|
||||
*
|
||||
* @param <S> the type of the source to inject the nodes for
|
||||
*/
|
||||
@@ -55,8 +54,8 @@ public final class CommandGraphInjector<S> {
|
||||
// the root node we are copying nodes from to the destination node.
|
||||
|
||||
/**
|
||||
* Adds the node from the root node of this injector to the given root node,
|
||||
* respecting the requirements satisfied by the given source.
|
||||
* Adds the node from the root node of this injector to the given root node, respecting the
|
||||
* requirements satisfied by the given source.
|
||||
*
|
||||
* <p>Prior to adding a literal with the same name as one previously contained
|
||||
* in the destination node, the old node is removed from the destination node.
|
||||
|
@@ -50,8 +50,8 @@ import org.checkerframework.checker.lock.qual.GuardedBy;
|
||||
* Provides suggestions for a given command input.
|
||||
*
|
||||
* <p>Similar to {@link CommandDispatcher#getCompletionSuggestions(ParseResults)}, except it
|
||||
* avoids fully parsing the given input and performs exactly one requirement predicate check
|
||||
* per considered node.
|
||||
* avoids fully parsing the given input and performs exactly one requirement predicate check per
|
||||
* considered node.
|
||||
*
|
||||
* @param <S> the type of the command source
|
||||
*/
|
||||
@@ -179,8 +179,8 @@ final class SuggestionsProvider<S> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the suggestions provided by the {@link Command} associated to the given
|
||||
* alias node and the hints given during registration for the given input.
|
||||
* Merges the suggestions provided by the {@link Command} associated to the given alias node and
|
||||
* the hints given during registration for the given input.
|
||||
*
|
||||
* <p>The context is not mutated by this method. The reader's cursor may be modified.
|
||||
*
|
||||
@@ -241,8 +241,8 @@ final class SuggestionsProvider<S> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the suggestions provided by the {@link Command} associated to
|
||||
* the specified arguments node for the given input.
|
||||
* Returns the suggestions provided by the {@link Command} associated to the specified arguments
|
||||
* node for the given input.
|
||||
*
|
||||
* <p>The reader and context are not mutated by this method.
|
||||
*
|
||||
@@ -290,8 +290,8 @@ final class SuggestionsProvider<S> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the hint nodes under the given node, which is either an alias node of
|
||||
* a {@link Command} or another hint node.
|
||||
* Parses the hint nodes under the given node, which is either an alias node of a {@link Command}
|
||||
* or another hint node.
|
||||
*
|
||||
* <p>The reader and context are not mutated by this method.
|
||||
*
|
||||
@@ -350,9 +350,8 @@ final class SuggestionsProvider<S> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a future that is completed with the result of merging the {@link Suggestions}
|
||||
* the given futures complete with. The results of the futures that complete exceptionally
|
||||
* are ignored.
|
||||
* Returns a future that is completed with the result of merging the {@link Suggestions} the given
|
||||
* futures complete with. The results of the futures that complete exceptionally are ignored.
|
||||
*
|
||||
* @param fullInput the command input
|
||||
* @param futures the futures that complete with the suggestions
|
||||
|
@@ -54,6 +54,9 @@ import org.checkerframework.checker.lock.qual.GuardedBy;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.jetbrains.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* Impelements Velocity's command handler.
|
||||
*/
|
||||
public class VelocityCommandManager implements CommandManager {
|
||||
|
||||
private final @GuardedBy("lock") CommandDispatcher<CommandSource> dispatcher;
|
||||
@@ -123,15 +126,15 @@ public class VelocityCommandManager implements CommandManager {
|
||||
|
||||
/**
|
||||
* Attempts to register the given command if it implements the
|
||||
* {@linkplain CommandRegistrar#registrableSuperInterface() registrable superinterface}
|
||||
* of the given registrar.
|
||||
* {@linkplain CommandRegistrar#registrableSuperInterface() registrable superinterface} of the
|
||||
* given registrar.
|
||||
*
|
||||
* @param registrar the registrar to register the command
|
||||
* @param command the command to register
|
||||
* @param meta the command metadata
|
||||
* @param <T> the type of the command
|
||||
* @return true if the command implements the registrable superinterface of the registrar;
|
||||
* false otherwise.
|
||||
* @return true if the command implements the registrable superinterface of the registrar; false
|
||||
* otherwise.
|
||||
* @throws IllegalArgumentException if the registrar cannot register the command
|
||||
*/
|
||||
private <T extends Command> boolean tryRegister(final CommandRegistrar<T> registrar,
|
||||
@@ -253,8 +256,7 @@ public class VelocityCommandManager implements CommandManager {
|
||||
*
|
||||
* @param source the source to execute the command for
|
||||
* @param cmdLine the partially completed command
|
||||
* @return a {@link CompletableFuture} eventually completed with a {@link List},
|
||||
* possibly empty
|
||||
* @return a {@link CompletableFuture} eventually completed with a {@link List}, possibly empty
|
||||
*/
|
||||
public CompletableFuture<List<String>> offerSuggestions(final CommandSource source,
|
||||
final String cmdLine) {
|
||||
@@ -267,8 +269,8 @@ public class VelocityCommandManager implements CommandManager {
|
||||
*
|
||||
* @param source the source to execute the command for
|
||||
* @param cmdLine the partially completed command
|
||||
* @return a {@link CompletableFuture} eventually completed with {@link Suggestions},
|
||||
* possibly empty
|
||||
* @return a {@link CompletableFuture} eventually completed with {@link Suggestions}, possibly
|
||||
* empty
|
||||
*/
|
||||
public CompletableFuture<Suggestions> offerBrigadierSuggestions(
|
||||
final CommandSource source, final String cmdLine) {
|
||||
@@ -281,7 +283,8 @@ public class VelocityCommandManager implements CommandManager {
|
||||
} catch (final Throwable e) {
|
||||
// Again, plugins are naughty
|
||||
return CompletableFuture.failedFuture(
|
||||
new RuntimeException("Unable to provide suggestions for " + cmdLine + " for " + source, e));
|
||||
new RuntimeException("Unable to provide suggestions for " + cmdLine + " for " + source,
|
||||
e));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,9 @@ import java.util.stream.Stream;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Handles building commands for plugins to register.
|
||||
*/
|
||||
public final class VelocityCommandMeta implements CommandMeta {
|
||||
|
||||
static final class Builder implements CommandMeta.Builder {
|
||||
@@ -87,12 +90,12 @@ public final class VelocityCommandMeta implements CommandMeta {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a node to use for hinting the arguments of a {@link Command}. Hint nodes are
|
||||
* sent to 1.13+ clients and the proxy uses them for providing suggestions.
|
||||
* Creates a node to use for hinting the arguments of a {@link Command}. Hint nodes are sent to
|
||||
* 1.13+ clients and the proxy uses them for providing suggestions.
|
||||
*
|
||||
* <p>A hint node is used to provide suggestions if and only if the requirements of
|
||||
* the corresponding {@link CommandNode} are satisfied. The requirement predicate
|
||||
* of the returned node always returns {@code false}.
|
||||
* the corresponding {@link CommandNode} are satisfied. The requirement predicate of the returned
|
||||
* node always returns {@code false}.
|
||||
*
|
||||
* @param hint the node containing hinting metadata
|
||||
* @return the hinting command node
|
||||
|
@@ -38,10 +38,9 @@ import java.util.Map;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Provides utility methods common to most {@link Command} implementations.
|
||||
* In particular, {@link InvocableCommand} implementations use the same logic for
|
||||
* creating and parsing the alias and arguments command nodes, which is contained
|
||||
* in this class.
|
||||
* Provides utility methods common to most {@link Command} implementations. In particular,
|
||||
* {@link InvocableCommand} implementations use the same logic for creating and parsing the alias
|
||||
* and arguments command nodes, which is contained in this class.
|
||||
*/
|
||||
public final class VelocityCommands {
|
||||
|
||||
@@ -85,11 +84,12 @@ public final class VelocityCommands {
|
||||
public static final String ARGS_NODE_NAME = "arguments";
|
||||
|
||||
/**
|
||||
* Returns the parsed arguments that come after the command alias, or {@code fallback} if
|
||||
* no arguments were provided.
|
||||
* Returns the parsed arguments that come after the command alias, or {@code fallback} if no
|
||||
* arguments were provided.
|
||||
*
|
||||
* @param arguments the map of parsed arguments, as returned by
|
||||
* {@link CommandContext#getArguments()} or {@link CommandContextBuilder#getArguments()}
|
||||
* {@link CommandContext#getArguments()} or
|
||||
* {@link CommandContextBuilder#getArguments()}
|
||||
* @param type the type class of the arguments
|
||||
* @param fallback the value to return if no arguments were provided
|
||||
* @param <V> the type of the arguments
|
||||
@@ -113,8 +113,8 @@ public final class VelocityCommands {
|
||||
// Alias nodes
|
||||
|
||||
/**
|
||||
* Returns whether a literal node with the given name can be added to
|
||||
* the {@link RootCommandNode} associated to a {@link CommandManager}.
|
||||
* Returns whether a literal node with the given name can be added to the {@link RootCommandNode}
|
||||
* associated to a {@link CommandManager}.
|
||||
*
|
||||
* <p>This is an internal method and should not be used in user-facing
|
||||
* methods. Instead, they should lowercase the given aliases themselves.
|
||||
@@ -159,8 +159,8 @@ public final class VelocityCommands {
|
||||
// Arguments node
|
||||
|
||||
/**
|
||||
* Returns the arguments node for the command represented by the given alias node,
|
||||
* if present; otherwise returns {@code null}.
|
||||
* Returns the arguments node for the command represented by the given alias node, if present;
|
||||
* otherwise returns {@code null}.
|
||||
*
|
||||
* @param alias the alias node
|
||||
* @param <S> the type of the command source
|
||||
|
@@ -27,8 +27,8 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An argument type that parses the remaining contents of a {@link StringReader},
|
||||
* splitting the input into words and placing the results in a string array.
|
||||
* An argument type that parses the remaining contents of a {@link StringReader}, splitting the
|
||||
* input into words and placing the results in a string array.
|
||||
*/
|
||||
public final class StringArrayArgumentType implements ArgumentType<String[]> {
|
||||
|
||||
@@ -39,7 +39,8 @@ public final class StringArrayArgumentType implements ArgumentType<String[]> {
|
||||
Splitter.on(CommandDispatcher.ARGUMENT_SEPARATOR_CHAR);
|
||||
private static final List<String> EXAMPLES = Arrays.asList("word", "some words");
|
||||
|
||||
private StringArrayArgumentType() {}
|
||||
private StringArrayArgumentType() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] parse(final StringReader reader) throws CommandSyntaxException {
|
||||
|
@@ -34,8 +34,8 @@ public final class VelocityArgumentBuilder<S, T>
|
||||
extends ArgumentBuilder<S, VelocityArgumentBuilder<S, T>> {
|
||||
|
||||
/**
|
||||
* Creates a builder for creating {@link VelocityArgumentCommandNode}s with
|
||||
* the given name and type.
|
||||
* Creates a builder for creating {@link VelocityArgumentCommandNode}s with the given name and
|
||||
* type.
|
||||
*
|
||||
* @param name the name of the node
|
||||
* @param type the type of the argument to parse
|
||||
|
@@ -40,9 +40,9 @@ import java.util.function.BiPredicate;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* An argument node that uses the given (possibly custom) {@link ArgumentType}
|
||||
* for parsing, while maintaining compatibility with the vanilla client.
|
||||
* The argument type must be greedy and accept any input.
|
||||
* An argument node that uses the given (possibly custom) {@link ArgumentType} for parsing, while
|
||||
* maintaining compatibility with the vanilla client. The argument type must be greedy and accept
|
||||
* any input.
|
||||
*
|
||||
* @param <S> the type of the command source
|
||||
* @param <T> the type of the argument to parse
|
||||
|
@@ -21,6 +21,9 @@ import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
/**
|
||||
* Basic, common command messages.
|
||||
*/
|
||||
public class CommandMessages {
|
||||
|
||||
public static final TranslatableComponent PLAYERS_ONLY = Component.translatable(
|
||||
|
@@ -40,6 +40,9 @@ import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.TranslatableComponent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
/**
|
||||
* Implements the Velocity default {@code /glist} command.
|
||||
*/
|
||||
public class GlistCommand {
|
||||
|
||||
private static final String SERVER_ARG = "server";
|
||||
|
@@ -39,6 +39,9 @@ import net.kyori.adventure.text.TranslatableComponent;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
/**
|
||||
* Implements Velocity's {@code /server} command.
|
||||
*/
|
||||
public class ServerCommand implements SimpleCommand {
|
||||
|
||||
public static final int MAX_SERVERS_TO_LIST = 50;
|
||||
@@ -54,7 +57,7 @@ public class ServerCommand implements SimpleCommand {
|
||||
final String[] args = invocation.arguments();
|
||||
|
||||
if (!(source instanceof Player)) {
|
||||
source.sendMessage(Identity.nil(), CommandMessages.PLAYERS_ONLY);
|
||||
source.sendMessage(CommandMessages.PLAYERS_ONLY);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,9 +66,8 @@ public class ServerCommand implements SimpleCommand {
|
||||
// Trying to connect to a server.
|
||||
String serverName = args[0];
|
||||
Optional<RegisteredServer> toConnect = server.getServer(serverName);
|
||||
if (!toConnect.isPresent()) {
|
||||
player.sendMessage(Identity.nil(), CommandMessages.SERVER_DOES_NOT_EXIST
|
||||
.args(Component.text(serverName)));
|
||||
if (toConnect.isEmpty()) {
|
||||
player.sendMessage(CommandMessages.SERVER_DOES_NOT_EXIST.args(Component.text(serverName)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -78,14 +80,14 @@ public class ServerCommand implements SimpleCommand {
|
||||
private void outputServerInformation(Player executor) {
|
||||
String currentServer = executor.getCurrentServer().map(ServerConnection::getServerInfo)
|
||||
.map(ServerInfo::getName).orElse("<unknown>");
|
||||
executor.sendMessage(Identity.nil(), Component.translatable(
|
||||
executor.sendMessage(Component.translatable(
|
||||
"velocity.command.server-current-server",
|
||||
NamedTextColor.YELLOW,
|
||||
Component.text(currentServer)));
|
||||
|
||||
List<RegisteredServer> servers = BuiltinCommandUtil.sortedServerList(server);
|
||||
if (servers.size() > MAX_SERVERS_TO_LIST) {
|
||||
executor.sendMessage(Identity.nil(), Component.translatable(
|
||||
executor.sendMessage(Component.translatable(
|
||||
"velocity.command.server-too-many", NamedTextColor.RED));
|
||||
return;
|
||||
}
|
||||
@@ -103,7 +105,7 @@ public class ServerCommand implements SimpleCommand {
|
||||
}
|
||||
}
|
||||
|
||||
executor.sendMessage(Identity.nil(), serverListBuilder.build());
|
||||
executor.sendMessage(serverListBuilder.build());
|
||||
}
|
||||
|
||||
private TextComponent formatServerComponent(String currentPlayerServer, RegisteredServer server) {
|
||||
@@ -113,9 +115,11 @@ public class ServerCommand implements SimpleCommand {
|
||||
int connectedPlayers = server.getPlayersConnected().size();
|
||||
TranslatableComponent playersTextComponent;
|
||||
if (connectedPlayers == 1) {
|
||||
playersTextComponent = Component.translatable("velocity.command.server-tooltip-player-online");
|
||||
playersTextComponent = Component.translatable(
|
||||
"velocity.command.server-tooltip-player-online");
|
||||
} else {
|
||||
playersTextComponent = Component.translatable("velocity.command.server-tooltip-players-online");
|
||||
playersTextComponent = Component.translatable(
|
||||
"velocity.command.server-tooltip-players-online");
|
||||
}
|
||||
playersTextComponent = playersTextComponent.args(Component.text(connectedPlayers));
|
||||
if (serverInfo.getName().equals(currentPlayerServer)) {
|
||||
@@ -130,7 +134,8 @@ public class ServerCommand implements SimpleCommand {
|
||||
serverTextComponent = serverTextComponent.color(NamedTextColor.GRAY)
|
||||
.clickEvent(ClickEvent.runCommand("/server " + serverInfo.getName()))
|
||||
.hoverEvent(
|
||||
showText(Component.translatable("velocity.command.server-tooltip-offer-connect-server")
|
||||
showText(
|
||||
Component.translatable("velocity.command.server-tooltip-offer-connect-server")
|
||||
.append(Component.newline())
|
||||
.append(playersTextComponent))
|
||||
);
|
||||
|
@@ -27,11 +27,17 @@ import com.velocitypowered.proxy.VelocityServer;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
/**
|
||||
* Shuts down the proxy.
|
||||
*/
|
||||
public final class ShutdownCommand {
|
||||
private ShutdownCommand() {}
|
||||
|
||||
private ShutdownCommand() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a Velocity Shutdown Command.
|
||||
*
|
||||
* @param server the proxy instance
|
||||
* @return the Shutdown Command
|
||||
*/
|
||||
@@ -42,7 +48,8 @@ public final class ShutdownCommand {
|
||||
server.shutdown(true);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
.then(RequiredArgumentBuilder.<CommandSource, String>argument("reason", StringArgumentType.greedyString())
|
||||
.then(RequiredArgumentBuilder.<CommandSource, String>argument("reason",
|
||||
StringArgumentType.greedyString())
|
||||
.executes(context -> {
|
||||
String reason = context.getArgument("reason", String.class);
|
||||
server.shutdown(true, MiniMessage.miniMessage().deserialize(
|
||||
|
@@ -60,6 +60,9 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
/**
|
||||
* Implements the {@code /velocity} command and friends.
|
||||
*/
|
||||
public class VelocityCommand implements SimpleCommand {
|
||||
|
||||
private interface SubCommand {
|
||||
@@ -383,7 +386,8 @@ public class VelocityCommand implements SimpleCommand {
|
||||
|
||||
source.sendMessage(Component.text(
|
||||
"An anonymised report containing useful information about "
|
||||
+ "this proxy has been saved at " + dumpPath.toAbsolutePath(), NamedTextColor.GREEN));
|
||||
+ "this proxy has been saved at " + dumpPath.toAbsolutePath(),
|
||||
NamedTextColor.GREEN));
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to complete dump command, "
|
||||
+ "the executor was interrupted: " + e.getMessage());
|
||||
|
@@ -27,14 +27,12 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Creates command invocation objects from a command context builder or
|
||||
* a command context.
|
||||
* Creates command invocation objects from a command context builder or a command context.
|
||||
*
|
||||
* <p>Let {@code builder} be a command context builder, and {@code context}
|
||||
* a context returned by calling {@link CommandContextBuilder#build(String)} on
|
||||
* {@code builder}. The invocations returned by {@link #create(CommandContext)}
|
||||
* when given {@code context}, and {@link #create(CommandContextBuilder)} when
|
||||
* given {@code builder} are equal.
|
||||
* a context returned by calling {@link CommandContextBuilder#build(String)} on {@code builder}. The
|
||||
* invocations returned by {@link #create(CommandContext)} when given {@code context}, and
|
||||
* {@link #create(CommandContextBuilder)} when given {@code builder} are equal.
|
||||
*
|
||||
* @param <I> the type of the built invocation
|
||||
*/
|
||||
@@ -67,7 +65,8 @@ public interface CommandInvocationFactory<I extends CommandInvocation<?>> {
|
||||
* @param nodes the list of parsed nodes, as returned by {@link CommandContext#getNodes()} and
|
||||
* {@link CommandContextBuilder#getNodes()}
|
||||
* @param arguments the list of parsed arguments, as returned by
|
||||
* {@link CommandContext#getArguments()} and {@link CommandContextBuilder#getArguments()}
|
||||
* {@link CommandContext#getArguments()} and
|
||||
* {@link CommandContextBuilder#getArguments()}
|
||||
* @return the built invocation context
|
||||
*/
|
||||
// This provides an abstraction over methods common to CommandContext and CommandContextBuilder.
|
||||
|
@@ -22,10 +22,14 @@ import com.mojang.brigadier.context.ParsedArgument;
|
||||
import com.mojang.brigadier.context.ParsedCommandNode;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.command.RawCommand;
|
||||
import com.velocitypowered.api.command.SimpleCommand;
|
||||
import com.velocitypowered.proxy.command.VelocityCommands;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implements {@link RawCommand.Invocation}.
|
||||
*/
|
||||
public final class RawCommandInvocation extends AbstractCommandInvocation<String>
|
||||
implements RawCommand.Invocation {
|
||||
|
||||
|
@@ -28,6 +28,9 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implements {@link SimpleCommand.Invocation}.
|
||||
*/
|
||||
public final class SimpleCommandInvocation extends AbstractCommandInvocation<String[]>
|
||||
implements SimpleCommand.Invocation {
|
||||
|
||||
|
@@ -23,8 +23,8 @@ import com.velocitypowered.api.command.Command;
|
||||
import com.velocitypowered.api.command.CommandMeta;
|
||||
|
||||
/**
|
||||
* Creates and registers the {@link LiteralCommandNode} representations of
|
||||
* a given {@link Command} in a {@link RootCommandNode}.
|
||||
* Creates and registers the {@link LiteralCommandNode} representations of a given {@link Command}
|
||||
* in a {@link RootCommandNode}.
|
||||
*
|
||||
* @param <T> the type of the command to register
|
||||
*/
|
||||
@@ -40,9 +40,9 @@ public interface CommandRegistrar<T extends Command> {
|
||||
void register(final CommandMeta meta, final T command);
|
||||
|
||||
/**
|
||||
* Returns the superclass or superinterface of all {@link Command} classes
|
||||
* compatible with this registrar. Note that {@link #register(CommandMeta, Command)}
|
||||
* may impose additional restrictions on individual {@link Command} instances.
|
||||
* Returns the superclass or superinterface of all {@link Command} classes compatible with this
|
||||
* registrar. Note that {@link #register(CommandMeta, Command)} may impose additional restrictions
|
||||
* on individual {@link Command} instances.
|
||||
*
|
||||
* @return the superclass of all the classes compatible with this registrar
|
||||
*/
|
||||
|
@@ -17,6 +17,9 @@
|
||||
|
||||
package com.velocitypowered.proxy.config;
|
||||
|
||||
/**
|
||||
* Supported passthrough modes for ping passthrough.
|
||||
*/
|
||||
public enum PingPassthroughMode {
|
||||
DISABLED,
|
||||
MODS,
|
||||
|
@@ -17,6 +17,9 @@
|
||||
|
||||
package com.velocitypowered.proxy.config;
|
||||
|
||||
/**
|
||||
* Supported player info forwarding methods.
|
||||
*/
|
||||
public enum PlayerInfoForwarding {
|
||||
NONE,
|
||||
LEGACY,
|
||||
|
@@ -52,29 +52,45 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
/**
|
||||
* Velocity's configuration.
|
||||
*/
|
||||
public class VelocityConfiguration implements ProxyConfig {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(VelocityConfiguration.class);
|
||||
|
||||
@Expose private String bind = "0.0.0.0:25577";
|
||||
@Expose private String motd = "&3A Velocity Server";
|
||||
@Expose private int showMaxPlayers = 500;
|
||||
@Expose private boolean onlineMode = true;
|
||||
@Expose private boolean preventClientProxyConnections = false;
|
||||
@Expose private PlayerInfoForwarding playerInfoForwardingMode = PlayerInfoForwarding.NONE;
|
||||
@Expose
|
||||
private String bind = "0.0.0.0:25577";
|
||||
@Expose
|
||||
private String motd = "&3A Velocity Server";
|
||||
@Expose
|
||||
private int showMaxPlayers = 500;
|
||||
@Expose
|
||||
private boolean onlineMode = true;
|
||||
@Expose
|
||||
private boolean preventClientProxyConnections = false;
|
||||
@Expose
|
||||
private PlayerInfoForwarding playerInfoForwardingMode = PlayerInfoForwarding.NONE;
|
||||
private byte[] forwardingSecret = generateRandomString(12).getBytes(StandardCharsets.UTF_8);
|
||||
@Expose private boolean announceForge = false;
|
||||
@Expose private boolean onlineModeKickExistingPlayers = false;
|
||||
@Expose private PingPassthroughMode pingPassthrough = PingPassthroughMode.DISABLED;
|
||||
@Expose
|
||||
private boolean announceForge = false;
|
||||
@Expose
|
||||
private boolean onlineModeKickExistingPlayers = false;
|
||||
@Expose
|
||||
private PingPassthroughMode pingPassthrough = PingPassthroughMode.DISABLED;
|
||||
private final Servers servers;
|
||||
private final ForcedHosts forcedHosts;
|
||||
@Expose private final Advanced advanced;
|
||||
@Expose private final Query query;
|
||||
@Expose
|
||||
private final Advanced advanced;
|
||||
@Expose
|
||||
private final Query query;
|
||||
private final Metrics metrics;
|
||||
@Expose private boolean enablePlayerAddressLogging = true;
|
||||
@Expose
|
||||
private boolean enablePlayerAddressLogging = true;
|
||||
private net.kyori.adventure.text.@MonotonicNonNull Component motdAsComponent;
|
||||
private @Nullable Favicon favicon;
|
||||
@Expose private boolean forceKeyAuthentication = true; // Added in 1.19
|
||||
@Expose
|
||||
private boolean forceKeyAuthentication = true; // Added in 1.19
|
||||
|
||||
private VelocityConfiguration(Servers servers, ForcedHosts forcedHosts, Advanced advanced,
|
||||
Query query, Metrics metrics) {
|
||||
@@ -112,6 +128,7 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
|
||||
/**
|
||||
* Attempts to validate the configuration.
|
||||
*
|
||||
* @return {@code true} if the configuration is sound, {@code false} if not
|
||||
*/
|
||||
public boolean validate() {
|
||||
@@ -408,6 +425,7 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
|
||||
/**
|
||||
* Reads the Velocity configuration from {@code path}.
|
||||
*
|
||||
* @param path the path to read from
|
||||
* @return the deserialized Velocity configuration
|
||||
* @throws IOException if we could not read from the {@code path}.
|
||||
@@ -455,23 +473,25 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
configVersion = 1.0;
|
||||
}
|
||||
|
||||
// Whether or not this config version is older than 2.0 which uses the deprecated "forwarding-secret" parameter
|
||||
// Whether or not this config version is older than 2.0 which uses the deprecated
|
||||
// "forwarding-secret" parameter
|
||||
boolean legacyConfig = configVersion < 2.0;
|
||||
|
||||
String forwardingSecretString;
|
||||
byte[] forwardingSecret;
|
||||
|
||||
// Handle the previous (version 1.0) config
|
||||
// There is duplicate/old code here in effort to make the future commit which abandons legacy config handling
|
||||
// easier to implement. All that would be required is removing the if statement here and keeping the contents
|
||||
// of the else block (with slight tidying).
|
||||
// There is duplicate/old code here in effort to make the future commit which abandons legacy
|
||||
// config handling easier to implement. All that would be required is removing the if statement
|
||||
// here and keeping the contents of the else block (with slight tidying).
|
||||
if (legacyConfig) {
|
||||
logger.warn("You are currently using a deprecated configuration version. The \"forwarding-secret\""
|
||||
+ " parameter has been recognized as a security concern and has been removed in config version 2.0."
|
||||
+ " It's recommended you rename your current \"velocity.toml\" to something else to allow Velocity"
|
||||
+ " to generate a config file of the new version. You may then configure that file as you normally would."
|
||||
+ " The only differences are the config-version and \"forwarding-secret\" has been replaced"
|
||||
+ " by \"forwarding-secret-file\".");
|
||||
logger.warn(
|
||||
"You are currently using a deprecated configuration version. The \"forwarding-secret\""
|
||||
+ " parameter is a security hazard and was removed in config version 2.0."
|
||||
+ " You should rename your current \"velocity.toml\" to something else to allow"
|
||||
+ " Velocity to generate a config file for the new version. You may then configure "
|
||||
+ " that file as you normally would. The only differences are the config-version "
|
||||
+ "and \"forwarding-secret\" has been replaced by \"forwarding-secret-file\".");
|
||||
|
||||
// Default legacy handling
|
||||
forwardingSecretString = System.getenv()
|
||||
@@ -493,7 +513,8 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
if (Files.isRegularFile(secretPath)) {
|
||||
forwardingSecretString = String.join("", Files.readAllLines(secretPath));
|
||||
} else {
|
||||
throw new RuntimeException("The file " + forwardSecretFile + " is not a valid file or it is a directory.");
|
||||
throw new RuntimeException(
|
||||
"The file " + forwardSecretFile + " is not a valid file or it is a directory.");
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("The forwarding-secret-file does not exist.");
|
||||
@@ -632,12 +653,11 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
}
|
||||
|
||||
/**
|
||||
* TOML requires keys to match a regex of {@code [A-Za-z0-9_-]} unless it is wrapped in
|
||||
* quotes; however, the TOML parser returns the key with the quotes so we need to clean the
|
||||
* server name before we pass it onto server registration to keep proper server name behavior.
|
||||
* TOML requires keys to match a regex of {@code [A-Za-z0-9_-]} unless it is wrapped in quotes;
|
||||
* however, the TOML parser returns the key with the quotes so we need to clean the server name
|
||||
* before we pass it onto server registration to keep proper server name behavior.
|
||||
*
|
||||
* @param name the server name to clean
|
||||
*
|
||||
* @return the cleaned server name
|
||||
*/
|
||||
private String cleanServerName(String name) {
|
||||
@@ -705,19 +725,32 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
|
||||
private static class Advanced {
|
||||
|
||||
@Expose private int compressionThreshold = 256;
|
||||
@Expose private int compressionLevel = -1;
|
||||
@Expose private int loginRatelimit = 3000;
|
||||
@Expose private int connectionTimeout = 5000;
|
||||
@Expose private int readTimeout = 30000;
|
||||
@Expose private boolean proxyProtocol = false;
|
||||
@Expose private boolean tcpFastOpen = false;
|
||||
@Expose private boolean bungeePluginMessageChannel = true;
|
||||
@Expose private boolean showPingRequests = false;
|
||||
@Expose private boolean failoverOnUnexpectedServerDisconnect = true;
|
||||
@Expose private boolean announceProxyCommands = true;
|
||||
@Expose private boolean logCommandExecutions = false;
|
||||
@Expose private boolean logPlayerConnections = true;
|
||||
@Expose
|
||||
private int compressionThreshold = 256;
|
||||
@Expose
|
||||
private int compressionLevel = -1;
|
||||
@Expose
|
||||
private int loginRatelimit = 3000;
|
||||
@Expose
|
||||
private int connectionTimeout = 5000;
|
||||
@Expose
|
||||
private int readTimeout = 30000;
|
||||
@Expose
|
||||
private boolean proxyProtocol = false;
|
||||
@Expose
|
||||
private boolean tcpFastOpen = false;
|
||||
@Expose
|
||||
private boolean bungeePluginMessageChannel = true;
|
||||
@Expose
|
||||
private boolean showPingRequests = false;
|
||||
@Expose
|
||||
private boolean failoverOnUnexpectedServerDisconnect = true;
|
||||
@Expose
|
||||
private boolean announceProxyCommands = true;
|
||||
@Expose
|
||||
private boolean logCommandExecutions = false;
|
||||
@Expose
|
||||
private boolean logPlayerConnections = true;
|
||||
|
||||
private Advanced() {
|
||||
}
|
||||
@@ -819,10 +852,14 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
|
||||
private static class Query {
|
||||
|
||||
@Expose private boolean queryEnabled = false;
|
||||
@Expose private int queryPort = 25577;
|
||||
@Expose private String queryMap = "Velocity";
|
||||
@Expose private boolean showPlugins = false;
|
||||
@Expose
|
||||
private boolean queryEnabled = false;
|
||||
@Expose
|
||||
private int queryPort = 25577;
|
||||
@Expose
|
||||
private String queryMap = "Velocity";
|
||||
@Expose
|
||||
private boolean showPlugins = false;
|
||||
|
||||
private Query() {
|
||||
}
|
||||
@@ -870,7 +907,11 @@ public class VelocityConfiguration implements ProxyConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for metrics.
|
||||
*/
|
||||
public static class Metrics {
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
private Metrics(CommentedConfig toml) {
|
||||
|
@@ -42,8 +42,8 @@ public interface ConnectionType {
|
||||
BackendConnectionPhase getInitialBackendPhase();
|
||||
|
||||
/**
|
||||
* Adds properties to the {@link GameProfile} if required. If any properties
|
||||
* are added, the returned {@link GameProfile} will be a copy.
|
||||
* Adds properties to the {@link GameProfile} if required. If any properties are added, the
|
||||
* returned {@link GameProfile} will be a copy.
|
||||
*
|
||||
* @param original The original {@link GameProfile}
|
||||
* @param forwardingType The Velocity {@link PlayerInfoForwarding}
|
||||
|
@@ -29,9 +29,8 @@ import com.velocitypowered.proxy.connection.util.ConnectionTypeImpl;
|
||||
public final class ConnectionTypes {
|
||||
|
||||
/**
|
||||
* Indicates that the connection has yet to reach the
|
||||
* point where we have a definitive answer as to what
|
||||
* type of connection we have.
|
||||
* Indicates that the connection has yet to reach the point where we have a definitive answer as
|
||||
* to what type of connection we have.
|
||||
*/
|
||||
public static final ConnectionType UNDETERMINED =
|
||||
new ConnectionTypeImpl(ClientConnectionPhases.VANILLA, BackendConnectionPhases.UNKNOWN);
|
||||
@@ -46,8 +45,7 @@ public final class ConnectionTypes {
|
||||
LegacyForgeHandshakeClientPhase.NOT_STARTED, BackendConnectionPhases.UNKNOWN);
|
||||
|
||||
/**
|
||||
* Indicates that the connection is a 1.8-1.12 Forge
|
||||
* connection.
|
||||
* Indicates that the connection is a 1.8-1.12 Forge connection.
|
||||
*/
|
||||
public static final ConnectionType LEGACY_FORGE = new LegacyForgeConnectionType();
|
||||
|
||||
|
@@ -87,6 +87,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Initializes a new {@link MinecraftConnection} instance.
|
||||
*
|
||||
* @param channel the channel on the connection
|
||||
* @param server the Velocity instance
|
||||
*/
|
||||
@@ -211,6 +212,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Writes and immediately flushes a message to the connection.
|
||||
*
|
||||
* @param msg the message to write
|
||||
*/
|
||||
public void write(Object msg) {
|
||||
@@ -223,6 +225,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Writes, but does not flush, a message to the connection.
|
||||
*
|
||||
* @param msg the message to write
|
||||
*/
|
||||
public void delayedWrite(Object msg) {
|
||||
@@ -244,6 +247,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Closes the connection after writing the {@code msg}.
|
||||
*
|
||||
* @param msg the message to write
|
||||
*/
|
||||
public void closeWith(Object msg) {
|
||||
@@ -273,6 +277,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Immediately closes the connection.
|
||||
*
|
||||
* @param markKnown whether the disconnection is known
|
||||
*/
|
||||
public void close(boolean markKnown) {
|
||||
@@ -319,6 +324,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Determines whether or not the channel should continue reading data automaticaly.
|
||||
*
|
||||
* @param autoReading whether or not we should read data automatically
|
||||
*/
|
||||
public void setAutoReading(boolean autoReading) {
|
||||
@@ -337,6 +343,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Changes the state of the Minecraft connection.
|
||||
*
|
||||
* @param state the new state
|
||||
*/
|
||||
public void setState(StateRegistry state) {
|
||||
@@ -353,6 +360,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Sets the new protocol version for the connection.
|
||||
*
|
||||
* @param protocolVersion the protocol version to use
|
||||
*/
|
||||
public void setProtocolVersion(ProtocolVersion protocolVersion) {
|
||||
@@ -380,6 +388,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Sets the session handler for this connection.
|
||||
*
|
||||
* @param sessionHandler the handler to use
|
||||
*/
|
||||
public void setSessionHandler(MinecraftSessionHandler sessionHandler) {
|
||||
@@ -399,6 +408,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
/**
|
||||
* Sets the compression threshold on the connection. You are responsible for sending
|
||||
* {@link com.velocitypowered.proxy.protocol.packet.SetCompression} beforehand.
|
||||
*
|
||||
* @param threshold the compression threshold to use
|
||||
*/
|
||||
public void setCompressionThreshold(int threshold) {
|
||||
@@ -440,6 +450,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Enables encryption on the connection.
|
||||
*
|
||||
* @param secret the secret key negotiated between the client and the server
|
||||
* @throws GeneralSecurityException if encryption can't be enabled
|
||||
*/
|
||||
@@ -471,6 +482,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Gets the detected {@link ConnectionType}.
|
||||
*
|
||||
* @return The {@link ConnectionType}
|
||||
*/
|
||||
public ConnectionType getType() {
|
||||
@@ -479,6 +491,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
||||
|
||||
/**
|
||||
* Sets the detected {@link ConnectionType}.
|
||||
*
|
||||
* @param connectionType The {@link ConnectionType}
|
||||
*/
|
||||
public void setType(ConnectionType connectionType) {
|
||||
|
@@ -17,6 +17,9 @@
|
||||
|
||||
package com.velocitypowered.proxy.connection;
|
||||
|
||||
/**
|
||||
* Marker interface for something that can be associated with a {@link MinecraftConnection}.
|
||||
*/
|
||||
public interface MinecraftConnectionAssociation {
|
||||
|
||||
}
|
||||
|
@@ -63,6 +63,9 @@ import com.velocitypowered.proxy.protocol.packet.title.TitleTextPacket;
|
||||
import com.velocitypowered.proxy.protocol.packet.title.TitleTimesPacket;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
|
||||
/**
|
||||
* Interface for dispatching received Minecraft packets.
|
||||
*/
|
||||
public interface MinecraftSessionHandler {
|
||||
|
||||
default boolean beforeHandle() {
|
||||
|
@@ -17,6 +17,9 @@
|
||||
|
||||
package com.velocitypowered.proxy.connection;
|
||||
|
||||
/**
|
||||
* Various useful constants.
|
||||
*/
|
||||
public class VelocityConstants {
|
||||
|
||||
private VelocityConstants() {
|
||||
|
@@ -30,9 +30,10 @@ import com.velocitypowered.proxy.protocol.packet.PluginMessage;
|
||||
public interface BackendConnectionPhase {
|
||||
|
||||
/**
|
||||
* Handle a plugin message in the context of
|
||||
* this phase.
|
||||
* Handle a plugin message in the context of this phase.
|
||||
*
|
||||
* @param server the server connection
|
||||
* @param player the player
|
||||
* @param message The message to handle
|
||||
* @return true if handled, false otherwise.
|
||||
*/
|
||||
@@ -44,6 +45,7 @@ public interface BackendConnectionPhase {
|
||||
|
||||
/**
|
||||
* Indicates whether the connection is considered complete.
|
||||
*
|
||||
* @return true if so
|
||||
*/
|
||||
default boolean consideredComplete() {
|
||||
@@ -51,8 +53,8 @@ public interface BackendConnectionPhase {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when the provided server connection is about to be terminated
|
||||
* because the provided player is connecting to a new server.
|
||||
* Fired when the provided server connection is about to be terminated because the provided player
|
||||
* is connecting to a new server.
|
||||
*
|
||||
* @param serverConnection The server the player is disconnecting from
|
||||
* @param player The player
|
||||
|
@@ -32,7 +32,8 @@ public final class BackendConnectionPhases {
|
||||
/**
|
||||
* The backend connection is vanilla.
|
||||
*/
|
||||
public static final BackendConnectionPhase VANILLA = new BackendConnectionPhase() {};
|
||||
public static final BackendConnectionPhase VANILLA = new BackendConnectionPhase() {
|
||||
};
|
||||
|
||||
/**
|
||||
* The backend connection is unknown at this time.
|
||||
@@ -54,9 +55,9 @@ public final class BackendConnectionPhases {
|
||||
};
|
||||
|
||||
/**
|
||||
* A special backend phase used to indicate that this connection is about to become
|
||||
* obsolete (transfer to a new server, for instance) and that Forge messages ought to be
|
||||
* forwarded on to an in-flight connection instead.
|
||||
* A special backend phase used to indicate that this connection is about to become obsolete
|
||||
* (transfer to a new server, for instance) and that Forge messages ought to be forwarded on to an
|
||||
* in-flight connection instead.
|
||||
*/
|
||||
public static final BackendConnectionPhase IN_TRANSITION = new BackendConnectionPhase() {
|
||||
@Override
|
||||
|
@@ -61,7 +61,11 @@ import java.util.regex.Pattern;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Handles a connected player.
|
||||
*/
|
||||
public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
private static final Pattern PLAUSIBLE_SHA1_HASH = Pattern.compile("^[a-z0-9]{40}$");
|
||||
private static final Logger logger = LogManager.getLogger(BackendPlaySessionHandler.class);
|
||||
private static final boolean BACKPRESSURE_LOG = Boolean
|
||||
@@ -286,7 +290,8 @@ public class BackendPlaySessionHandler implements MinecraftSessionHandler {
|
||||
public boolean handle(ServerData packet) {
|
||||
server.getServerListPingHandler().getInitialPing(this.serverConn.getPlayer())
|
||||
.thenComposeAsync(
|
||||
ping -> server.getEventManager().fire(new ProxyPingEvent(this.serverConn.getPlayer(), ping)),
|
||||
ping -> server.getEventManager()
|
||||
.fire(new ProxyPingEvent(this.serverConn.getPlayer(), ping)),
|
||||
playerConnection.eventLoop()
|
||||
)
|
||||
.thenAcceptAsync(pingEvent ->
|
||||
|
@@ -44,9 +44,16 @@ import net.kyori.adventure.text.serializer.ComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
@SuppressFBWarnings(value = "OS_OPEN_STREAM", justification = "Most methods in this class open "
|
||||
/**
|
||||
* Handles messages coming from servers trying to communicate with the BungeeCord plugin
|
||||
* messaging channel interface.
|
||||
*/
|
||||
@SuppressFBWarnings(
|
||||
value = "OS_OPEN_STREAM",
|
||||
justification = "Most methods in this class open "
|
||||
+ "instances of ByteBufDataOutput backed by heap-allocated ByteBufs. Closing them does "
|
||||
+ "nothing.")
|
||||
+ "nothing."
|
||||
)
|
||||
public class BungeeCordMessageResponder {
|
||||
|
||||
private static final MinecraftChannelIdentifier MODERN_CHANNEL = MinecraftChannelIdentifier
|
||||
|
@@ -52,7 +52,11 @@ import net.kyori.adventure.text.Component;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
/**
|
||||
* Handles a player trying to log into the proxy.
|
||||
*/
|
||||
public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
|
||||
private static final Logger logger = LogManager.getLogger(LoginSessionHandler.class);
|
||||
|
||||
private static final Component MODERN_IP_FORWARDING_FAILURE = Component
|
||||
@@ -88,7 +92,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
requestedForwardingVersion = packet.content().readByte();
|
||||
}
|
||||
ByteBuf forwardingData = createForwardingData(configuration.getForwardingSecret(),
|
||||
serverConn.getPlayerRemoteAddressAsString(), serverConn.getPlayer(), requestedForwardingVersion);
|
||||
serverConn.getPlayerRemoteAddressAsString(), serverConn.getPlayer(),
|
||||
requestedForwardingVersion);
|
||||
|
||||
LoginPluginResponse response = new LoginPluginResponse(packet.getId(), true, forwardingData);
|
||||
mc.write(response);
|
||||
@@ -178,7 +183,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
requested = Math.min(requested, VelocityConstants.MODERN_FORWARDING_MAX_VERSION);
|
||||
if (requested > VelocityConstants.MODERN_FORWARDING_DEFAULT) {
|
||||
if (player.getProtocolVersion().compareTo(ProtocolVersion.MINECRAFT_1_19_3) >= 0) {
|
||||
return requested >= VelocityConstants.MODERN_LAZY_SESSION ? VelocityConstants.MODERN_LAZY_SESSION
|
||||
return requested >= VelocityConstants.MODERN_LAZY_SESSION
|
||||
? VelocityConstants.MODERN_LAZY_SESSION
|
||||
: VelocityConstants.MODERN_FORWARDING_DEFAULT;
|
||||
}
|
||||
if (player.getIdentifiedKey() != null) {
|
||||
@@ -189,7 +195,8 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
|
||||
// Since V2 is not backwards compatible we have to throw the key if v2 and requested is v1
|
||||
case LINKED_V2:
|
||||
return requested >= VelocityConstants.MODERN_FORWARDING_WITH_KEY_V2
|
||||
? VelocityConstants.MODERN_FORWARDING_WITH_KEY_V2 : VelocityConstants.MODERN_FORWARDING_DEFAULT;
|
||||
? VelocityConstants.MODERN_FORWARDING_WITH_KEY_V2
|
||||
: VelocityConstants.MODERN_FORWARDING_DEFAULT;
|
||||
default:
|
||||
return VelocityConstants.MODERN_FORWARDING_DEFAULT;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user