Mirror von
https://github.com/PaperMC/Velocity.git
synchronisiert 2024-11-16 21:10:30 +01:00
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.
Dieser Commit ist enthalten in:
Ursprung
ffa4c95435
Commit
d72d707b1c
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
Normale Datei
80
api/build.gradle.kts
Normale Datei
@ -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.FileObject;
|
||||||
import javax.tools.StandardLocation;
|
import javax.tools.StandardLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Annotation processor for Velocity.
|
||||||
|
*/
|
||||||
@SupportedAnnotationTypes({"com.velocitypowered.api.plugin.Plugin"})
|
@SupportedAnnotationTypes({"com.velocitypowered.api.plugin.Plugin"})
|
||||||
public class PluginAnnotationProcessor extends AbstractProcessor {
|
public class PluginAnnotationProcessor extends AbstractProcessor {
|
||||||
|
|
||||||
|
@ -19,6 +19,9 @@ import java.util.regex.Pattern;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialized version of {@link com.velocitypowered.api.plugin.PluginDescription}.
|
||||||
|
*/
|
||||||
public final class SerializedPluginDescription {
|
public final class SerializedPluginDescription {
|
||||||
|
|
||||||
public static final Pattern ID_PATTERN = Pattern.compile("[a-z][a-z0-9-_]{0,63}");
|
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 {
|
public static final class Dependency {
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
|
@ -84,6 +84,7 @@ public interface CommandManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@link CommandMeta} from the specified command alias, if registered.
|
* Retrieves the {@link CommandMeta} from the specified command alias, if registered.
|
||||||
|
*
|
||||||
* @param alias the command alias to lookup
|
* @param alias the command alias to lookup
|
||||||
* @return an {@link CommandMeta} of the alias
|
* @return an {@link CommandMeta} of the alias
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +29,7 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a CommandExecuteEvent.
|
* Constructs a CommandExecuteEvent.
|
||||||
|
*
|
||||||
* @param commandSource the source executing the command
|
* @param commandSource the source executing the command
|
||||||
* @param command the command being executed without first slash
|
* @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
|
* @return the original command being executed
|
||||||
*/
|
*/
|
||||||
public String getCommand() {
|
public String getCommand() {
|
||||||
@ -108,6 +110,7 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows the command to be sent, without modification.
|
* Allows the command to be sent, without modification.
|
||||||
|
*
|
||||||
* @return the allowed result
|
* @return the allowed result
|
||||||
*/
|
*/
|
||||||
public static CommandResult allowed() {
|
public static CommandResult allowed() {
|
||||||
@ -116,6 +119,7 @@ public final class CommandExecuteEvent implements ResultedEvent<CommandResult> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the command from being executed.
|
* Prevents the command from being executed.
|
||||||
|
*
|
||||||
* @return the denied result
|
* @return the denied result
|
||||||
*/
|
*/
|
||||||
public static CommandResult denied() {
|
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
|
* @return the forward result
|
||||||
*/
|
*/
|
||||||
public static CommandResult forwardToServer() {
|
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.
|
* Prevents the command from being executed on proxy, but forward command to server.
|
||||||
|
*
|
||||||
* @param newCommand the command without first slash to use instead
|
* @param newCommand the command without first slash to use instead
|
||||||
* @return a result with a new command being forwarded to server
|
* @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
|
* @param newCommand the command to use instead without first slash
|
||||||
* @return a result with a new command
|
* @return a result with a new command
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +29,7 @@ public class PlayerAvailableCommandsEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an available commands event.
|
* Constructs an available commands event.
|
||||||
|
*
|
||||||
* @param player the targeted player
|
* @param player the targeted player
|
||||||
* @param rootNode the Brigadier root node
|
* @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 {
|
public enum LoginStatus {
|
||||||
|
|
||||||
SUCCESSFUL_LOGIN,
|
SUCCESSFUL_LOGIN,
|
||||||
|
@ -37,6 +37,7 @@ public final class PreLoginEvent implements ResultedEvent<PreLoginEvent.PreLogin
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
|
*
|
||||||
* @param connection the connection logging into the proxy
|
* @param connection the connection logging into the proxy
|
||||||
* @param username the player's username
|
* @param username the player's username
|
||||||
*/
|
*/
|
||||||
|
@ -35,6 +35,7 @@ public final class GameProfileRequestEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
|
*
|
||||||
* @param connection the connection connecting to the proxy
|
* @param connection the connection connecting to the proxy
|
||||||
* @param originalProfile the original {@link GameProfile} for the user
|
* @param originalProfile the original {@link GameProfile} for the user
|
||||||
* @param onlineMode whether or not the user connected in online or offline mode
|
* @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.
|
* Creates a {@code KickedFromServerEvent} instance.
|
||||||
|
*
|
||||||
* @param player the player affected
|
* @param player the player affected
|
||||||
* @param server the server the player disconnected from
|
* @param server the server the player disconnected from
|
||||||
* @param originalReason the reason for being kicked, optional
|
* @param originalReason the reason for being kicked, optional
|
||||||
|
@ -28,6 +28,7 @@ public final class PlayerChatEvent implements ResultedEvent<PlayerChatEvent.Chat
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a PlayerChatEvent.
|
* Constructs a PlayerChatEvent.
|
||||||
|
*
|
||||||
* @param player the player sending the message
|
* @param player the player sending the message
|
||||||
* @param message the message being sent
|
* @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.
|
* Allows the message to be sent, without modification.
|
||||||
|
*
|
||||||
* @return the allowed result
|
* @return the allowed result
|
||||||
*/
|
*/
|
||||||
public static ChatResult allowed() {
|
public static ChatResult allowed() {
|
||||||
@ -104,6 +106,7 @@ public final class PlayerChatEvent implements ResultedEvent<PlayerChatEvent.Chat
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevents the message from being sent.
|
* Prevents the message from being sent.
|
||||||
|
*
|
||||||
* @return the denied result
|
* @return the denied result
|
||||||
*/
|
*/
|
||||||
public static ChatResult denied() {
|
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
|
* @param message the message to use instead
|
||||||
* @return a result with a new message
|
* @return a result with a new message
|
||||||
*/
|
*/
|
||||||
|
@ -28,6 +28,7 @@ public class PlayerChooseInitialServerEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a PlayerChooseInitialServerEvent.
|
* Constructs a PlayerChooseInitialServerEvent.
|
||||||
|
*
|
||||||
* @param player the player that was connected
|
* @param player the player that was connected
|
||||||
* @param initialServer the initial server selected, may be {@code null}
|
* @param initialServer the initial server selected, may be {@code null}
|
||||||
*/
|
*/
|
||||||
@ -46,9 +47,10 @@ public class PlayerChooseInitialServerEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the new initial server.
|
* Sets the new initial server.
|
||||||
|
*
|
||||||
* @param server the initial server the player should connect to
|
* @param server the initial server the player should connect to
|
||||||
*/
|
*/
|
||||||
public void setInitialServer(RegisteredServer server) {
|
public void setInitialServer(@Nullable RegisteredServer server) {
|
||||||
this.initialServer = server;
|
this.initialServer = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@ public class PlayerResourcePackStatusEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates this event.
|
* Instantiates this event.
|
||||||
|
*
|
||||||
* @deprecated Use {@link PlayerResourcePackStatusEvent#PlayerResourcePackStatusEvent
|
* @deprecated Use {@link PlayerResourcePackStatusEvent#PlayerResourcePackStatusEvent
|
||||||
* (Player, Status, ResourcePackInfo)} instead.
|
* (Player, Status, ResourcePackInfo)} instead.
|
||||||
*/
|
*/
|
||||||
|
@ -33,6 +33,7 @@ public final class ServerConnectedEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a ServerConnectedEvent.
|
* Constructs a ServerConnectedEvent.
|
||||||
|
*
|
||||||
* @param player the player that was connected
|
* @param player the player that was connected
|
||||||
* @param server the server the player was connected to
|
* @param server the server the player was connected to
|
||||||
* @param previousServer the server the player was previously connected to, null if none
|
* @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}.
|
* Constructs a new {@code ServerLoginPluginMessageEvent}.
|
||||||
|
*
|
||||||
* @param connection the connection on which the plugin message was sent
|
* @param connection the connection on which the plugin message was sent
|
||||||
* @param identifier the channel identifier for the message sent
|
* @param identifier the channel identifier for the message sent
|
||||||
* @param contents the contents of the message
|
* @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 {
|
public static class ResponseResult implements ResultedEvent.Result {
|
||||||
|
|
||||||
private static final ResponseResult UNKNOWN = new ResponseResult(null);
|
private static final ResponseResult UNKNOWN = new ResponseResult(null);
|
||||||
|
@ -33,6 +33,7 @@ public final class ServerPreConnectEvent implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the ServerPreConnectEvent.
|
* Creates the ServerPreConnectEvent.
|
||||||
|
*
|
||||||
* @param player the player who is connecting to a server
|
* @param player the player who is connecting to a server
|
||||||
* @param originalServer the server the player was trying to connect to
|
* @param originalServer the server the player was trying to connect to
|
||||||
*/
|
*/
|
||||||
@ -43,6 +44,7 @@ public final class ServerPreConnectEvent implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the ServerPreConnectEvent.
|
* Creates the ServerPreConnectEvent.
|
||||||
|
*
|
||||||
* @param player the player who is connecting to a server
|
* @param player the player who is connecting to a server
|
||||||
* @param originalServer the server the player was trying to connect to
|
* @param originalServer the server the player was trying to connect to
|
||||||
* @param previousServer the server the player ís connected 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.
|
* Returns the player connecting to the server.
|
||||||
|
*
|
||||||
* @return the player connecting to the server
|
* @return the player connecting to the server
|
||||||
*/
|
*/
|
||||||
public Player getPlayer() {
|
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
|
* 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 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()}.
|
* player is currently on when this event is fired, use {@link #getPreviousServer()}.
|
||||||
|
*
|
||||||
* @return the server that the player originally tried to connect to
|
* @return the server that the player originally tried to connect to
|
||||||
*/
|
*/
|
||||||
public RegisteredServer getOriginalServer() {
|
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
|
* {@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
|
* 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).
|
* beforehand (for instance, if the player has just joined the proxy).
|
||||||
|
*
|
||||||
* @return the server the player is currently connected to.
|
* @return the server the player is currently connected to.
|
||||||
*/
|
*/
|
||||||
public @Nullable RegisteredServer getPreviousServer() {
|
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
|
* 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
|
* is used, then {@link ConnectionRequestBuilder#connect()}'s result will have the status
|
||||||
* {@link Status#CONNECTION_CANCELLED}.
|
* {@link Status#CONNECTION_CANCELLED}.
|
||||||
|
*
|
||||||
* @return a result to deny conneections
|
* @return a result to deny conneections
|
||||||
*/
|
*/
|
||||||
public static ServerResult denied() {
|
public static ServerResult denied() {
|
||||||
@ -145,6 +151,7 @@ public final class ServerPreConnectEvent implements
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows the player to connect to the specified server.
|
* Allows the player to connect to the specified server.
|
||||||
|
*
|
||||||
* @param server the new server to connect to
|
* @param server the new server to connect to
|
||||||
* @return a result to allow the player to connect to the specified server
|
* @return a result to allow the player to connect to the specified server
|
||||||
*/
|
*/
|
||||||
|
@ -28,7 +28,7 @@ public class ServerResourcePackSendEvent implements ResultedEvent<ResultedEvent.
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new ServerResourcePackSendEvent.
|
* Constructs a new ServerResourcePackSendEvent.
|
||||||
*
|
*
|
||||||
* @param receivedResourcePack The resource pack the server sent.
|
* @param receivedResourcePack The resource pack the server sent.
|
||||||
* @param serverConnection The connection this occurred on.
|
* @param serverConnection The connection this occurred on.
|
||||||
*/
|
*/
|
||||||
|
@ -29,6 +29,7 @@ public class TabCompleteEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new TabCompleteEvent instance.
|
* Constructs a new TabCompleteEvent instance.
|
||||||
|
*
|
||||||
* @param player the player
|
* @param player the player
|
||||||
* @param partialMessage the partial message
|
* @param partialMessage the partial message
|
||||||
* @param suggestions the initial list of suggestions
|
* @param suggestions the initial list of suggestions
|
||||||
@ -41,6 +42,7 @@ public class TabCompleteEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the player requesting the tab completion.
|
* Returns the player requesting the tab completion.
|
||||||
|
*
|
||||||
* @return the requesting player
|
* @return the requesting player
|
||||||
*/
|
*/
|
||||||
public Player getPlayer() {
|
public Player getPlayer() {
|
||||||
@ -49,6 +51,7 @@ public class TabCompleteEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the message being partially completed.
|
* Returns the message being partially completed.
|
||||||
|
*
|
||||||
* @return the partial message
|
* @return the partial message
|
||||||
*/
|
*/
|
||||||
public String getPartialMessage() {
|
public String getPartialMessage() {
|
||||||
@ -57,6 +60,7 @@ public class TabCompleteEvent {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all the suggestions provided to the user, as a mutable list.
|
* Returns all the suggestions provided to the user, as a mutable list.
|
||||||
|
*
|
||||||
* @return the suggestions
|
* @return the suggestions
|
||||||
*/
|
*/
|
||||||
public List<String> getSuggestions() {
|
public List<String> getSuggestions() {
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
package com.velocitypowered.api.plugin;
|
package com.velocitypowered.api.plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown if a JAR in the plugin directory does not look valid.
|
||||||
|
*/
|
||||||
public class InvalidPluginException extends Exception {
|
public class InvalidPluginException extends Exception {
|
||||||
|
|
||||||
public InvalidPluginException() {
|
public InvalidPluginException() {
|
||||||
|
@ -27,6 +27,7 @@ public final class PluginDependency {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
|
*
|
||||||
* @param id the plugin ID
|
* @param id the plugin ID
|
||||||
* @param version an optional version
|
* @param version an optional version
|
||||||
* @param optional whether or not this dependency is optional
|
* @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;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows the server to communicate with a client logging into the proxy using login plugin
|
* Represents a connextion that is in the login phase. This is most useful in conjunction
|
||||||
* messages.
|
* for login plugin messages.
|
||||||
*/
|
*/
|
||||||
public interface LoginPhaseConnection extends InboundConnection, KeyIdentifiable {
|
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,
|
void sendLoginPluginMessage(ChannelIdentifier identifier, byte[] contents,
|
||||||
MessageConsumer consumer);
|
MessageConsumer consumer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumes the message.
|
||||||
|
*/
|
||||||
interface MessageConsumer {
|
interface MessageConsumer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumes the message and responds to it.
|
||||||
|
*
|
||||||
|
* @param responseBody the message from the client, if any
|
||||||
|
*/
|
||||||
void onMessageResponse(byte @Nullable [] responseBody);
|
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.HoverEvent;
|
||||||
import net.kyori.adventure.text.event.HoverEventSource;
|
import net.kyori.adventure.text.event.HoverEventSource;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a player who is connected to the proxy.
|
* Represents a player who is connected to the proxy.
|
||||||
*/
|
*/
|
||||||
public interface Player extends CommandSource, Identified, InboundConnection,
|
public interface Player extends
|
||||||
ChannelMessageSource, ChannelMessageSink, HoverEventSource<HoverEvent.ShowEntity>, Keyed, KeyIdentifiable {
|
/* Fundamental Velocity interfaces */
|
||||||
|
CommandSource, InboundConnection, ChannelMessageSource, ChannelMessageSink,
|
||||||
|
/* Adventure-specific interfaces */
|
||||||
|
Identified, HoverEventSource<HoverEvent.ShowEntity>, Keyed, KeyIdentifiable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the player's current username.
|
* Returns the player's current username.
|
||||||
@ -48,8 +52,8 @@ public interface Player extends CommandSource, Identified, InboundConnection,
|
|||||||
String getUsername();
|
String getUsername();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the locale the proxy will use to send messages translated via the Adventure global translator.
|
* Returns the locale the proxy will use to send messages translated via the Adventure global
|
||||||
* By default, the value of {@link PlayerSettings#getLocale()} is used.
|
* 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>
|
* <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.
|
* Validates a signature against this public key.
|
||||||
|
*
|
||||||
* @param signature the signature data
|
* @param signature the signature data
|
||||||
* @param toVerify the signed data
|
* @param toVerify the signed data
|
||||||
*
|
*
|
||||||
@ -53,6 +54,9 @@ public interface IdentifiedKey extends KeySigned {
|
|||||||
*/
|
*/
|
||||||
Revision getKeyRevision();
|
Revision getKeyRevision();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The different versions of player keys, per Minecraft version.
|
||||||
|
*/
|
||||||
enum Revision {
|
enum Revision {
|
||||||
GENERIC_V1(ImmutableSet.of(), ImmutableSet.of(ProtocolVersion.MINECRAFT_1_19)),
|
GENERIC_V1(ImmutableSet.of(), ImmutableSet.of(ProtocolVersion.MINECRAFT_1_19)),
|
||||||
LINKED_V2(ImmutableSet.of(), ImmutableSet.of(ProtocolVersion.MINECRAFT_1_19_1));
|
LINKED_V2(ImmutableSet.of(), ImmutableSet.of(ProtocolVersion.MINECRAFT_1_19_1));
|
||||||
|
@ -7,15 +7,18 @@
|
|||||||
|
|
||||||
package com.velocitypowered.api.proxy.crypto;
|
package com.velocitypowered.api.proxy.crypto;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifies a type with a public RSA signature.
|
* Identifies a type with a public RSA signature.
|
||||||
*/
|
*/
|
||||||
public interface KeyIdentifiable {
|
public interface KeyIdentifiable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the timed identified key of the object context.
|
* Returns the timed identified key of the object context. This is only available if the client
|
||||||
* <p>Only available in 1.19 and newer</p>
|
* is running Minecraft 1.19 or newer.
|
||||||
|
*
|
||||||
* @return the key or null if not available
|
* @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 java.time.Instant;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the signature of a signed object.
|
||||||
|
*/
|
||||||
public interface KeySigned {
|
public interface KeySigned {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,6 +9,9 @@ package com.velocitypowered.api.proxy.crypto;
|
|||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A signed message.
|
||||||
|
*/
|
||||||
public interface SignedMessage extends KeySigned {
|
public interface SignedMessage extends KeySigned {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
package com.velocitypowered.api.proxy.messages;
|
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 com.google.common.base.Strings;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -49,13 +50,16 @@ public final class MinecraftChannelIdentifier implements ChannelIdentifier {
|
|||||||
* @return a new channel identifier
|
* @return a new channel identifier
|
||||||
*/
|
*/
|
||||||
public static MinecraftChannelIdentifier create(String namespace, String name) {
|
public static MinecraftChannelIdentifier create(String namespace, String name) {
|
||||||
Preconditions.checkArgument(!Strings.isNullOrEmpty(namespace), "namespace is null or empty");
|
checkArgument(!Strings.isNullOrEmpty(namespace), "namespace is null or empty");
|
||||||
Preconditions.checkArgument(name != null, "namespace is null or empty");
|
checkArgument(name != null, "namespace is null or empty");
|
||||||
Preconditions.checkArgument(VALID_IDENTIFIER_REGEX.matcher(namespace).matches(),
|
checkArgument(VALID_IDENTIFIER_REGEX.matcher(namespace).matches(),
|
||||||
"namespace is not valid, must match: %s got %s", VALID_IDENTIFIER_REGEX.toString(), namespace);
|
"namespace is not valid, must match: %s got %s",
|
||||||
Preconditions
|
VALID_IDENTIFIER_REGEX.toString(),
|
||||||
.checkArgument(VALID_IDENTIFIER_REGEX.matcher(name).matches(),
|
namespace);
|
||||||
"name is not valid, must match: %s got %s", VALID_IDENTIFIER_REGEX.toString(), name);
|
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);
|
return new MinecraftChannelIdentifier(namespace, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,12 +67,18 @@ public interface PlayerSettings {
|
|||||||
*/
|
*/
|
||||||
boolean isClientListingAllowed();
|
boolean isClientListingAllowed();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The client's current chat display mode.
|
||||||
|
*/
|
||||||
enum ChatMode {
|
enum ChatMode {
|
||||||
SHOWN,
|
SHOWN,
|
||||||
COMMANDS_ONLY,
|
COMMANDS_ONLY,
|
||||||
HIDDEN
|
HIDDEN
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The player's selected dominant hand.
|
||||||
|
*/
|
||||||
enum MainHand {
|
enum MainHand {
|
||||||
LEFT,
|
LEFT,
|
||||||
RIGHT
|
RIGHT
|
||||||
|
@ -10,6 +10,9 @@ package com.velocitypowered.api.proxy.player;
|
|||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
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 {
|
public interface ResourcePackInfo {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,12 +78,12 @@ public interface ResourcePackInfo {
|
|||||||
ResourcePackInfo.Builder asBuilder();
|
ResourcePackInfo.Builder asBuilder();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a copy of this {@link ResourcePackInfo} instance as a builder with the new URL as the pack URL so that
|
* Returns a copy of this {@link ResourcePackInfo} instance as a builder, using the new URL.
|
||||||
* it can be modified.
|
* <p/>
|
||||||
* It is <b>not</b> guaranteed that
|
* It is <b>not</b> guaranteed that
|
||||||
* {@code resourcePackInfo.asBuilder(resourcePackInfo.getUrl()).build().equals(resourcePackInfo)} is true.
|
* {@code resourcePackInfo.asBuilder(resourcePackInfo.getUrl()).build().equals(resourcePackInfo)}
|
||||||
* That is due to the transient {@link ResourcePackInfo#getOrigin()} and
|
* is true, because the {@link ResourcePackInfo#getOrigin()} and
|
||||||
* {@link ResourcePackInfo#getOriginalOrigin()} fields.
|
* {@link ResourcePackInfo#getOriginalOrigin()} fields are transient.
|
||||||
*
|
*
|
||||||
* @param newUrl The new URL to use in the updated builder.
|
* @param newUrl The new URL to use in the updated builder.
|
||||||
*
|
*
|
||||||
@ -88,6 +91,9 @@ public interface ResourcePackInfo {
|
|||||||
*/
|
*/
|
||||||
ResourcePackInfo.Builder asBuilder(String newUrl);
|
ResourcePackInfo.Builder asBuilder(String newUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder for {@link ResourcePackInfo} instances.
|
||||||
|
*/
|
||||||
interface Builder {
|
interface Builder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,6 +10,9 @@ package com.velocitypowered.api.proxy.player;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents what, if any, extended parts of the skin this player has.
|
||||||
|
*/
|
||||||
public final class SkinParts {
|
public final class SkinParts {
|
||||||
|
|
||||||
private final byte bitmask;
|
private final byte bitmask;
|
||||||
|
@ -121,7 +121,7 @@ public interface TabListEntry extends KeyIdentifiable {
|
|||||||
TabListEntry setGameMode(int gameMode);
|
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
|
* @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}.
|
* 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>For any player currently connected to this proxy this will be filled automatically.</p>
|
||||||
* <p>Will ignore mismatching key revisions data.</p>
|
* <p>Will ignore mismatching key revisions data.</p>
|
||||||
*
|
*
|
||||||
|
@ -245,6 +245,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the hostname for the response.
|
* Sets the hostname for the response.
|
||||||
|
*
|
||||||
* @param hostname the hostname to set
|
* @param hostname the hostname to set
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
@ -255,6 +256,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the game version for the response.
|
* Sets the game version for the response.
|
||||||
|
*
|
||||||
* @param gameVersion the game version to set
|
* @param gameVersion the game version to set
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
@ -265,6 +267,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the map that will appear in the response.
|
* Sets the map that will appear in the response.
|
||||||
|
*
|
||||||
* @param map the map to set
|
* @param map the map to set
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
@ -275,6 +278,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the players that are currently claimed to be online.
|
* Sets the players that are currently claimed to be online.
|
||||||
|
*
|
||||||
* @param currentPlayers a non-negative number representing all players online
|
* @param currentPlayers a non-negative number representing all players online
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
@ -286,6 +290,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum number of players this server purportedly can hold.
|
* Sets the maximum number of players this server purportedly can hold.
|
||||||
|
*
|
||||||
* @param maxPlayers a non-negative number representing the maximum number of builders
|
* @param maxPlayers a non-negative number representing the maximum number of builders
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
@ -297,6 +302,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the host where this proxy is running.
|
* Sets the host where this proxy is running.
|
||||||
|
*
|
||||||
* @param proxyHost the host where the proxy is running
|
* @param proxyHost the host where the proxy is running
|
||||||
* @return this instance, for chaining
|
* @return this instance, for chaining
|
||||||
*/
|
*/
|
||||||
@ -307,6 +313,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the port where this proxy is running.
|
* Sets the port where this proxy is running.
|
||||||
|
*
|
||||||
* @param proxyPort the port where the proxy is running
|
* @param proxyPort the port where the proxy is running
|
||||||
* @return this instance, for chaining
|
* @return this instance, for chaining
|
||||||
*/
|
*/
|
||||||
@ -319,6 +326,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the specified players to the player list.
|
* Adds the specified players to the player list.
|
||||||
|
*
|
||||||
* @param players the players to add
|
* @param players the players to add
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
@ -329,6 +337,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the specified players to the player list.
|
* Adds the specified players to the player list.
|
||||||
|
*
|
||||||
* @param players the players to add
|
* @param players the players to add
|
||||||
* @return this builder, for chaining
|
* @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()}.
|
* Removes all players from the builder. This does not affect {@link #getCurrentPlayers()}.
|
||||||
|
*
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
public Builder clearPlayers() {
|
public Builder clearPlayers() {
|
||||||
@ -348,6 +358,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the proxy version.
|
* Sets the proxy version.
|
||||||
|
*
|
||||||
* @param proxyVersion the proxy version to set
|
* @param proxyVersion the proxy version to set
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
@ -358,6 +369,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the specified plugins to the plugins list.
|
* Adds the specified plugins to the plugins list.
|
||||||
|
*
|
||||||
* @param plugins the plugins to add
|
* @param plugins the plugins to add
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
@ -368,6 +380,7 @@ public final class QueryResponse {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the specified plugins to the plugins list.
|
* Adds the specified plugins to the plugins list.
|
||||||
|
*
|
||||||
* @param plugins the plugins to add
|
* @param plugins the plugins to add
|
||||||
* @return this builder, for chaining
|
* @return this builder, for chaining
|
||||||
*/
|
*/
|
||||||
|
@ -191,6 +191,7 @@ public final class ServerPing {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses the modified {@code mods} list in the response.
|
* Uses the modified {@code mods} list in the response.
|
||||||
|
*
|
||||||
* @param mods the mods list to use
|
* @param mods the mods list to use
|
||||||
* @return this build, for chaining
|
* @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
|
* 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.
|
* builder can be re-used after this event has been called.
|
||||||
|
*
|
||||||
* @return a new {@link ServerPing} instance
|
* @return a new {@link ServerPing} instance
|
||||||
*/
|
*/
|
||||||
public ServerPing build() {
|
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 {
|
public static final class Version {
|
||||||
|
|
||||||
private final int protocol;
|
private final int protocol;
|
||||||
@ -310,6 +318,7 @@ public final class ServerPing {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
|
*
|
||||||
* @param protocol the protocol version as an integer
|
* @param protocol the protocol version as an integer
|
||||||
* @param name a friendly name for the protocol version
|
* @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 {
|
public static final class Players {
|
||||||
|
|
||||||
private final int online;
|
private final int online;
|
||||||
@ -360,6 +373,7 @@ public final class ServerPing {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance.
|
* Creates a new instance.
|
||||||
|
*
|
||||||
* @param online the number of online players
|
* @param online the number of online players
|
||||||
* @param max the maximum number of players
|
* @param max the maximum number of players
|
||||||
* @param sample a sample of players on the server
|
* @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 {
|
public static final class SamplePlayer {
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
package com.velocitypowered.api.scheduler;
|
package com.velocitypowered.api.scheduler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerates all possible task statuses.
|
||||||
|
*/
|
||||||
public enum TaskStatus {
|
public enum TaskStatus {
|
||||||
/**
|
/**
|
||||||
* The task is scheduled and is currently running.
|
* The task is scheduled and is currently running.
|
||||||
|
@ -24,6 +24,7 @@ public final class GameProfile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Mojang game profile.
|
* Creates a new Mojang game profile.
|
||||||
|
*
|
||||||
* @param id the UUID for the profile
|
* @param id the UUID for the profile
|
||||||
* @param name the profile's username
|
* @param name the profile's username
|
||||||
* @param properties properties for the profile
|
* @param properties properties for the profile
|
||||||
@ -35,6 +36,7 @@ public final class GameProfile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new Mojang game profile.
|
* Creates a new Mojang game profile.
|
||||||
|
*
|
||||||
* @param undashedId the undashed, Mojang-style UUID for the profile
|
* @param undashedId the undashed, Mojang-style UUID for the profile
|
||||||
* @param name the profile's username
|
* @param name the profile's username
|
||||||
* @param properties properties for the profile
|
* @param properties properties for the profile
|
||||||
@ -53,6 +55,7 @@ public final class GameProfile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the undashed, Mojang-style UUID.
|
* Returns the undashed, Mojang-style UUID.
|
||||||
|
*
|
||||||
* @return the undashed UUID
|
* @return the undashed UUID
|
||||||
*/
|
*/
|
||||||
public String getUndashedId() {
|
public String getUndashedId() {
|
||||||
@ -61,6 +64,7 @@ public final class GameProfile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the UUID associated with this game profile.
|
* Returns the UUID associated with this game profile.
|
||||||
|
*
|
||||||
* @return the UUID
|
* @return the UUID
|
||||||
*/
|
*/
|
||||||
public UUID getId() {
|
public UUID getId() {
|
||||||
@ -69,6 +73,7 @@ public final class GameProfile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the username associated with this profile.
|
* Returns the username associated with this profile.
|
||||||
|
*
|
||||||
* @return the username
|
* @return the username
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -77,6 +82,7 @@ public final class GameProfile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an immutable list of profile properties associated with this profile.
|
* Returns an immutable list of profile properties associated with this profile.
|
||||||
|
*
|
||||||
* @return the properties associated with this profile
|
* @return the properties associated with this profile
|
||||||
*/
|
*/
|
||||||
public List<Property> getProperties() {
|
public List<Property> getProperties() {
|
||||||
@ -183,6 +189,7 @@ public final class GameProfile {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a profile property entry.
|
* Creates a profile property entry.
|
||||||
|
*
|
||||||
* @param name the name of the property
|
* @param name the name of the property
|
||||||
* @param value the value of the property
|
* @param value the value of the property
|
||||||
* @param signature the Mojang signature for 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.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the information for a Forge mod list.
|
||||||
|
*/
|
||||||
public final class ModInfo {
|
public final class ModInfo {
|
||||||
|
|
||||||
public static final ModInfo DEFAULT = new ModInfo("FML", ImmutableList.of());
|
public static final ModInfo DEFAULT = new ModInfo("FML", ImmutableList.of());
|
||||||
@ -20,6 +23,12 @@ public final class ModInfo {
|
|||||||
private final String type;
|
private final String type;
|
||||||
private final List<Mod> modList;
|
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) {
|
public ModInfo(String type, List<Mod> modList) {
|
||||||
this.type = Preconditions.checkNotNull(type, "type");
|
this.type = Preconditions.checkNotNull(type, "type");
|
||||||
this.modList = ImmutableList.copyOf(modList);
|
this.modList = ImmutableList.copyOf(modList);
|
||||||
@ -58,6 +67,9 @@ public final class ModInfo {
|
|||||||
return Objects.hash(type, modList);
|
return Objects.hash(type, modList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a mod to send to the client.
|
||||||
|
*/
|
||||||
public static final class Mod {
|
public static final class Mod {
|
||||||
|
|
||||||
@SerializedName("modid")
|
@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
Normale Datei
47
build.gradle.kts
Normale Datei
@ -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
Normale Datei
27
buildSrc/build.gradle.kts
Normale Datei
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0"?>
|
||||||
<!DOCTYPE module PUBLIC
|
<!DOCTYPE module PUBLIC
|
||||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Checkstyle configuration that checks the Google coding conventions from Google Java Style
|
Checkstyle configuration that checks the Google coding conventions from Google Java Style
|
||||||
@ -16,10 +16,9 @@
|
|||||||
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
|
Authors: Max Vetrenko, Ruslan Diachenko, Roman Ivanov.
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<!--
|
<module name="Checker">
|
||||||
Developer notes: Fix MissingJavadocMethod/Type RequireEmptyLineBeforeBlockTagGroup and CustomImportOrder
|
<module name="SuppressWarningsFilter"/>
|
||||||
-->
|
|
||||||
<module name = "Checker">
|
|
||||||
<property name="charset" value="UTF-8"/>
|
<property name="charset" value="UTF-8"/>
|
||||||
|
|
||||||
<property name="severity" value="warning"/>
|
<property name="severity" value="warning"/>
|
||||||
@ -33,7 +32,7 @@
|
|||||||
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
|
<!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
|
||||||
<module name="SuppressionFilter">
|
<module name="SuppressionFilter">
|
||||||
<property name="file" value="${org.checkstyle.google.suppressionfilter.config}"
|
<property name="file" value="${org.checkstyle.google.suppressionfilter.config}"
|
||||||
default="checkstyle-suppressions.xml" />
|
default="checkstyle-suppressions.xml" />
|
||||||
<property name="optional" value="true"/>
|
<property name="optional" value="true"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
@ -45,7 +44,7 @@
|
|||||||
|
|
||||||
<module name="LineLength">
|
<module name="LineLength">
|
||||||
<property name="fileExtensions" value="java"/>
|
<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://"/>
|
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
@ -54,9 +53,9 @@
|
|||||||
<module name="IllegalTokenText">
|
<module name="IllegalTokenText">
|
||||||
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
|
<property name="tokens" value="STRING_LITERAL, CHAR_LITERAL"/>
|
||||||
<property name="format"
|
<property name="format"
|
||||||
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
|
value="\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
|
||||||
<property name="message"
|
<property name="message"
|
||||||
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
|
value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="AvoidEscapedUnicodeCharacters">
|
<module name="AvoidEscapedUnicodeCharacters">
|
||||||
<property name="allowEscapesForControlCharacters" value="true"/>
|
<property name="allowEscapesForControlCharacters" value="true"/>
|
||||||
@ -71,15 +70,15 @@
|
|||||||
<module name="EmptyBlock">
|
<module name="EmptyBlock">
|
||||||
<property name="option" value="TEXT"/>
|
<property name="option" value="TEXT"/>
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
|
value="LITERAL_TRY, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE, LITERAL_SWITCH"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="NeedBraces">
|
<module name="NeedBraces">
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, LITERAL_WHILE"/>
|
value="LITERAL_DO, LITERAL_ELSE, LITERAL_FOR, LITERAL_IF, LITERAL_WHILE"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="LeftCurly">
|
<module name="LeftCurly">
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_CONSTANT_DEF, ENUM_DEF,
|
value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_CONSTANT_DEF, ENUM_DEF,
|
||||||
INTERFACE_DEF, LAMBDA, LITERAL_CASE, LITERAL_CATCH, LITERAL_DEFAULT,
|
INTERFACE_DEF, LAMBDA, LITERAL_CASE, LITERAL_CATCH, LITERAL_DEFAULT,
|
||||||
LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF,
|
LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF,
|
||||||
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF,
|
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF,
|
||||||
@ -88,14 +87,14 @@
|
|||||||
<module name="RightCurly">
|
<module name="RightCurly">
|
||||||
<property name="id" value="RightCurlySame"/>
|
<property name="id" value="RightCurlySame"/>
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
|
value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE,
|
||||||
LITERAL_DO"/>
|
LITERAL_DO"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="RightCurly">
|
<module name="RightCurly">
|
||||||
<property name="id" value="RightCurlyAlone"/>
|
<property name="id" value="RightCurlyAlone"/>
|
||||||
<property name="option" value="alone"/>
|
<property name="option" value="alone"/>
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
|
value="CLASS_DEF, METHOD_DEF, CTOR_DEF, LITERAL_FOR, LITERAL_WHILE, STATIC_INIT,
|
||||||
INSTANCE_INIT, ANNOTATION_DEF, ENUM_DEF, INTERFACE_DEF, RECORD_DEF,
|
INSTANCE_INIT, ANNOTATION_DEF, ENUM_DEF, INTERFACE_DEF, RECORD_DEF,
|
||||||
COMPACT_CTOR_DEF"/>
|
COMPACT_CTOR_DEF"/>
|
||||||
</module>
|
</module>
|
||||||
@ -105,13 +104,7 @@
|
|||||||
<property name="query" value="//RCURLY[parent::SLIST[count(./*)=1]
|
<property name="query" value="//RCURLY[parent::SLIST[count(./*)=1]
|
||||||
or preceding-sibling::*[last()][self::LCURLY]]"/>
|
or preceding-sibling::*[last()][self::LCURLY]]"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="WhitespaceAfter">
|
<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="WhitespaceAround">
|
<module name="WhitespaceAround">
|
||||||
<property name="allowEmptyConstructors" value="true"/>
|
<property name="allowEmptyConstructors" value="true"/>
|
||||||
<property name="allowEmptyLambdas" value="true"/>
|
<property name="allowEmptyLambdas" value="true"/>
|
||||||
@ -120,7 +113,7 @@
|
|||||||
<property name="allowEmptyLoops" value="true"/>
|
<property name="allowEmptyLoops" value="true"/>
|
||||||
<property name="ignoreEnhancedForColon" value="false"/>
|
<property name="ignoreEnhancedForColon" value="false"/>
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR,
|
value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR,
|
||||||
BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAMBDA, LAND,
|
BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, DO_WHILE, EQUAL, GE, GT, LAMBDA, LAND,
|
||||||
LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY,
|
LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY,
|
||||||
LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
|
LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SWITCH, LITERAL_SYNCHRONIZED,
|
||||||
@ -128,10 +121,10 @@
|
|||||||
NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR,
|
NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR,
|
||||||
SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
|
SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
|
||||||
<message key="ws.notFollowed"
|
<message key="ws.notFollowed"
|
||||||
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks
|
value="WhitespaceAround: ''{0}'' is not followed by whitespace. Empty blocks
|
||||||
may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
|
may only be represented as '{}' when not part of a multi-block statement (4.1.3)"/>
|
||||||
<message key="ws.notPreceded"
|
<message key="ws.notPreceded"
|
||||||
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
|
value="WhitespaceAround: ''{0}'' is not preceded with whitespace."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="OneStatementPerLine"/>
|
<module name="OneStatementPerLine"/>
|
||||||
<module name="MultipleVariableDeclarations"/>
|
<module name="MultipleVariableDeclarations"/>
|
||||||
@ -142,7 +135,7 @@
|
|||||||
<module name="ModifierOrder"/>
|
<module name="ModifierOrder"/>
|
||||||
<module name="EmptyLineSeparator">
|
<module name="EmptyLineSeparator">
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
value="PACKAGE_DEF, IMPORT, STATIC_IMPORT, CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
||||||
STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF, RECORD_DEF,
|
STATIC_INIT, INSTANCE_INIT, METHOD_DEF, CTOR_DEF, VARIABLE_DEF, RECORD_DEF,
|
||||||
COMPACT_CTOR_DEF"/>
|
COMPACT_CTOR_DEF"/>
|
||||||
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
<property name="allowNoEmptyLineBetweenFields" value="true"/>
|
||||||
@ -177,79 +170,79 @@
|
|||||||
<module name="PackageName">
|
<module name="PackageName">
|
||||||
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
|
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Package name ''{0}'' must match pattern ''{1}''."/>
|
value="Package name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="TypeName">
|
<module name="TypeName">
|
||||||
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
<property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
||||||
ANNOTATION_DEF, RECORD_DEF"/>
|
ANNOTATION_DEF, RECORD_DEF"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Type name ''{0}'' must match pattern ''{1}''."/>
|
value="Type name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="MemberName">
|
<module name="MemberName">
|
||||||
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
|
<property name="format" value="^[a-z][a-z0-9][a-zA-Z0-9]*$"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Member name ''{0}'' must match pattern ''{1}''."/>
|
value="Member name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="ParameterName">
|
<module name="ParameterName">
|
||||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
|
value="Parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="LambdaParameterName">
|
<module name="LambdaParameterName">
|
||||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
|
value="Lambda parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="CatchParameterName">
|
<module name="CatchParameterName">
|
||||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
|
value="Catch parameter name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="LocalVariableName">
|
<module name="LocalVariableName">
|
||||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
|
value="Local variable name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="PatternVariableName">
|
<module name="PatternVariableName">
|
||||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Pattern variable name ''{0}'' must match pattern ''{1}''."/>
|
value="Pattern variable name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="ClassTypeParameterName">
|
<module name="ClassTypeParameterName">
|
||||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Class type name ''{0}'' must match pattern ''{1}''."/>
|
value="Class type name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="RecordComponentName">
|
<module name="RecordComponentName">
|
||||||
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
<property name="format" value="^[a-z]([a-z0-9][a-zA-Z0-9]*)?$"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Record component name ''{0}'' must match pattern ''{1}''."/>
|
value="Record component name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="RecordTypeParameterName">
|
<module name="RecordTypeParameterName">
|
||||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Record type name ''{0}'' must match pattern ''{1}''."/>
|
value="Record type name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="MethodTypeParameterName">
|
<module name="MethodTypeParameterName">
|
||||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Method type name ''{0}'' must match pattern ''{1}''."/>
|
value="Method type name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="InterfaceTypeParameterName">
|
<module name="InterfaceTypeParameterName">
|
||||||
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
<property name="format" value="(^[A-Z][0-9]?)$|([A-Z][a-zA-Z0-9]*[T]$)"/>
|
||||||
<message key="name.invalidPattern"
|
<message key="name.invalidPattern"
|
||||||
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
|
value="Interface type name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="NoFinalizer"/>
|
<module name="NoFinalizer"/>
|
||||||
<module name="GenericWhitespace">
|
<module name="GenericWhitespace">
|
||||||
<message key="ws.followed"
|
<message key="ws.followed"
|
||||||
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
|
value="GenericWhitespace ''{0}'' is followed by whitespace."/>
|
||||||
<message key="ws.preceded"
|
<message key="ws.preceded"
|
||||||
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
|
value="GenericWhitespace ''{0}'' is preceded with whitespace."/>
|
||||||
<message key="ws.illegalFollow"
|
<message key="ws.illegalFollow"
|
||||||
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
|
value="GenericWhitespace ''{0}'' should followed by whitespace."/>
|
||||||
<message key="ws.notPreceded"
|
<message key="ws.notPreceded"
|
||||||
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
|
value="GenericWhitespace ''{0}'' is not preceded with whitespace."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="Indentation">
|
<module name="Indentation">
|
||||||
<property name="basicOffset" value="2"/>
|
<property name="basicOffset" value="2"/>
|
||||||
@ -261,9 +254,9 @@
|
|||||||
</module>
|
</module>
|
||||||
<module name="AbbreviationAsWordInName">
|
<module name="AbbreviationAsWordInName">
|
||||||
<property name="ignoreFinal" value="false"/>
|
<property name="ignoreFinal" value="false"/>
|
||||||
<property name="allowedAbbreviationLength" value="1"/>
|
<property name="allowedAbbreviationLength" value="0"/>
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,
|
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF,
|
||||||
PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF, PATTERN_VARIABLE_DEF, RECORD_DEF,
|
PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF, PATTERN_VARIABLE_DEF, RECORD_DEF,
|
||||||
RECORD_COMPONENT_DEF"/>
|
RECORD_COMPONENT_DEF"/>
|
||||||
</module>
|
</module>
|
||||||
@ -278,18 +271,18 @@
|
|||||||
</module>
|
</module>
|
||||||
<module name="MethodParamPad">
|
<module name="MethodParamPad">
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,
|
value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF,
|
||||||
SUPER_CTOR_CALL, ENUM_CONSTANT_DEF, RECORD_DEF"/>
|
SUPER_CTOR_CALL, ENUM_CONSTANT_DEF, RECORD_DEF"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="NoWhitespaceBefore">
|
<module name="NoWhitespaceBefore">
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="COMMA, SEMI, POST_INC, POST_DEC, DOT,
|
value="COMMA, SEMI, POST_INC, POST_DEC, DOT,
|
||||||
LABELED_STAT, METHOD_REF"/>
|
LABELED_STAT, METHOD_REF"/>
|
||||||
<property name="allowLineBreaks" value="true"/>
|
<property name="allowLineBreaks" value="true"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="ParenPad">
|
<module name="ParenPad">
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT, ENUM_CONSTANT_DEF,
|
value="ANNOTATION, ANNOTATION_FIELD_DEF, CTOR_CALL, CTOR_DEF, DOT, ENUM_CONSTANT_DEF,
|
||||||
EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW,
|
EXPR, LITERAL_CATCH, LITERAL_DO, LITERAL_FOR, LITERAL_IF, LITERAL_NEW,
|
||||||
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,
|
LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_WHILE, METHOD_CALL,
|
||||||
METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA,
|
METHOD_DEF, QUESTION, RESOURCE_SPECIFICATION, SUPER_CTOR_CALL, LAMBDA,
|
||||||
@ -298,14 +291,14 @@
|
|||||||
<module name="OperatorWrap">
|
<module name="OperatorWrap">
|
||||||
<property name="option" value="NL"/>
|
<property name="option" value="NL"/>
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR,
|
value="BAND, BOR, BSR, BXOR, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR,
|
||||||
LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF,
|
LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR, METHOD_REF,
|
||||||
TYPE_EXTENSION_AND "/>
|
TYPE_EXTENSION_AND "/>
|
||||||
</module>
|
</module>
|
||||||
<module name="AnnotationLocation">
|
<module name="AnnotationLocation">
|
||||||
<property name="id" value="AnnotationLocationMostCases"/>
|
<property name="id" value="AnnotationLocationMostCases"/>
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF,
|
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF,
|
||||||
RECORD_DEF, COMPACT_CTOR_DEF"/>
|
RECORD_DEF, COMPACT_CTOR_DEF"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="AnnotationLocation">
|
<module name="AnnotationLocation">
|
||||||
@ -318,15 +311,14 @@
|
|||||||
<module name="JavadocTagContinuationIndentation"/>
|
<module name="JavadocTagContinuationIndentation"/>
|
||||||
<module name="SummaryJavadoc">
|
<module name="SummaryJavadoc">
|
||||||
<property name="forbiddenSummaryFragments"
|
<property name="forbiddenSummaryFragments"
|
||||||
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
|
value="^@return the *|^This method returns |^A [{]@code [a-zA-Z0-9]+[}]( is a )"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="JavadocParagraph"/>
|
<module name="JavadocParagraph"/>
|
||||||
<!-- <module name="RequireEmptyLineBeforeBlockTagGroup"/>
|
<module name="RequireEmptyLineBeforeBlockTagGroup"/>
|
||||||
-->
|
|
||||||
<module name="AtclauseOrder">
|
<module name="AtclauseOrder">
|
||||||
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
|
<property name="tagOrder" value="@param, @return, @throws, @deprecated"/>
|
||||||
<property name="target"
|
<property name="target"
|
||||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
|
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
|
||||||
</module>
|
</module>
|
||||||
<module name="JavadocMethod">
|
<module name="JavadocMethod">
|
||||||
<property name="accessModifiers" value="public"/>
|
<property name="accessModifiers" value="public"/>
|
||||||
@ -335,7 +327,7 @@
|
|||||||
<property name="allowedAnnotations" value="Override, Test"/>
|
<property name="allowedAnnotations" value="Override, Test"/>
|
||||||
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, COMPACT_CTOR_DEF"/>
|
<property name="tokens" value="METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, COMPACT_CTOR_DEF"/>
|
||||||
</module>
|
</module>
|
||||||
<!-- <module name="MissingJavadocMethod">
|
<module name="MissingJavadocMethod">
|
||||||
<property name="scope" value="public"/>
|
<property name="scope" value="public"/>
|
||||||
<property name="minLineCount" value="2"/>
|
<property name="minLineCount" value="2"/>
|
||||||
<property name="allowedAnnotations" value="Override, Test"/>
|
<property name="allowedAnnotations" value="Override, Test"/>
|
||||||
@ -345,15 +337,14 @@
|
|||||||
<module name="MissingJavadocType">
|
<module name="MissingJavadocType">
|
||||||
<property name="scope" value="protected"/>
|
<property name="scope" value="protected"/>
|
||||||
<property name="tokens"
|
<property name="tokens"
|
||||||
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF,
|
||||||
RECORD_DEF, ANNOTATION_DEF"/>
|
RECORD_DEF, ANNOTATION_DEF"/>
|
||||||
<property name="excludeScope" value="nothing"/>
|
<property name="excludeScope" value="nothing"/>
|
||||||
</module>
|
</module>
|
||||||
-->
|
|
||||||
<module name="MethodName">
|
<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"
|
<message key="name.invalidPattern"
|
||||||
value="Method name ''{0}'' must match pattern ''{1}''."/>
|
value="Method name ''{0}'' must match pattern ''{1}''."/>
|
||||||
</module>
|
</module>
|
||||||
<module name="SingleLineJavadoc"/>
|
<module name="SingleLineJavadoc"/>
|
||||||
<module name="EmptyCatchBlock">
|
<module name="EmptyCatchBlock">
|
||||||
@ -365,8 +356,21 @@
|
|||||||
<!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter -->
|
<!-- https://checkstyle.org/config_filters.html#SuppressionXpathFilter -->
|
||||||
<module name="SuppressionXpathFilter">
|
<module name="SuppressionXpathFilter">
|
||||||
<property name="file" value="${org.checkstyle.google.suppressionxpathfilter.config}"
|
<property name="file" value="${org.checkstyle.google.suppressionxpathfilter.config}"
|
||||||
default="checkstyle-xpath-suppressions.xml" />
|
default="checkstyle-xpath-suppressions.xml" />
|
||||||
<property name="optional" value="true"/>
|
<property name="optional" value="true"/>
|
||||||
</module>
|
</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>
|
||||||
</module>
|
</module>
|
||||||
|
26
gradle.properties
Normale Datei
26
gradle.properties
Normale Datei
@ -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
Normale Datei
18
native/build.gradle.kts
Normale Datei
@ -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;
|
import com.velocitypowered.natives.util.BufferPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic interface for any Velocity native.
|
||||||
|
*/
|
||||||
public interface Native {
|
public interface Native {
|
||||||
BufferPreference preferredBufferType();
|
BufferPreference preferredBufferType();
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
package com.velocitypowered.natives;
|
package com.velocitypowered.natives;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when we cannot set up a variant of a native library.
|
||||||
|
*/
|
||||||
public class NativeSetupException extends RuntimeException {
|
public class NativeSetupException extends RuntimeException {
|
||||||
|
|
||||||
public NativeSetupException() {
|
public NativeSetupException() {
|
||||||
|
@ -28,6 +28,7 @@ class CompressorUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensures that the buffer does not go over {@code max}.
|
* Ensures that the buffer does not go over {@code max}.
|
||||||
|
*
|
||||||
* @param buf the buffer for check
|
* @param buf the buffer for check
|
||||||
* @param max the maximum size for the buffer
|
* @param max the maximum size for the buffer
|
||||||
* @throws DataFormatException if the buffer becomes too bug
|
* @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.Deflater;
|
||||||
import java.util.zip.Inflater;
|
import java.util.zip.Inflater;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements deflate compression by wrapping {@link Deflater} and {@link Inflater}.
|
||||||
|
*/
|
||||||
public class JavaVelocityCompressor implements VelocityCompressor {
|
public class JavaVelocityCompressor implements VelocityCompressor {
|
||||||
|
|
||||||
public static final VelocityCompressorFactory FACTORY = JavaVelocityCompressor::new;
|
public static final VelocityCompressorFactory FACTORY = JavaVelocityCompressor::new;
|
||||||
|
@ -22,6 +22,9 @@ import com.velocitypowered.natives.util.BufferPreference;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import java.util.zip.DataFormatException;
|
import java.util.zip.DataFormatException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements deflate compression using the {@code libdeflate} native C library.
|
||||||
|
*/
|
||||||
public class LibdeflateVelocityCompressor implements VelocityCompressor {
|
public class LibdeflateVelocityCompressor implements VelocityCompressor {
|
||||||
|
|
||||||
public static final VelocityCompressorFactory FACTORY = LibdeflateVelocityCompressor::new;
|
public static final VelocityCompressorFactory FACTORY = LibdeflateVelocityCompressor::new;
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
package com.velocitypowered.natives.compression;
|
package com.velocitypowered.natives.compression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for {@link VelocityCompressor}.
|
||||||
|
*/
|
||||||
public interface VelocityCompressorFactory {
|
public interface VelocityCompressorFactory {
|
||||||
|
|
||||||
VelocityCompressor create(int level);
|
VelocityCompressor create(int level);
|
||||||
|
@ -26,6 +26,9 @@ import javax.crypto.SecretKey;
|
|||||||
import javax.crypto.ShortBufferException;
|
import javax.crypto.ShortBufferException;
|
||||||
import javax.crypto.spec.IvParameterSpec;
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements AES-CFB8 encryption/decryption using {@link Cipher}.
|
||||||
|
*/
|
||||||
public class JavaVelocityCipher implements VelocityCipher {
|
public class JavaVelocityCipher implements VelocityCipher {
|
||||||
|
|
||||||
public static final VelocityCipherFactory FACTORY = new VelocityCipherFactory() {
|
public static final VelocityCipherFactory FACTORY = new VelocityCipherFactory() {
|
||||||
|
@ -23,6 +23,9 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements AES-CFB8 encryption/decryption using a native library.
|
||||||
|
*/
|
||||||
public class NativeVelocityCipher implements VelocityCipher {
|
public class NativeVelocityCipher implements VelocityCipher {
|
||||||
|
|
||||||
public static final VelocityCipherFactory FACTORY = new VelocityCipherFactory() {
|
public static final VelocityCipherFactory FACTORY = new VelocityCipherFactory() {
|
||||||
|
@ -21,6 +21,15 @@ import com.velocitypowered.natives.Disposable;
|
|||||||
import com.velocitypowered.natives.Native;
|
import com.velocitypowered.natives.Native;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements an AES-CFB8 cipher that either encrypts or decrypts connection data.
|
||||||
|
*/
|
||||||
public interface VelocityCipher extends Disposable, Native {
|
public interface VelocityCipher extends Disposable, Native {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypts the given {@link ByteBuf} in-place.
|
||||||
|
*
|
||||||
|
* @param source the buffer to encrypt
|
||||||
|
*/
|
||||||
void process(ByteBuf source);
|
void process(ByteBuf source);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,9 @@ package com.velocitypowered.natives.encryption;
|
|||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory interface for {@link VelocityCipher}.
|
||||||
|
*/
|
||||||
public interface VelocityCipherFactory {
|
public interface VelocityCipherFactory {
|
||||||
|
|
||||||
VelocityCipher forEncryption(SecretKey key) throws GeneralSecurityException;
|
VelocityCipher forEncryption(SecretKey key) throws GeneralSecurityException;
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
package com.velocitypowered.natives.util;
|
package com.velocitypowered.natives.util;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Emumerates Netty buffer preferences and requirements for use with Netty.
|
||||||
|
*/
|
||||||
public enum BufferPreference {
|
public enum BufferPreference {
|
||||||
/**
|
/**
|
||||||
* A heap buffer is required.
|
* A heap buffer is required.
|
||||||
|
@ -21,6 +21,9 @@ import com.velocitypowered.natives.Native;
|
|||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufAllocator;
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional utilities for {@link ByteBuf}.
|
||||||
|
*/
|
||||||
public class MoreByteBufUtils {
|
public class MoreByteBufUtils {
|
||||||
private MoreByteBufUtils() {
|
private MoreByteBufUtils() {
|
||||||
throw new AssertionError();
|
throw new AssertionError();
|
||||||
|
@ -22,6 +22,11 @@ import java.util.function.BooleanSupplier;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
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> {
|
public final class NativeCodeLoader<T> implements Supplier<T> {
|
||||||
|
|
||||||
private final Variant<T> selected;
|
private final Variant<T> selected;
|
||||||
|
@ -21,6 +21,9 @@ import io.netty.buffer.ByteBuf;
|
|||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import java.util.function.BooleanSupplier;
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statically-computed constraints for native code.
|
||||||
|
*/
|
||||||
public class NativeConstraints {
|
public class NativeConstraints {
|
||||||
private static final boolean NATIVES_ENABLED = !Boolean.getBoolean("velocity.natives-disabled");
|
private static final boolean NATIVES_ENABLED = !Boolean.getBoolean("velocity.natives-disabled");
|
||||||
private static final boolean IS_AMD64;
|
private static final boolean IS_AMD64;
|
||||||
|
@ -31,6 +31,9 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enumerates all supported natives for Velocity.
|
||||||
|
*/
|
||||||
public class Natives {
|
public class Natives {
|
||||||
|
|
||||||
private 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
Normale Datei
159
proxy/build.gradle.kts
Normale Datei
@ -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.config.MetricsConfig;
|
||||||
import org.bstats.json.JsonObjectBuilder;
|
import org.bstats.json.JsonObjectBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes bStats.
|
||||||
|
*/
|
||||||
public class Metrics {
|
public class Metrics {
|
||||||
|
|
||||||
private MetricsBase metricsBase;
|
private MetricsBase metricsBase;
|
||||||
|
@ -26,7 +26,11 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds parsed command line options.
|
||||||
|
*/
|
||||||
public final class ProxyOptions {
|
public final class ProxyOptions {
|
||||||
|
|
||||||
private static final Logger logger = LogManager.getLogger(ProxyOptions.class);
|
private static final Logger logger = LogManager.getLogger(ProxyOptions.class);
|
||||||
private final boolean help;
|
private final boolean help;
|
||||||
private final @Nullable Integer port;
|
private final @Nullable Integer port;
|
||||||
@ -37,7 +41,7 @@ public final class ProxyOptions {
|
|||||||
final OptionSpec<Void> help = parser.acceptsAll(Arrays.asList("h", "help"), "Print help")
|
final OptionSpec<Void> help = parser.acceptsAll(Arrays.asList("h", "help"), "Print help")
|
||||||
.forHelp();
|
.forHelp();
|
||||||
final OptionSpec<Integer> port = parser.acceptsAll(Arrays.asList("p", "port"),
|
final OptionSpec<Integer> port = parser.acceptsAll(Arrays.asList("p", "port"),
|
||||||
"Specify the bind port to be used. The configuration bind port will be ignored.")
|
"Specify the bind port to be used. The configuration bind port will be ignored.")
|
||||||
.withRequiredArg().ofType(Integer.class);
|
.withRequiredArg().ofType(Integer.class);
|
||||||
final OptionSet set = parser.parse(args);
|
final OptionSet set = parser.parse(args);
|
||||||
|
|
||||||
|
@ -23,6 +23,10 @@ import java.text.DecimalFormat;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main class. Responsible for parsing command line arguments and then launching the
|
||||||
|
* proxy.
|
||||||
|
*/
|
||||||
public class Velocity {
|
public class Velocity {
|
||||||
|
|
||||||
private static final Logger logger;
|
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.
|
* Main method that the JVM will call when {@code java -jar velocity.jar} is executed.
|
||||||
|
*
|
||||||
* @param args the arguments to the proxy
|
* @param args the arguments to the proxy
|
||||||
*/
|
*/
|
||||||
public static void main(String... args) {
|
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.server.ServerMap;
|
||||||
import com.velocitypowered.proxy.util.AddressUtil;
|
import com.velocitypowered.proxy.util.AddressUtil;
|
||||||
import com.velocitypowered.proxy.util.ClosestLocaleMatcher;
|
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.VelocityChannelRegistrar;
|
||||||
import com.velocitypowered.proxy.util.bossbar.AdventureBossBarManager;
|
import com.velocitypowered.proxy.util.bossbar.AdventureBossBarManager;
|
||||||
import com.velocitypowered.proxy.util.ratelimit.Ratelimiter;
|
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.NonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of {@link ProxyServer}.
|
||||||
|
*/
|
||||||
public class VelocityServer implements ProxyServer, ForwardingAudience {
|
public class VelocityServer implements ProxyServer, ForwardingAudience {
|
||||||
|
|
||||||
private static final Logger logger = LogManager.getLogger(VelocityServer.class);
|
private static final Logger logger = LogManager.getLogger(VelocityServer.class);
|
||||||
@ -250,7 +253,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
.create(Key.key("velocity", "translations"));
|
.create(Key.key("velocity", "translations"));
|
||||||
translationRegistry.defaultLocale(Locale.US);
|
translationRegistry.defaultLocale(Locale.US);
|
||||||
try {
|
try {
|
||||||
FileSystemUtils.visitResources(VelocityServer.class, path -> {
|
ResourceUtils.visitResources(VelocityServer.class, path -> {
|
||||||
logger.info("Loading localizations...");
|
logger.info("Loading localizations...");
|
||||||
|
|
||||||
final Path langPath = Path.of("lang");
|
final Path langPath = Path.of("lang");
|
||||||
@ -275,7 +278,6 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Files.walk(langPath).forEach(file -> {
|
Files.walk(langPath).forEach(file -> {
|
||||||
if (!Files.isRegularFile(file)) {
|
if (!Files.isRegularFile(file)) {
|
||||||
return;
|
return;
|
||||||
@ -468,10 +470,10 @@ 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 explicitExit whether the user explicitly shut down the proxy
|
||||||
* @param reason message to kick online players with
|
* @param reason message to kick online players with
|
||||||
*/
|
*/
|
||||||
public void shutdown(boolean explicitExit, Component reason) {
|
public void shutdown(boolean explicitExit, Component reason) {
|
||||||
if (eventManager == null || pluginManager == null || cm == null || scheduler == null) {
|
if (eventManager == null || pluginManager == null || cm == null || scheduler == null) {
|
||||||
@ -502,8 +504,8 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
// makes sure that all the disconnect events are being fired
|
// makes sure that all the disconnect events are being fired
|
||||||
|
|
||||||
CompletableFuture<Void> playersTeardownFuture = CompletableFuture.allOf(players.stream()
|
CompletableFuture<Void> playersTeardownFuture = CompletableFuture.allOf(players.stream()
|
||||||
.map(ConnectedPlayer::getTeardownFuture)
|
.map(ConnectedPlayer::getTeardownFuture)
|
||||||
.toArray((IntFunction<CompletableFuture<Void>[]>) CompletableFuture[]::new));
|
.toArray((IntFunction<CompletableFuture<Void>[]>) CompletableFuture[]::new));
|
||||||
|
|
||||||
playersTeardownFuture.get(10, TimeUnit.SECONDS);
|
playersTeardownFuture.get(10, TimeUnit.SECONDS);
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
@ -580,6 +582,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the {@code connection} can be registered with the proxy.
|
* Checks if the {@code connection} can be registered with the proxy.
|
||||||
|
*
|
||||||
* @param connection the connection to check
|
* @param connection the connection to check
|
||||||
* @return {@code true} if we can register the connection, {@code false} if not
|
* @return {@code true} if we can register the connection, {@code false} if not
|
||||||
*/
|
*/
|
||||||
@ -591,9 +594,10 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
return !(connectionsByName.containsKey(lowerName)
|
return !(connectionsByName.containsKey(lowerName)
|
||||||
|| connectionsByUuid.containsKey(connection.getUniqueId()));
|
|| connectionsByUuid.containsKey(connection.getUniqueId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to register the {@code connection} with the proxy.
|
* Attempts to register the {@code connection} with the proxy.
|
||||||
|
*
|
||||||
* @param connection the connection to register
|
* @param connection the connection to register
|
||||||
* @return {@code true} if we registered the connection, {@code false} if not
|
* @return {@code true} if we registered the connection, {@code false} if not
|
||||||
*/
|
*/
|
||||||
@ -650,7 +654,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
|
|
||||||
return getAllPlayers().stream().filter(p -> p.getUsername()
|
return getAllPlayers().stream().filter(p -> p.getUsername()
|
||||||
.regionMatches(true, 0, partialName, 0, partialName.length()))
|
.regionMatches(true, 0, partialName, 0, partialName.length()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -659,7 +663,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
|
|
||||||
return getAllServers().stream().filter(s -> s.getServerInfo().getName()
|
return getAllServers().stream().filter(s -> s.getServerInfo().getName()
|
||||||
.regionMatches(true, 0, partialName, 0, partialName.length()))
|
.regionMatches(true, 0, partialName, 0, partialName.length()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -32,9 +32,8 @@ import org.checkerframework.checker.lock.qual.GuardedBy;
|
|||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the nodes of a {@link RootCommandNode} to a possibly non-empty
|
* Copies the nodes of a {@link RootCommandNode} to a possibly non-empty destination
|
||||||
* destination {@link RootCommandNode}, respecting the requirements satisfied
|
* {@link RootCommandNode}, respecting the requirements satisfied by a given command source.
|
||||||
* by a given command source.
|
|
||||||
*
|
*
|
||||||
* @param <S> the type of the source to inject the nodes for
|
* @param <S> the type of the source to inject the nodes for
|
||||||
*/
|
*/
|
||||||
@ -55,13 +54,13 @@ public final class CommandGraphInjector<S> {
|
|||||||
// the root node we are copying nodes from to the destination node.
|
// 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,
|
* Adds the node from the root node of this injector to the given root node, respecting the
|
||||||
* respecting the requirements satisfied by the given source.
|
* requirements satisfied by the given source.
|
||||||
*
|
*
|
||||||
* <p>Prior to adding a literal with the same name as one previously contained
|
* <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.
|
* in the destination node, the old node is removed from the destination node.
|
||||||
*
|
*
|
||||||
* @param dest the root node to add the permissible nodes to
|
* @param dest the root node to add the permissible nodes to
|
||||||
* @param source the command source to inject the nodes for
|
* @param source the command source to inject the nodes for
|
||||||
*/
|
*/
|
||||||
public void inject(final RootCommandNode<S> dest, final S source) {
|
public void inject(final RootCommandNode<S> dest, final S source) {
|
||||||
@ -69,7 +68,7 @@ public final class CommandGraphInjector<S> {
|
|||||||
try {
|
try {
|
||||||
final RootCommandNode<S> origin = this.dispatcher.getRoot();
|
final RootCommandNode<S> origin = this.dispatcher.getRoot();
|
||||||
final CommandContextBuilder<S> rootContext =
|
final CommandContextBuilder<S> rootContext =
|
||||||
new CommandContextBuilder<>(this.dispatcher, source, origin, 0);
|
new CommandContextBuilder<>(this.dispatcher, source, origin, 0);
|
||||||
|
|
||||||
// Filter alias nodes
|
// Filter alias nodes
|
||||||
for (final CommandNode<S> node : origin.getChildren()) {
|
for (final CommandNode<S> node : origin.getChildren()) {
|
||||||
@ -78,7 +77,7 @@ public final class CommandGraphInjector<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final CommandContextBuilder<S> context = rootContext.copy()
|
final CommandContextBuilder<S> context = rootContext.copy()
|
||||||
.withNode(node, ALIAS_RANGE);
|
.withNode(node, ALIAS_RANGE);
|
||||||
if (!node.canUse(context, ALIAS_READER)) {
|
if (!node.canUse(context, ALIAS_READER)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -86,7 +85,7 @@ public final class CommandGraphInjector<S> {
|
|||||||
final LiteralCommandNode<S> asLiteral = (LiteralCommandNode<S>) node;
|
final LiteralCommandNode<S> asLiteral = (LiteralCommandNode<S>) node;
|
||||||
final LiteralCommandNode<S> copy = asLiteral.createBuilder().build();
|
final LiteralCommandNode<S> copy = asLiteral.createBuilder().build();
|
||||||
final VelocityArgumentCommandNode<S, ?> argsNode =
|
final VelocityArgumentCommandNode<S, ?> argsNode =
|
||||||
VelocityCommands.getArgumentsNode(asLiteral);
|
VelocityCommands.getArgumentsNode(asLiteral);
|
||||||
if (argsNode == null) {
|
if (argsNode == null) {
|
||||||
// This literal is associated to a BrigadierCommand, filter normally.
|
// This literal is associated to a BrigadierCommand, filter normally.
|
||||||
this.copyChildren(node, copy, source);
|
this.copyChildren(node, copy, source);
|
||||||
@ -126,7 +125,7 @@ public final class CommandGraphInjector<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void copyChildren(final CommandNode<S> parent, final CommandNode<S> dest,
|
private void copyChildren(final CommandNode<S> parent, final CommandNode<S> dest,
|
||||||
final S source) {
|
final S source) {
|
||||||
for (final CommandNode<S> child : parent.getChildren()) {
|
for (final CommandNode<S> child : parent.getChildren()) {
|
||||||
final CommandNode<S> filtered = this.filterNode(child, source);
|
final CommandNode<S> filtered = this.filterNode(child, source);
|
||||||
if (filtered != null) {
|
if (filtered != null) {
|
||||||
|
@ -50,8 +50,8 @@ import org.checkerframework.checker.lock.qual.GuardedBy;
|
|||||||
* Provides suggestions for a given command input.
|
* Provides suggestions for a given command input.
|
||||||
*
|
*
|
||||||
* <p>Similar to {@link CommandDispatcher#getCompletionSuggestions(ParseResults)}, except it
|
* <p>Similar to {@link CommandDispatcher#getCompletionSuggestions(ParseResults)}, except it
|
||||||
* avoids fully parsing the given input and performs exactly one requirement predicate check
|
* avoids fully parsing the given input and performs exactly one requirement predicate check per
|
||||||
* per considered node.
|
* considered node.
|
||||||
*
|
*
|
||||||
* @param <S> the type of the command source
|
* @param <S> the type of the command source
|
||||||
*/
|
*/
|
||||||
@ -74,31 +74,31 @@ final class SuggestionsProvider<S> {
|
|||||||
/**
|
/**
|
||||||
* Provides suggestions for the given input and source.
|
* Provides suggestions for the given input and source.
|
||||||
*
|
*
|
||||||
* @param input the partial input
|
* @param input the partial input
|
||||||
* @param source the command source invoking the command
|
* @param source the command source invoking the command
|
||||||
* @return a future that completes with the suggestions
|
* @return a future that completes with the suggestions
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<Suggestions> provideSuggestions(final String input, final S source) {
|
public CompletableFuture<Suggestions> provideSuggestions(final String input, final S source) {
|
||||||
final CommandContextBuilder<S> context = new CommandContextBuilder<>(
|
final CommandContextBuilder<S> context = new CommandContextBuilder<>(
|
||||||
this.dispatcher, source, this.dispatcher.getRoot(), 0);
|
this.dispatcher, source, this.dispatcher.getRoot(), 0);
|
||||||
return this.provideSuggestions(new StringReader(input), context);
|
return this.provideSuggestions(new StringReader(input), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides suggestions for the given input and context.
|
* Provides suggestions for the given input and context.
|
||||||
*
|
*
|
||||||
* @param reader the input reader
|
* @param reader the input reader
|
||||||
* @param context an empty context
|
* @param context an empty context
|
||||||
* @return a future that completes with the suggestions
|
* @return a future that completes with the suggestions
|
||||||
*/
|
*/
|
||||||
private CompletableFuture<Suggestions> provideSuggestions(
|
private CompletableFuture<Suggestions> provideSuggestions(
|
||||||
final StringReader reader, final CommandContextBuilder<S> context) {
|
final StringReader reader, final CommandContextBuilder<S> context) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
final StringRange aliasRange = this.consumeAlias(reader);
|
final StringRange aliasRange = this.consumeAlias(reader);
|
||||||
final String alias = aliasRange.get(reader).toLowerCase(Locale.ENGLISH);
|
final String alias = aliasRange.get(reader).toLowerCase(Locale.ENGLISH);
|
||||||
final LiteralCommandNode<S> literal =
|
final LiteralCommandNode<S> literal =
|
||||||
(LiteralCommandNode<S>) context.getRootNode().getChild(alias);
|
(LiteralCommandNode<S>) context.getRootNode().getChild(alias);
|
||||||
|
|
||||||
final boolean hasArguments = reader.canRead();
|
final boolean hasArguments = reader.canRead();
|
||||||
if (hasArguments) {
|
if (hasArguments) {
|
||||||
@ -119,9 +119,9 @@ final class SuggestionsProvider<S> {
|
|||||||
|
|
||||||
private StringRange consumeAlias(final StringReader reader) {
|
private StringRange consumeAlias(final StringReader reader) {
|
||||||
final int firstSep = reader.getString().indexOf(
|
final int firstSep = reader.getString().indexOf(
|
||||||
CommandDispatcher.ARGUMENT_SEPARATOR_CHAR, reader.getCursor());
|
CommandDispatcher.ARGUMENT_SEPARATOR_CHAR, reader.getCursor());
|
||||||
final StringRange range = StringRange.between(
|
final StringRange range = StringRange.between(
|
||||||
reader.getCursor(), firstSep == -1 ? reader.getTotalLength() : firstSep);
|
reader.getCursor(), firstSep == -1 ? reader.getTotalLength() : firstSep);
|
||||||
reader.setCursor(range.getEnd());
|
reader.setCursor(range.getEnd());
|
||||||
return range;
|
return range;
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ final class SuggestionsProvider<S> {
|
|||||||
* Returns whether a literal node with the given lowercase name should be considered for
|
* Returns whether a literal node with the given lowercase name should be considered for
|
||||||
* suggestions given the specified input.
|
* suggestions given the specified input.
|
||||||
*
|
*
|
||||||
* @param name the lowercase literal name
|
* @param name the lowercase literal name
|
||||||
* @param input the partial input
|
* @param input the partial input
|
||||||
* @return true if the literal should be considered; false otherwise
|
* @return true if the literal should be considered; false otherwise
|
||||||
*/
|
*/
|
||||||
@ -141,12 +141,12 @@ final class SuggestionsProvider<S> {
|
|||||||
/**
|
/**
|
||||||
* Returns alias suggestions for the given input.
|
* Returns alias suggestions for the given input.
|
||||||
*
|
*
|
||||||
* @param reader the input reader
|
* @param reader the input reader
|
||||||
* @param contextSoFar an empty context
|
* @param contextSoFar an empty context
|
||||||
* @return a future that completes with the suggestions
|
* @return a future that completes with the suggestions
|
||||||
*/
|
*/
|
||||||
private CompletableFuture<Suggestions> provideAliasSuggestions(
|
private CompletableFuture<Suggestions> provideAliasSuggestions(
|
||||||
final StringReader reader, final CommandContextBuilder<S> contextSoFar) {
|
final StringReader reader, final CommandContextBuilder<S> contextSoFar) {
|
||||||
final S source = contextSoFar.getSource();
|
final S source = contextSoFar.getSource();
|
||||||
// Lowercase the alias here so all comparisons can be case-sensitive (cheaper)
|
// Lowercase the alias here so all comparisons can be case-sensitive (cheaper)
|
||||||
// TODO Is this actually faster? It may incur an allocation
|
// TODO Is this actually faster? It may incur an allocation
|
||||||
@ -166,7 +166,7 @@ final class SuggestionsProvider<S> {
|
|||||||
|
|
||||||
if (shouldConsider(alias, input) && node.canUse(source)) {
|
if (shouldConsider(alias, input) && node.canUse(source)) {
|
||||||
final CommandContextBuilder<S> context = contextSoFar.copy()
|
final CommandContextBuilder<S> context = contextSoFar.copy()
|
||||||
.withNode(node, ALIAS_SUGGESTION_RANGE);
|
.withNode(node, ALIAS_SUGGESTION_RANGE);
|
||||||
if (node.canUse(context, reader)) {
|
if (node.canUse(context, reader)) {
|
||||||
// LiteralCommandNode#listSuggestions is case insensitive
|
// LiteralCommandNode#listSuggestions is case insensitive
|
||||||
final SuggestionsBuilder builder = new SuggestionsBuilder(input, 0);
|
final SuggestionsBuilder builder = new SuggestionsBuilder(input, 0);
|
||||||
@ -179,19 +179,19 @@ final class SuggestionsProvider<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Merges the suggestions provided by the {@link Command} associated to the given
|
* Merges the suggestions provided by the {@link Command} associated to the given alias node and
|
||||||
* alias node and the hints given during registration for the given input.
|
* 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.
|
* <p>The context is not mutated by this method. The reader's cursor may be modified.
|
||||||
*
|
*
|
||||||
* @param alias the alias node
|
* @param alias the alias node
|
||||||
* @param reader the input reader
|
* @param reader the input reader
|
||||||
* @param contextSoFar the context, containing {@code alias}
|
* @param contextSoFar the context, containing {@code alias}
|
||||||
* @return a future that completes with the suggestions
|
* @return a future that completes with the suggestions
|
||||||
*/
|
*/
|
||||||
private CompletableFuture<Suggestions> provideArgumentsSuggestions(
|
private CompletableFuture<Suggestions> provideArgumentsSuggestions(
|
||||||
final LiteralCommandNode<S> alias, final StringReader reader,
|
final LiteralCommandNode<S> alias, final StringReader reader,
|
||||||
final CommandContextBuilder<S> contextSoFar) {
|
final CommandContextBuilder<S> contextSoFar) {
|
||||||
final S source = contextSoFar.getSource();
|
final S source = contextSoFar.getSource();
|
||||||
final String fullInput = reader.getString();
|
final String fullInput = reader.getString();
|
||||||
final VelocityArgumentCommandNode<S, ?> argsNode = VelocityCommands.getArgumentsNode(alias);
|
final VelocityArgumentCommandNode<S, ?> argsNode = VelocityCommands.getArgumentsNode(alias);
|
||||||
@ -227,7 +227,7 @@ final class SuggestionsProvider<S> {
|
|||||||
// Ask the command for suggestions via the arguments node
|
// Ask the command for suggestions via the arguments node
|
||||||
reader.setCursor(start);
|
reader.setCursor(start);
|
||||||
final CompletableFuture<Suggestions> cmdSuggestions =
|
final CompletableFuture<Suggestions> cmdSuggestions =
|
||||||
this.getArgumentsNodeSuggestions(argsNode, reader, context);
|
this.getArgumentsNodeSuggestions(argsNode, reader, context);
|
||||||
final boolean hasHints = alias.getChildren().size() > 1;
|
final boolean hasHints = alias.getChildren().size() > 1;
|
||||||
if (!hasHints) {
|
if (!hasHints) {
|
||||||
return this.merge(fullInput, cmdSuggestions);
|
return this.merge(fullInput, cmdSuggestions);
|
||||||
@ -236,24 +236,24 @@ final class SuggestionsProvider<S> {
|
|||||||
// Parse the hint nodes to get remaining suggestions
|
// Parse the hint nodes to get remaining suggestions
|
||||||
reader.setCursor(start);
|
reader.setCursor(start);
|
||||||
final CompletableFuture<Suggestions> hintSuggestions =
|
final CompletableFuture<Suggestions> hintSuggestions =
|
||||||
this.getHintSuggestions(alias, reader, contextSoFar);
|
this.getHintSuggestions(alias, reader, contextSoFar);
|
||||||
return this.merge(fullInput, cmdSuggestions, hintSuggestions);
|
return this.merge(fullInput, cmdSuggestions, hintSuggestions);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the suggestions provided by the {@link Command} associated to
|
* Returns the suggestions provided by the {@link Command} associated to the specified arguments
|
||||||
* the specified arguments node for the given input.
|
* node for the given input.
|
||||||
*
|
*
|
||||||
* <p>The reader and context are not mutated by this method.
|
* <p>The reader and context are not mutated by this method.
|
||||||
*
|
*
|
||||||
* @param node the arguments node of the command
|
* @param node the arguments node of the command
|
||||||
* @param reader the input reader
|
* @param reader the input reader
|
||||||
* @param context the context, containing an alias node and {@code node}
|
* @param context the context, containing an alias node and {@code node}
|
||||||
* @return a future that completes with the suggestions
|
* @return a future that completes with the suggestions
|
||||||
*/
|
*/
|
||||||
private CompletableFuture<Suggestions> getArgumentsNodeSuggestions(
|
private CompletableFuture<Suggestions> getArgumentsNodeSuggestions(
|
||||||
final VelocityArgumentCommandNode<S, ?> node, final StringReader reader,
|
final VelocityArgumentCommandNode<S, ?> node, final StringReader reader,
|
||||||
final CommandContextBuilder<S> context) {
|
final CommandContextBuilder<S> context) {
|
||||||
final int start = reader.getCursor();
|
final int start = reader.getCursor();
|
||||||
final String fullInput = reader.getString();
|
final String fullInput = reader.getString();
|
||||||
final CommandContext<S> built = context.build(fullInput);
|
final CommandContext<S> built = context.build(fullInput);
|
||||||
@ -271,14 +271,14 @@ final class SuggestionsProvider<S> {
|
|||||||
*
|
*
|
||||||
* <p>The reader and context are not mutated by this method.
|
* <p>The reader and context are not mutated by this method.
|
||||||
*
|
*
|
||||||
* @param alias the alias node
|
* @param alias the alias node
|
||||||
* @param reader the input reader
|
* @param reader the input reader
|
||||||
* @param context the context, containing {@code alias}
|
* @param context the context, containing {@code alias}
|
||||||
* @return a future that completes with the suggestions
|
* @return a future that completes with the suggestions
|
||||||
*/
|
*/
|
||||||
private CompletableFuture<Suggestions> getHintSuggestions(
|
private CompletableFuture<Suggestions> getHintSuggestions(
|
||||||
final LiteralCommandNode<S> alias, final StringReader reader,
|
final LiteralCommandNode<S> alias, final StringReader reader,
|
||||||
final CommandContextBuilder<S> context) {
|
final CommandContextBuilder<S> context) {
|
||||||
final ParseResults<S> parse = this.parseHints(alias, reader, context);
|
final ParseResults<S> parse = this.parseHints(alias, reader, context);
|
||||||
try {
|
try {
|
||||||
return this.dispatcher.getCompletionSuggestions(parse);
|
return this.dispatcher.getCompletionSuggestions(parse);
|
||||||
@ -290,20 +290,20 @@ final class SuggestionsProvider<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the hint nodes under the given node, which is either an alias node of
|
* Parses the hint nodes under the given node, which is either an alias node of a {@link Command}
|
||||||
* a {@link Command} or another hint node.
|
* or another hint node.
|
||||||
*
|
*
|
||||||
* <p>The reader and context are not mutated by this method.
|
* <p>The reader and context are not mutated by this method.
|
||||||
*
|
*
|
||||||
* @param node the node to parse
|
* @param node the node to parse
|
||||||
* @param originalReader the input reader
|
* @param originalReader the input reader
|
||||||
* @param contextSoFar the context, containing the alias node of the command
|
* @param contextSoFar the context, containing the alias node of the command
|
||||||
* @return the parse results containing the parsed hint nodes
|
* @return the parse results containing the parsed hint nodes
|
||||||
* @see VelocityCommandMeta#copyHints(CommandMeta) for the conditions under which the returned
|
* @see VelocityCommandMeta#copyHints(CommandMeta) for the conditions under which the returned
|
||||||
* hints can be suggested to a {@link CommandSource}.
|
* hints can be suggested to a {@link CommandSource}.
|
||||||
*/
|
*/
|
||||||
private ParseResults<S> parseHints(final CommandNode<S> node, final StringReader originalReader,
|
private ParseResults<S> parseHints(final CommandNode<S> node, final StringReader originalReader,
|
||||||
final CommandContextBuilder<S> contextSoFar) {
|
final CommandContextBuilder<S> contextSoFar) {
|
||||||
// This is a stripped-down version of CommandDispatcher#parseNodes that doesn't
|
// This is a stripped-down version of CommandDispatcher#parseNodes that doesn't
|
||||||
// check the requirements are satisfied and ignores redirects, neither of which
|
// check the requirements are satisfied and ignores redirects, neither of which
|
||||||
// are used by hint nodes. Parsing errors are ignored.
|
// are used by hint nodes. Parsing errors are ignored.
|
||||||
@ -350,17 +350,16 @@ final class SuggestionsProvider<S> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a future that is completed with the result of merging the {@link Suggestions}
|
* Returns a future that is completed with the result of merging the {@link Suggestions} the given
|
||||||
* the given futures complete with. The results of the futures that complete exceptionally
|
* futures complete with. The results of the futures that complete exceptionally are ignored.
|
||||||
* are ignored.
|
|
||||||
*
|
*
|
||||||
* @param fullInput the command input
|
* @param fullInput the command input
|
||||||
* @param futures the futures that complete with the suggestions
|
* @param futures the futures that complete with the suggestions
|
||||||
* @return the future that completes with the merged suggestions
|
* @return the future that completes with the merged suggestions
|
||||||
*/
|
*/
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
private CompletableFuture<Suggestions> merge(
|
private CompletableFuture<Suggestions> merge(
|
||||||
final String fullInput, final CompletableFuture<Suggestions>... futures) {
|
final String fullInput, final CompletableFuture<Suggestions>... futures) {
|
||||||
// https://github.com/Mojang/brigadier/pull/81
|
// https://github.com/Mojang/brigadier/pull/81
|
||||||
return CompletableFuture.allOf(futures).handle((unused, throwable) -> {
|
return CompletableFuture.allOf(futures).handle((unused, throwable) -> {
|
||||||
final List<Suggestions> suggestions = new ArrayList<>(futures.length);
|
final List<Suggestions> suggestions = new ArrayList<>(futures.length);
|
||||||
|
@ -54,6 +54,9 @@ import org.checkerframework.checker.lock.qual.GuardedBy;
|
|||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.jetbrains.annotations.VisibleForTesting;
|
import org.jetbrains.annotations.VisibleForTesting;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Impelements Velocity's command handler.
|
||||||
|
*/
|
||||||
public class VelocityCommandManager implements CommandManager {
|
public class VelocityCommandManager implements CommandManager {
|
||||||
|
|
||||||
private final @GuardedBy("lock") CommandDispatcher<CommandSource> dispatcher;
|
private final @GuardedBy("lock") CommandDispatcher<CommandSource> dispatcher;
|
||||||
@ -76,9 +79,9 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
this.eventManager = Preconditions.checkNotNull(eventManager);
|
this.eventManager = Preconditions.checkNotNull(eventManager);
|
||||||
final RootCommandNode<CommandSource> root = this.dispatcher.getRoot();
|
final RootCommandNode<CommandSource> root = this.dispatcher.getRoot();
|
||||||
this.registrars = ImmutableList.of(
|
this.registrars = ImmutableList.of(
|
||||||
new BrigadierCommandRegistrar(root, this.lock.writeLock()),
|
new BrigadierCommandRegistrar(root, this.lock.writeLock()),
|
||||||
new SimpleCommandRegistrar(root, this.lock.writeLock()),
|
new SimpleCommandRegistrar(root, this.lock.writeLock()),
|
||||||
new RawCommandRegistrar(root, this.lock.writeLock()));
|
new RawCommandRegistrar(root, this.lock.writeLock()));
|
||||||
this.suggestionsProvider = new SuggestionsProvider<>(this.dispatcher, this.lock.readLock());
|
this.suggestionsProvider = new SuggestionsProvider<>(this.dispatcher, this.lock.readLock());
|
||||||
this.injector = new CommandGraphInjector<>(this.dispatcher, this.lock.readLock());
|
this.injector = new CommandGraphInjector<>(this.dispatcher, this.lock.readLock());
|
||||||
this.commandMetas = new ConcurrentHashMap<>();
|
this.commandMetas = new ConcurrentHashMap<>();
|
||||||
@ -118,24 +121,24 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
command + " does not implement a registrable Command subinterface");
|
command + " does not implement a registrable Command subinterface");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to register the given command if it implements the
|
* Attempts to register the given command if it implements the
|
||||||
* {@linkplain CommandRegistrar#registrableSuperInterface() registrable superinterface}
|
* {@linkplain CommandRegistrar#registrableSuperInterface() registrable superinterface} of the
|
||||||
* of the given registrar.
|
* given registrar.
|
||||||
*
|
*
|
||||||
* @param registrar the registrar to register the command
|
* @param registrar the registrar to register the command
|
||||||
* @param command the command to register
|
* @param command the command to register
|
||||||
* @param meta the command metadata
|
* @param meta the command metadata
|
||||||
* @param <T> the type of the command
|
* @param <T> the type of the command
|
||||||
* @return true if the command implements the registrable superinterface of the registrar;
|
* @return true if the command implements the registrable superinterface of the registrar; false
|
||||||
* false otherwise.
|
* otherwise.
|
||||||
* @throws IllegalArgumentException if the registrar cannot register the command
|
* @throws IllegalArgumentException if the registrar cannot register the command
|
||||||
*/
|
*/
|
||||||
private <T extends Command> boolean tryRegister(final CommandRegistrar<T> registrar,
|
private <T extends Command> boolean tryRegister(final CommandRegistrar<T> registrar,
|
||||||
final Command command, final CommandMeta meta) {
|
final Command command, final CommandMeta meta) {
|
||||||
final Class<T> superInterface = registrar.registrableSuperInterface();
|
final Class<T> superInterface = registrar.registrableSuperInterface();
|
||||||
if (!superInterface.isInstance(command)) {
|
if (!superInterface.isInstance(command)) {
|
||||||
return false;
|
return false;
|
||||||
@ -188,7 +191,7 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
/**
|
/**
|
||||||
* Fires a {@link CommandExecuteEvent}.
|
* Fires a {@link CommandExecuteEvent}.
|
||||||
*
|
*
|
||||||
* @param source the source to execute the command for
|
* @param source the source to execute the command for
|
||||||
* @param cmdLine the command to execute
|
* @param cmdLine the command to execute
|
||||||
* @return the {@link CompletableFuture} of the event
|
* @return the {@link CompletableFuture} of the event
|
||||||
*/
|
*/
|
||||||
@ -251,10 +254,9 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
/**
|
/**
|
||||||
* Returns suggestions to fill in the given command.
|
* Returns suggestions to fill in the given command.
|
||||||
*
|
*
|
||||||
* @param source the source to execute the command for
|
* @param source the source to execute the command for
|
||||||
* @param cmdLine the partially completed command
|
* @param cmdLine the partially completed command
|
||||||
* @return a {@link CompletableFuture} eventually completed with a {@link List},
|
* @return a {@link CompletableFuture} eventually completed with a {@link List}, possibly empty
|
||||||
* possibly empty
|
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<List<String>> offerSuggestions(final CommandSource source,
|
public CompletableFuture<List<String>> offerSuggestions(final CommandSource source,
|
||||||
final String cmdLine) {
|
final String cmdLine) {
|
||||||
@ -265,10 +267,10 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
/**
|
/**
|
||||||
* Returns suggestions to fill in the given command.
|
* Returns suggestions to fill in the given command.
|
||||||
*
|
*
|
||||||
* @param source the source to execute the command for
|
* @param source the source to execute the command for
|
||||||
* @param cmdLine the partially completed command
|
* @param cmdLine the partially completed command
|
||||||
* @return a {@link CompletableFuture} eventually completed with {@link Suggestions},
|
* @return a {@link CompletableFuture} eventually completed with {@link Suggestions}, possibly
|
||||||
* possibly empty
|
* empty
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<Suggestions> offerBrigadierSuggestions(
|
public CompletableFuture<Suggestions> offerBrigadierSuggestions(
|
||||||
final CommandSource source, final String cmdLine) {
|
final CommandSource source, final String cmdLine) {
|
||||||
@ -281,14 +283,15 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
} catch (final Throwable e) {
|
} catch (final Throwable e) {
|
||||||
// Again, plugins are naughty
|
// Again, plugins are naughty
|
||||||
return CompletableFuture.failedFuture(
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the given command input.
|
* Parses the given command input.
|
||||||
*
|
*
|
||||||
* @param input the normalized command input, without the leading slash ('/')
|
* @param input the normalized command input, without the leading slash ('/')
|
||||||
* @param source the command source to parse the command for
|
* @param source the command source to parse the command for
|
||||||
* @return the parse results
|
* @return the parse results
|
||||||
*/
|
*/
|
||||||
@ -307,8 +310,8 @@ public class VelocityCommandManager implements CommandManager {
|
|||||||
try {
|
try {
|
||||||
// A RootCommandNode may only contain LiteralCommandNode children instances
|
// A RootCommandNode may only contain LiteralCommandNode children instances
|
||||||
return dispatcher.getRoot().getChildren().stream()
|
return dispatcher.getRoot().getChildren().stream()
|
||||||
.map(CommandNode::getName)
|
.map(CommandNode::getName)
|
||||||
.collect(ImmutableList.toImmutableList());
|
.collect(ImmutableList.toImmutableList());
|
||||||
} finally {
|
} finally {
|
||||||
lock.readLock().unlock();
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,9 @@ import java.util.stream.Stream;
|
|||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles building commands for plugins to register.
|
||||||
|
*/
|
||||||
public final class VelocityCommandMeta implements CommandMeta {
|
public final class VelocityCommandMeta implements CommandMeta {
|
||||||
|
|
||||||
static final class Builder implements CommandMeta.Builder {
|
static final class Builder implements CommandMeta.Builder {
|
||||||
@ -44,7 +47,7 @@ public final class VelocityCommandMeta implements CommandMeta {
|
|||||||
public Builder(final String alias) {
|
public Builder(final String alias) {
|
||||||
Preconditions.checkNotNull(alias, "alias");
|
Preconditions.checkNotNull(alias, "alias");
|
||||||
this.aliases = ImmutableSet.<String>builder()
|
this.aliases = ImmutableSet.<String>builder()
|
||||||
.add(alias.toLowerCase(Locale.ENGLISH));
|
.add(alias.toLowerCase(Locale.ENGLISH));
|
||||||
this.hints = ImmutableList.builder();
|
this.hints = ImmutableList.builder();
|
||||||
this.plugin = null;
|
this.plugin = null;
|
||||||
}
|
}
|
||||||
@ -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
|
* Creates a node to use for hinting the arguments of a {@link Command}. Hint nodes are sent to
|
||||||
* sent to 1.13+ clients and the proxy uses them for providing suggestions.
|
* 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
|
* <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
|
* the corresponding {@link CommandNode} are satisfied. The requirement predicate of the returned
|
||||||
* of the returned node always returns {@code false}.
|
* node always returns {@code false}.
|
||||||
*
|
*
|
||||||
* @param hint the node containing hinting metadata
|
* @param hint the node containing hinting metadata
|
||||||
* @return the hinting command node
|
* @return the hinting command node
|
||||||
@ -101,8 +104,8 @@ public final class VelocityCommandMeta implements CommandMeta {
|
|||||||
// We need to perform a deep copy of the hint to prevent the user
|
// We need to perform a deep copy of the hint to prevent the user
|
||||||
// from modifying the nodes and adding a Command or a redirect.
|
// from modifying the nodes and adding a Command or a redirect.
|
||||||
final ArgumentBuilder<CommandSource, ?> builder = hint.createBuilder()
|
final ArgumentBuilder<CommandSource, ?> builder = hint.createBuilder()
|
||||||
// Requirement checking is performed by SuggestionProvider
|
// Requirement checking is performed by SuggestionProvider
|
||||||
.requires(source -> false);
|
.requires(source -> false);
|
||||||
for (final CommandNode<CommandSource> child : hint.getChildren()) {
|
for (final CommandNode<CommandSource> child : hint.getChildren()) {
|
||||||
builder.then(copyForHinting(child));
|
builder.then(copyForHinting(child));
|
||||||
}
|
}
|
||||||
@ -125,9 +128,9 @@ public final class VelocityCommandMeta implements CommandMeta {
|
|||||||
private final Object plugin;
|
private final Object plugin;
|
||||||
|
|
||||||
private VelocityCommandMeta(
|
private VelocityCommandMeta(
|
||||||
final Set<String> aliases,
|
final Set<String> aliases,
|
||||||
final List<CommandNode<CommandSource>> hints,
|
final List<CommandNode<CommandSource>> hints,
|
||||||
final @Nullable Object plugin
|
final @Nullable Object plugin
|
||||||
) {
|
) {
|
||||||
this.aliases = aliases;
|
this.aliases = aliases;
|
||||||
this.hints = hints;
|
this.hints = hints;
|
||||||
|
@ -38,10 +38,9 @@ import java.util.Map;
|
|||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides utility methods common to most {@link Command} implementations.
|
* Provides utility methods common to most {@link Command} implementations. In particular,
|
||||||
* In particular, {@link InvocableCommand} implementations use the same logic for
|
* {@link InvocableCommand} implementations use the same logic for creating and parsing the alias
|
||||||
* creating and parsing the alias and arguments command nodes, which is contained
|
* and arguments command nodes, which is contained in this class.
|
||||||
* in this class.
|
|
||||||
*/
|
*/
|
||||||
public final class VelocityCommands {
|
public final class VelocityCommands {
|
||||||
|
|
||||||
@ -51,7 +50,7 @@ public final class VelocityCommands {
|
|||||||
* Normalizes the given command input.
|
* Normalizes the given command input.
|
||||||
*
|
*
|
||||||
* @param input the raw command input, without the leading slash ('/')
|
* @param input the raw command input, without the leading slash ('/')
|
||||||
* @param trim whether to remove leading and trailing whitespace from the input
|
* @param trim whether to remove leading and trailing whitespace from the input
|
||||||
* @return the normalized command input
|
* @return the normalized command input
|
||||||
*/
|
*/
|
||||||
static String normalizeInput(final String input, final boolean trim) {
|
static String normalizeInput(final String input, final boolean trim) {
|
||||||
@ -60,7 +59,7 @@ public final class VelocityCommands {
|
|||||||
if (firstSep != -1) {
|
if (firstSep != -1) {
|
||||||
// Aliases are case-insensitive, arguments are not
|
// Aliases are case-insensitive, arguments are not
|
||||||
return command.substring(0, firstSep).toLowerCase(Locale.ENGLISH)
|
return command.substring(0, firstSep).toLowerCase(Locale.ENGLISH)
|
||||||
+ command.substring(firstSep);
|
+ command.substring(firstSep);
|
||||||
} else {
|
} else {
|
||||||
return command.toLowerCase(Locale.ENGLISH);
|
return command.toLowerCase(Locale.ENGLISH);
|
||||||
}
|
}
|
||||||
@ -85,18 +84,19 @@ public final class VelocityCommands {
|
|||||||
public static final String ARGS_NODE_NAME = "arguments";
|
public static final String ARGS_NODE_NAME = "arguments";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the parsed arguments that come after the command alias, or {@code fallback} if
|
* Returns the parsed arguments that come after the command alias, or {@code fallback} if no
|
||||||
* no arguments were provided.
|
* arguments were provided.
|
||||||
*
|
*
|
||||||
* @param arguments the map of parsed arguments, as returned by
|
* @param arguments the map of parsed arguments, as returned by
|
||||||
* {@link CommandContext#getArguments()} or {@link CommandContextBuilder#getArguments()}
|
* {@link CommandContext#getArguments()} or
|
||||||
* @param type the type class of the arguments
|
* {@link CommandContextBuilder#getArguments()}
|
||||||
* @param fallback the value to return if no arguments were provided
|
* @param type the type class of the arguments
|
||||||
* @param <V> the type of the arguments
|
* @param fallback the value to return if no arguments were provided
|
||||||
|
* @param <V> the type of the arguments
|
||||||
* @return the command arguments
|
* @return the command arguments
|
||||||
*/
|
*/
|
||||||
public static <V> V readArguments(final Map<String, ? extends ParsedArgument<?, ?>> arguments,
|
public static <V> V readArguments(final Map<String, ? extends ParsedArgument<?, ?>> arguments,
|
||||||
final Class<V> type, final V fallback) {
|
final Class<V> type, final V fallback) {
|
||||||
final ParsedArgument<?, ?> argument = arguments.get(ARGS_NODE_NAME);
|
final ParsedArgument<?, ?> argument = arguments.get(ARGS_NODE_NAME);
|
||||||
if (argument == null) {
|
if (argument == null) {
|
||||||
return fallback; // either no arguments were given or this isn't an InvocableCommand
|
return fallback; // either no arguments were given or this isn't an InvocableCommand
|
||||||
@ -106,15 +106,15 @@ public final class VelocityCommands {
|
|||||||
return type.cast(result);
|
return type.cast(result);
|
||||||
} catch (final ClassCastException e) {
|
} catch (final ClassCastException e) {
|
||||||
throw new IllegalArgumentException("Parsed argument is of type " + result.getClass()
|
throw new IllegalArgumentException("Parsed argument is of type " + result.getClass()
|
||||||
+ ", expected " + type, e);
|
+ ", expected " + type, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alias nodes
|
// Alias nodes
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a literal node with the given name can be added to
|
* Returns whether a literal node with the given name can be added to the {@link RootCommandNode}
|
||||||
* the {@link RootCommandNode} associated to a {@link CommandManager}.
|
* associated to a {@link CommandManager}.
|
||||||
*
|
*
|
||||||
* <p>This is an internal method and should not be used in user-facing
|
* <p>This is an internal method and should not be used in user-facing
|
||||||
* methods. Instead, they should lowercase the given aliases themselves.
|
* methods. Instead, they should lowercase the given aliases themselves.
|
||||||
@ -130,11 +130,11 @@ public final class VelocityCommands {
|
|||||||
* Creates a copy of the given literal with the specified name.
|
* Creates a copy of the given literal with the specified name.
|
||||||
*
|
*
|
||||||
* @param original the literal node to copy
|
* @param original the literal node to copy
|
||||||
* @param newName the name of the returned literal node
|
* @param newName the name of the returned literal node
|
||||||
* @return a copy of the literal with the given name
|
* @return a copy of the literal with the given name
|
||||||
*/
|
*/
|
||||||
public static LiteralCommandNode<CommandSource> shallowCopy(
|
public static LiteralCommandNode<CommandSource> shallowCopy(
|
||||||
final LiteralCommandNode<CommandSource> original, final String newName) {
|
final LiteralCommandNode<CommandSource> original, final String newName) {
|
||||||
// Brigadier resolves the redirect of a node if further input can be parsed.
|
// Brigadier resolves the redirect of a node if further input can be parsed.
|
||||||
// Let <bar> be a literal node having a redirect to a <foo> literal. Then,
|
// Let <bar> be a literal node having a redirect to a <foo> literal. Then,
|
||||||
// the context returned by CommandDispatcher#parseNodes when given the input
|
// the context returned by CommandDispatcher#parseNodes when given the input
|
||||||
@ -145,11 +145,11 @@ public final class VelocityCommands {
|
|||||||
Preconditions.checkNotNull(original, "original");
|
Preconditions.checkNotNull(original, "original");
|
||||||
Preconditions.checkNotNull(newName, "secondaryAlias");
|
Preconditions.checkNotNull(newName, "secondaryAlias");
|
||||||
final LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder
|
final LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder
|
||||||
.<CommandSource>literal(newName)
|
.<CommandSource>literal(newName)
|
||||||
.requires(original.getRequirement())
|
.requires(original.getRequirement())
|
||||||
.requiresWithContext(original.getContextRequirement())
|
.requiresWithContext(original.getContextRequirement())
|
||||||
.forward(original.getRedirect(), original.getRedirectModifier(), original.isFork())
|
.forward(original.getRedirect(), original.getRedirectModifier(), original.isFork())
|
||||||
.executes(original.getCommand());
|
.executes(original.getCommand());
|
||||||
for (final CommandNode<CommandSource> child : original.getChildren()) {
|
for (final CommandNode<CommandSource> child : original.getChildren()) {
|
||||||
builder.then(child);
|
builder.then(child);
|
||||||
}
|
}
|
||||||
@ -159,15 +159,15 @@ public final class VelocityCommands {
|
|||||||
// Arguments node
|
// Arguments node
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the arguments node for the command represented by the given alias node,
|
* Returns the arguments node for the command represented by the given alias node, if present;
|
||||||
* if present; otherwise returns {@code null}.
|
* otherwise returns {@code null}.
|
||||||
*
|
*
|
||||||
* @param alias the alias node
|
* @param alias the alias node
|
||||||
* @param <S> the type of the command source
|
* @param <S> the type of the command source
|
||||||
* @return the arguments node, or null if not present
|
* @return the arguments node, or null if not present
|
||||||
*/
|
*/
|
||||||
static <S> @Nullable VelocityArgumentCommandNode<S, ?> getArgumentsNode(
|
static <S> @Nullable VelocityArgumentCommandNode<S, ?> getArgumentsNode(
|
||||||
final LiteralCommandNode<S> alias) {
|
final LiteralCommandNode<S> alias) {
|
||||||
final CommandNode<S> node = alias.getChild(ARGS_NODE_NAME);
|
final CommandNode<S> node = alias.getChild(ARGS_NODE_NAME);
|
||||||
if (node instanceof VelocityArgumentCommandNode) {
|
if (node instanceof VelocityArgumentCommandNode) {
|
||||||
return (VelocityArgumentCommandNode<S, ?>) node;
|
return (VelocityArgumentCommandNode<S, ?>) node;
|
||||||
|
@ -27,8 +27,8 @@ import java.util.Collection;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An argument type that parses the remaining contents of a {@link StringReader},
|
* An argument type that parses the remaining contents of a {@link StringReader}, splitting the
|
||||||
* splitting the input into words and placing the results in a string array.
|
* input into words and placing the results in a string array.
|
||||||
*/
|
*/
|
||||||
public final class StringArrayArgumentType implements ArgumentType<String[]> {
|
public final class StringArrayArgumentType implements ArgumentType<String[]> {
|
||||||
|
|
||||||
@ -36,10 +36,11 @@ public final class StringArrayArgumentType implements ArgumentType<String[]> {
|
|||||||
public static final String[] EMPTY = new String[0];
|
public static final String[] EMPTY = new String[0];
|
||||||
|
|
||||||
private static final Splitter WORD_SPLITTER =
|
private static final Splitter WORD_SPLITTER =
|
||||||
Splitter.on(CommandDispatcher.ARGUMENT_SEPARATOR_CHAR);
|
Splitter.on(CommandDispatcher.ARGUMENT_SEPARATOR_CHAR);
|
||||||
private static final List<String> EXAMPLES = Arrays.asList("word", "some words");
|
private static final List<String> EXAMPLES = Arrays.asList("word", "some words");
|
||||||
|
|
||||||
private StringArrayArgumentType() {}
|
private StringArrayArgumentType() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] parse(final StringReader reader) throws CommandSyntaxException {
|
public String[] parse(final StringReader reader) throws CommandSyntaxException {
|
||||||
|
@ -31,20 +31,20 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
|||||||
* @param <T> the type of the argument to parse
|
* @param <T> the type of the argument to parse
|
||||||
*/
|
*/
|
||||||
public final class VelocityArgumentBuilder<S, T>
|
public final class VelocityArgumentBuilder<S, T>
|
||||||
extends ArgumentBuilder<S, VelocityArgumentBuilder<S, T>> {
|
extends ArgumentBuilder<S, VelocityArgumentBuilder<S, T>> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a builder for creating {@link VelocityArgumentCommandNode}s with
|
* Creates a builder for creating {@link VelocityArgumentCommandNode}s with the given name and
|
||||||
* the given name and type.
|
* type.
|
||||||
*
|
*
|
||||||
* @param name the name of the node
|
* @param name the name of the node
|
||||||
* @param type the type of the argument to parse
|
* @param type the type of the argument to parse
|
||||||
* @param <S> the type of the command source
|
* @param <S> the type of the command source
|
||||||
* @param <T> the type of the argument to parse
|
* @param <T> the type of the argument to parse
|
||||||
* @return a builder
|
* @return a builder
|
||||||
*/
|
*/
|
||||||
public static <S, T> VelocityArgumentBuilder<S, T> velocityArgument(final String name,
|
public static <S, T> VelocityArgumentBuilder<S, T> velocityArgument(final String name,
|
||||||
final ArgumentType<T> type) {
|
final ArgumentType<T> type) {
|
||||||
Preconditions.checkNotNull(name, "name");
|
Preconditions.checkNotNull(name, "name");
|
||||||
Preconditions.checkNotNull(type, "type");
|
Preconditions.checkNotNull(type, "type");
|
||||||
return new VelocityArgumentBuilder<>(name, type);
|
return new VelocityArgumentBuilder<>(name, type);
|
||||||
@ -82,7 +82,7 @@ public final class VelocityArgumentBuilder<S, T>
|
|||||||
@Override
|
@Override
|
||||||
public VelocityArgumentCommandNode<S, T> build() {
|
public VelocityArgumentCommandNode<S, T> build() {
|
||||||
return new VelocityArgumentCommandNode<>(this.name, this.type, getCommand(), getRequirement(),
|
return new VelocityArgumentCommandNode<>(this.name, this.type, getCommand(), getRequirement(),
|
||||||
getContextRequirement(), getRedirect(), getRedirectModifier(), isFork(),
|
getContextRequirement(), getRedirect(), getRedirectModifier(), isFork(),
|
||||||
this.suggestionsProvider);
|
this.suggestionsProvider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,9 @@ import java.util.function.BiPredicate;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An argument node that uses the given (possibly custom) {@link ArgumentType}
|
* An argument node that uses the given (possibly custom) {@link ArgumentType} for parsing, while
|
||||||
* for parsing, while maintaining compatibility with the vanilla client.
|
* maintaining compatibility with the vanilla client. The argument type must be greedy and accept
|
||||||
* The argument type must be greedy and accept any input.
|
* any input.
|
||||||
*
|
*
|
||||||
* @param <S> the type of the command source
|
* @param <S> the type of the command source
|
||||||
* @param <T> the type of the argument to parse
|
* @param <T> the type of the argument to parse
|
||||||
@ -52,25 +52,25 @@ public class VelocityArgumentCommandNode<S, T> extends ArgumentCommandNode<S, St
|
|||||||
private final ArgumentType<T> type;
|
private final ArgumentType<T> type;
|
||||||
|
|
||||||
VelocityArgumentCommandNode(
|
VelocityArgumentCommandNode(
|
||||||
final String name, final ArgumentType<T> type, final Command<S> command,
|
final String name, final ArgumentType<T> type, final Command<S> command,
|
||||||
final Predicate<S> requirement,
|
final Predicate<S> requirement,
|
||||||
final BiPredicate<CommandContextBuilder<S>, ImmutableStringReader> contextRequirement,
|
final BiPredicate<CommandContextBuilder<S>, ImmutableStringReader> contextRequirement,
|
||||||
final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks,
|
final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks,
|
||||||
final SuggestionProvider<S> customSuggestions) {
|
final SuggestionProvider<S> customSuggestions) {
|
||||||
super(name, StringArgumentType.greedyString(), command, requirement, contextRequirement,
|
super(name, StringArgumentType.greedyString(), command, requirement, contextRequirement,
|
||||||
redirect, modifier, forks, customSuggestions);
|
redirect, modifier, forks, customSuggestions);
|
||||||
this.type = Preconditions.checkNotNull(type, "type");
|
this.type = Preconditions.checkNotNull(type, "type");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void parse(final StringReader reader, final CommandContextBuilder<S> contextBuilder)
|
public void parse(final StringReader reader, final CommandContextBuilder<S> contextBuilder)
|
||||||
throws CommandSyntaxException {
|
throws CommandSyntaxException {
|
||||||
// Same as super, except we use the rich ArgumentType
|
// Same as super, except we use the rich ArgumentType
|
||||||
final int start = reader.getCursor();
|
final int start = reader.getCursor();
|
||||||
final T result = this.type.parse(reader);
|
final T result = this.type.parse(reader);
|
||||||
if (reader.canRead()) {
|
if (reader.canRead()) {
|
||||||
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherParseException()
|
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherParseException()
|
||||||
.createWithContext(reader, "Expected greedy ArgumentType to parse all input");
|
.createWithContext(reader, "Expected greedy ArgumentType to parse all input");
|
||||||
}
|
}
|
||||||
|
|
||||||
final ParsedArgument<S, T> parsed = new ParsedArgument<>(start, reader.getCursor(), result);
|
final ParsedArgument<S, T> parsed = new ParsedArgument<>(start, reader.getCursor(), result);
|
||||||
@ -80,8 +80,8 @@ public class VelocityArgumentCommandNode<S, T> extends ArgumentCommandNode<S, St
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Suggestions> listSuggestions(
|
public CompletableFuture<Suggestions> listSuggestions(
|
||||||
final CommandContext<S> context, final SuggestionsBuilder builder)
|
final CommandContext<S> context, final SuggestionsBuilder builder)
|
||||||
throws CommandSyntaxException {
|
throws CommandSyntaxException {
|
||||||
if (getCustomSuggestions() == null) {
|
if (getCustomSuggestions() == null) {
|
||||||
return Suggestions.empty();
|
return Suggestions.empty();
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,9 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.kyori.adventure.text.TranslatableComponent;
|
import net.kyori.adventure.text.TranslatableComponent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic, common command messages.
|
||||||
|
*/
|
||||||
public class CommandMessages {
|
public class CommandMessages {
|
||||||
|
|
||||||
public static final TranslatableComponent PLAYERS_ONLY = Component.translatable(
|
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.TranslatableComponent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the Velocity default {@code /glist} command.
|
||||||
|
*/
|
||||||
public class GlistCommand {
|
public class GlistCommand {
|
||||||
|
|
||||||
private static final String SERVER_ARG = "server";
|
private static final String SERVER_ARG = "server";
|
||||||
@ -55,22 +58,22 @@ public class GlistCommand {
|
|||||||
*/
|
*/
|
||||||
public void register() {
|
public void register() {
|
||||||
LiteralCommandNode<CommandSource> totalNode = LiteralArgumentBuilder
|
LiteralCommandNode<CommandSource> totalNode = LiteralArgumentBuilder
|
||||||
.<CommandSource>literal("glist")
|
.<CommandSource>literal("glist")
|
||||||
.requires(source ->
|
.requires(source ->
|
||||||
source.getPermissionValue("velocity.command.glist") == Tristate.TRUE)
|
source.getPermissionValue("velocity.command.glist") == Tristate.TRUE)
|
||||||
.executes(this::totalCount)
|
.executes(this::totalCount)
|
||||||
.build();
|
.build();
|
||||||
ArgumentCommandNode<CommandSource, String> serverNode = RequiredArgumentBuilder
|
ArgumentCommandNode<CommandSource, String> serverNode = RequiredArgumentBuilder
|
||||||
.<CommandSource, String>argument(SERVER_ARG, StringArgumentType.string())
|
.<CommandSource, String>argument(SERVER_ARG, StringArgumentType.string())
|
||||||
.suggests((context, builder) -> {
|
.suggests((context, builder) -> {
|
||||||
for (RegisteredServer server : server.getAllServers()) {
|
for (RegisteredServer server : server.getAllServers()) {
|
||||||
builder.suggest(server.getServerInfo().getName());
|
builder.suggest(server.getServerInfo().getName());
|
||||||
}
|
}
|
||||||
builder.suggest("all");
|
builder.suggest("all");
|
||||||
return builder.buildFuture();
|
return builder.buildFuture();
|
||||||
})
|
})
|
||||||
.executes(this::serverCount)
|
.executes(this::serverCount)
|
||||||
.build();
|
.build();
|
||||||
totalNode.addChild(serverNode);
|
totalNode.addChild(serverNode);
|
||||||
server.getCommandManager().register(new BrigadierCommand(totalNode));
|
server.getCommandManager().register(new BrigadierCommand(totalNode));
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,9 @@ import net.kyori.adventure.text.TranslatableComponent;
|
|||||||
import net.kyori.adventure.text.event.ClickEvent;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements Velocity's {@code /server} command.
|
||||||
|
*/
|
||||||
public class ServerCommand implements SimpleCommand {
|
public class ServerCommand implements SimpleCommand {
|
||||||
|
|
||||||
public static final int MAX_SERVERS_TO_LIST = 50;
|
public static final int MAX_SERVERS_TO_LIST = 50;
|
||||||
@ -54,7 +57,7 @@ public class ServerCommand implements SimpleCommand {
|
|||||||
final String[] args = invocation.arguments();
|
final String[] args = invocation.arguments();
|
||||||
|
|
||||||
if (!(source instanceof Player)) {
|
if (!(source instanceof Player)) {
|
||||||
source.sendMessage(Identity.nil(), CommandMessages.PLAYERS_ONLY);
|
source.sendMessage(CommandMessages.PLAYERS_ONLY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,9 +66,8 @@ public class ServerCommand implements SimpleCommand {
|
|||||||
// Trying to connect to a server.
|
// Trying to connect to a server.
|
||||||
String serverName = args[0];
|
String serverName = args[0];
|
||||||
Optional<RegisteredServer> toConnect = server.getServer(serverName);
|
Optional<RegisteredServer> toConnect = server.getServer(serverName);
|
||||||
if (!toConnect.isPresent()) {
|
if (toConnect.isEmpty()) {
|
||||||
player.sendMessage(Identity.nil(), CommandMessages.SERVER_DOES_NOT_EXIST
|
player.sendMessage(CommandMessages.SERVER_DOES_NOT_EXIST.args(Component.text(serverName)));
|
||||||
.args(Component.text(serverName)));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,14 +80,14 @@ public class ServerCommand implements SimpleCommand {
|
|||||||
private void outputServerInformation(Player executor) {
|
private void outputServerInformation(Player executor) {
|
||||||
String currentServer = executor.getCurrentServer().map(ServerConnection::getServerInfo)
|
String currentServer = executor.getCurrentServer().map(ServerConnection::getServerInfo)
|
||||||
.map(ServerInfo::getName).orElse("<unknown>");
|
.map(ServerInfo::getName).orElse("<unknown>");
|
||||||
executor.sendMessage(Identity.nil(), Component.translatable(
|
executor.sendMessage(Component.translatable(
|
||||||
"velocity.command.server-current-server",
|
"velocity.command.server-current-server",
|
||||||
NamedTextColor.YELLOW,
|
NamedTextColor.YELLOW,
|
||||||
Component.text(currentServer)));
|
Component.text(currentServer)));
|
||||||
|
|
||||||
List<RegisteredServer> servers = BuiltinCommandUtil.sortedServerList(server);
|
List<RegisteredServer> servers = BuiltinCommandUtil.sortedServerList(server);
|
||||||
if (servers.size() > MAX_SERVERS_TO_LIST) {
|
if (servers.size() > MAX_SERVERS_TO_LIST) {
|
||||||
executor.sendMessage(Identity.nil(), Component.translatable(
|
executor.sendMessage(Component.translatable(
|
||||||
"velocity.command.server-too-many", NamedTextColor.RED));
|
"velocity.command.server-too-many", NamedTextColor.RED));
|
||||||
return;
|
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) {
|
private TextComponent formatServerComponent(String currentPlayerServer, RegisteredServer server) {
|
||||||
@ -113,9 +115,11 @@ public class ServerCommand implements SimpleCommand {
|
|||||||
int connectedPlayers = server.getPlayersConnected().size();
|
int connectedPlayers = server.getPlayersConnected().size();
|
||||||
TranslatableComponent playersTextComponent;
|
TranslatableComponent playersTextComponent;
|
||||||
if (connectedPlayers == 1) {
|
if (connectedPlayers == 1) {
|
||||||
playersTextComponent = Component.translatable("velocity.command.server-tooltip-player-online");
|
playersTextComponent = Component.translatable(
|
||||||
|
"velocity.command.server-tooltip-player-online");
|
||||||
} else {
|
} 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));
|
playersTextComponent = playersTextComponent.args(Component.text(connectedPlayers));
|
||||||
if (serverInfo.getName().equals(currentPlayerServer)) {
|
if (serverInfo.getName().equals(currentPlayerServer)) {
|
||||||
@ -130,9 +134,10 @@ public class ServerCommand implements SimpleCommand {
|
|||||||
serverTextComponent = serverTextComponent.color(NamedTextColor.GRAY)
|
serverTextComponent = serverTextComponent.color(NamedTextColor.GRAY)
|
||||||
.clickEvent(ClickEvent.runCommand("/server " + serverInfo.getName()))
|
.clickEvent(ClickEvent.runCommand("/server " + serverInfo.getName()))
|
||||||
.hoverEvent(
|
.hoverEvent(
|
||||||
showText(Component.translatable("velocity.command.server-tooltip-offer-connect-server")
|
showText(
|
||||||
.append(Component.newline())
|
Component.translatable("velocity.command.server-tooltip-offer-connect-server")
|
||||||
.append(playersTextComponent))
|
.append(Component.newline())
|
||||||
|
.append(playersTextComponent))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return serverTextComponent;
|
return serverTextComponent;
|
||||||
@ -142,7 +147,7 @@ public class ServerCommand implements SimpleCommand {
|
|||||||
public List<String> suggest(final SimpleCommand.Invocation invocation) {
|
public List<String> suggest(final SimpleCommand.Invocation invocation) {
|
||||||
final String[] currentArgs = invocation.arguments();
|
final String[] currentArgs = invocation.arguments();
|
||||||
Stream<String> possibilities = server.getAllServers().stream()
|
Stream<String> possibilities = server.getAllServers().stream()
|
||||||
.map(rs -> rs.getServerInfo().getName());
|
.map(rs -> rs.getServerInfo().getName());
|
||||||
|
|
||||||
if (currentArgs.length == 0) {
|
if (currentArgs.length == 0) {
|
||||||
return possibilities.collect(Collectors.toList());
|
return possibilities.collect(Collectors.toList());
|
||||||
|
@ -27,31 +27,38 @@ import com.velocitypowered.proxy.VelocityServer;
|
|||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
public final class ShutdownCommand {
|
/**
|
||||||
private ShutdownCommand() {}
|
* Shuts down the proxy.
|
||||||
|
*/
|
||||||
|
public final class ShutdownCommand {
|
||||||
|
|
||||||
|
private ShutdownCommand() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Velocity Shutdown Command.
|
* Creates a Velocity Shutdown Command.
|
||||||
|
*
|
||||||
* @param server the proxy instance
|
* @param server the proxy instance
|
||||||
* @return the Shutdown Command
|
* @return the Shutdown Command
|
||||||
*/
|
*/
|
||||||
public static BrigadierCommand command(final VelocityServer server) {
|
public static BrigadierCommand command(final VelocityServer server) {
|
||||||
return new BrigadierCommand(LiteralArgumentBuilder.<CommandSource>literal("shutdown")
|
return new BrigadierCommand(LiteralArgumentBuilder.<CommandSource>literal("shutdown")
|
||||||
.requires(source -> source == server.getConsoleCommandSource())
|
.requires(source -> source == server.getConsoleCommandSource())
|
||||||
.executes(context -> {
|
|
||||||
server.shutdown(true);
|
|
||||||
return Command.SINGLE_SUCCESS;
|
|
||||||
})
|
|
||||||
.then(RequiredArgumentBuilder.<CommandSource, String>argument("reason", StringArgumentType.greedyString())
|
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
String reason = context.getArgument("reason", String.class);
|
server.shutdown(true);
|
||||||
server.shutdown(true, MiniMessage.miniMessage().deserialize(
|
|
||||||
MiniMessage.miniMessage().serialize(
|
|
||||||
LegacyComponentSerializer.legacy('&').deserialize(reason)
|
|
||||||
)
|
|
||||||
));
|
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
})
|
})
|
||||||
).build());
|
.then(RequiredArgumentBuilder.<CommandSource, String>argument("reason",
|
||||||
|
StringArgumentType.greedyString())
|
||||||
|
.executes(context -> {
|
||||||
|
String reason = context.getArgument("reason", String.class);
|
||||||
|
server.shutdown(true, MiniMessage.miniMessage().deserialize(
|
||||||
|
MiniMessage.miniMessage().serialize(
|
||||||
|
LegacyComponentSerializer.legacy('&').deserialize(reason)
|
||||||
|
)
|
||||||
|
));
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
|
})
|
||||||
|
).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,9 @@ import org.apache.logging.log4j.LogManager;
|
|||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements the {@code /velocity} command and friends.
|
||||||
|
*/
|
||||||
public class VelocityCommand implements SimpleCommand {
|
public class VelocityCommand implements SimpleCommand {
|
||||||
|
|
||||||
private interface SubCommand {
|
private interface SubCommand {
|
||||||
@ -125,9 +128,9 @@ public class VelocityCommand implements SimpleCommand {
|
|||||||
|
|
||||||
if (currentArgs.length == 0) {
|
if (currentArgs.length == 0) {
|
||||||
return commands.entrySet().stream()
|
return commands.entrySet().stream()
|
||||||
.filter(e -> e.getValue().hasPermission(source, new String[0]))
|
.filter(e -> e.getValue().hasPermission(source, new String[0]))
|
||||||
.map(Map.Entry::getKey)
|
.map(Map.Entry::getKey)
|
||||||
.collect(ImmutableList.toImmutableList());
|
.collect(ImmutableList.toImmutableList());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentArgs.length == 1) {
|
if (currentArgs.length == 1) {
|
||||||
@ -353,11 +356,11 @@ public class VelocityCommand implements SimpleCommand {
|
|||||||
JsonObject servers = new JsonObject();
|
JsonObject servers = new JsonObject();
|
||||||
for (RegisteredServer iter : allServers) {
|
for (RegisteredServer iter : allServers) {
|
||||||
servers.add(iter.getServerInfo().getName(),
|
servers.add(iter.getServerInfo().getName(),
|
||||||
InformationUtils.collectServerInfo(iter));
|
InformationUtils.collectServerInfo(iter));
|
||||||
}
|
}
|
||||||
JsonArray connectOrder = new JsonArray();
|
JsonArray connectOrder = new JsonArray();
|
||||||
List<String> attemptedConnectionOrder = ImmutableList.copyOf(
|
List<String> attemptedConnectionOrder = ImmutableList.copyOf(
|
||||||
server.getConfiguration().getAttemptConnectionOrder());
|
server.getConfiguration().getAttemptConnectionOrder());
|
||||||
for (String s : attemptedConnectionOrder) {
|
for (String s : attemptedConnectionOrder) {
|
||||||
connectOrder.add(s);
|
connectOrder.add(s);
|
||||||
}
|
}
|
||||||
@ -366,7 +369,7 @@ public class VelocityCommand implements SimpleCommand {
|
|||||||
proxyConfig.add("servers", servers);
|
proxyConfig.add("servers", servers);
|
||||||
proxyConfig.add("connectOrder", connectOrder);
|
proxyConfig.add("connectOrder", connectOrder);
|
||||||
proxyConfig.add("forcedHosts",
|
proxyConfig.add("forcedHosts",
|
||||||
InformationUtils.collectForcedHosts(server.getConfiguration()));
|
InformationUtils.collectForcedHosts(server.getConfiguration()));
|
||||||
|
|
||||||
JsonObject dump = new JsonObject();
|
JsonObject dump = new JsonObject();
|
||||||
dump.add("versionInfo", InformationUtils.collectProxyInfo(server.getVersion()));
|
dump.add("versionInfo", InformationUtils.collectProxyInfo(server.getVersion()));
|
||||||
@ -383,7 +386,8 @@ public class VelocityCommand implements SimpleCommand {
|
|||||||
|
|
||||||
source.sendMessage(Component.text(
|
source.sendMessage(Component.text(
|
||||||
"An anonymised report containing useful information about "
|
"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) {
|
} catch (IOException e) {
|
||||||
logger.error("Failed to complete dump command, "
|
logger.error("Failed to complete dump command, "
|
||||||
+ "the executor was interrupted: " + e.getMessage());
|
+ "the executor was interrupted: " + e.getMessage());
|
||||||
|
@ -27,14 +27,12 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates command invocation objects from a command context builder or
|
* Creates command invocation objects from a command context builder or a command context.
|
||||||
* a command context.
|
|
||||||
*
|
*
|
||||||
* <p>Let {@code builder} be a command context builder, and {@code context}
|
* <p>Let {@code builder} be a command context builder, and {@code context}
|
||||||
* a context returned by calling {@link CommandContextBuilder#build(String)} on
|
* a context returned by calling {@link CommandContextBuilder#build(String)} on {@code builder}. The
|
||||||
* {@code builder}. The invocations returned by {@link #create(CommandContext)}
|
* invocations returned by {@link #create(CommandContext)} when given {@code context}, and
|
||||||
* when given {@code context}, and {@link #create(CommandContextBuilder)} when
|
* {@link #create(CommandContextBuilder)} when given {@code builder} are equal.
|
||||||
* given {@code builder} are equal.
|
|
||||||
*
|
*
|
||||||
* @param <I> the type of the built invocation
|
* @param <I> the type of the built invocation
|
||||||
*/
|
*/
|
||||||
@ -63,16 +61,17 @@ public interface CommandInvocationFactory<I extends CommandInvocation<?>> {
|
|||||||
/**
|
/**
|
||||||
* Creates an invocation from the given parsed nodes and arguments.
|
* Creates an invocation from the given parsed nodes and arguments.
|
||||||
*
|
*
|
||||||
* @param source the command source
|
* @param source the command source
|
||||||
* @param nodes the list of parsed nodes, as returned by {@link CommandContext#getNodes()} and
|
* @param nodes the list of parsed nodes, as returned by {@link CommandContext#getNodes()} and
|
||||||
* {@link CommandContextBuilder#getNodes()}
|
* {@link CommandContextBuilder#getNodes()}
|
||||||
* @param arguments the list of parsed arguments, as returned by
|
* @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
|
* @return the built invocation context
|
||||||
*/
|
*/
|
||||||
// This provides an abstraction over methods common to CommandContext and CommandContextBuilder.
|
// This provides an abstraction over methods common to CommandContext and CommandContextBuilder.
|
||||||
// Annoyingly, they mostly have the same getters but one is (correctly) not a subclass of
|
// Annoyingly, they mostly have the same getters but one is (correctly) not a subclass of
|
||||||
// the other. Subclasses may override the methods above to obtain class-specific data.
|
// the other. Subclasses may override the methods above to obtain class-specific data.
|
||||||
I create(final CommandSource source, final List<? extends ParsedCommandNode<?>> nodes,
|
I create(final CommandSource source, final List<? extends ParsedCommandNode<?>> nodes,
|
||||||
final Map<String, ? extends ParsedArgument<?, ?>> arguments);
|
final Map<String, ? extends ParsedArgument<?, ?>> arguments);
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,16 @@ import com.mojang.brigadier.context.ParsedArgument;
|
|||||||
import com.mojang.brigadier.context.ParsedCommandNode;
|
import com.mojang.brigadier.context.ParsedCommandNode;
|
||||||
import com.velocitypowered.api.command.CommandSource;
|
import com.velocitypowered.api.command.CommandSource;
|
||||||
import com.velocitypowered.api.command.RawCommand;
|
import com.velocitypowered.api.command.RawCommand;
|
||||||
|
import com.velocitypowered.api.command.SimpleCommand;
|
||||||
import com.velocitypowered.proxy.command.VelocityCommands;
|
import com.velocitypowered.proxy.command.VelocityCommands;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements {@link RawCommand.Invocation}.
|
||||||
|
*/
|
||||||
public final class RawCommandInvocation extends AbstractCommandInvocation<String>
|
public final class RawCommandInvocation extends AbstractCommandInvocation<String>
|
||||||
implements RawCommand.Invocation {
|
implements RawCommand.Invocation {
|
||||||
|
|
||||||
public static final Factory FACTORY = new Factory();
|
public static final Factory FACTORY = new Factory();
|
||||||
|
|
||||||
@ -35,8 +39,8 @@ public final class RawCommandInvocation extends AbstractCommandInvocation<String
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RawCommand.Invocation create(
|
public RawCommand.Invocation create(
|
||||||
final CommandSource source, final List<? extends ParsedCommandNode<?>> nodes,
|
final CommandSource source, final List<? extends ParsedCommandNode<?>> nodes,
|
||||||
final Map<String, ? extends ParsedArgument<?, ?>> arguments) {
|
final Map<String, ? extends ParsedArgument<?, ?>> arguments) {
|
||||||
final String alias = VelocityCommands.readAlias(nodes);
|
final String alias = VelocityCommands.readAlias(nodes);
|
||||||
final String args = VelocityCommands.readArguments(arguments, String.class, "");
|
final String args = VelocityCommands.readArguments(arguments, String.class, "");
|
||||||
return new RawCommandInvocation(source, alias, args);
|
return new RawCommandInvocation(source, alias, args);
|
||||||
@ -46,7 +50,7 @@ public final class RawCommandInvocation extends AbstractCommandInvocation<String
|
|||||||
private final String alias;
|
private final String alias;
|
||||||
|
|
||||||
private RawCommandInvocation(final CommandSource source,
|
private RawCommandInvocation(final CommandSource source,
|
||||||
final String alias, final String arguments) {
|
final String alias, final String arguments) {
|
||||||
super(source, arguments);
|
super(source, arguments);
|
||||||
this.alias = Preconditions.checkNotNull(alias, "alias");
|
this.alias = Preconditions.checkNotNull(alias, "alias");
|
||||||
}
|
}
|
||||||
@ -82,9 +86,9 @@ public final class RawCommandInvocation extends AbstractCommandInvocation<String
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "RawCommandInvocation{"
|
return "RawCommandInvocation{"
|
||||||
+ "source='" + this.source() + '\''
|
+ "source='" + this.source() + '\''
|
||||||
+ ", alias='" + this.alias + '\''
|
+ ", alias='" + this.alias + '\''
|
||||||
+ ", arguments='" + this.arguments() + '\''
|
+ ", arguments='" + this.arguments() + '\''
|
||||||
+ '}';
|
+ '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,11 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements {@link SimpleCommand.Invocation}.
|
||||||
|
*/
|
||||||
public final class SimpleCommandInvocation extends AbstractCommandInvocation<String[]>
|
public final class SimpleCommandInvocation extends AbstractCommandInvocation<String[]>
|
||||||
implements SimpleCommand.Invocation {
|
implements SimpleCommand.Invocation {
|
||||||
|
|
||||||
public static final Factory FACTORY = new Factory();
|
public static final Factory FACTORY = new Factory();
|
||||||
|
|
||||||
@ -37,11 +40,11 @@ public final class SimpleCommandInvocation extends AbstractCommandInvocation<Str
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SimpleCommand.Invocation create(
|
public SimpleCommand.Invocation create(
|
||||||
final CommandSource source, final List<? extends ParsedCommandNode<?>> nodes,
|
final CommandSource source, final List<? extends ParsedCommandNode<?>> nodes,
|
||||||
final Map<String, ? extends ParsedArgument<?, ?>> arguments) {
|
final Map<String, ? extends ParsedArgument<?, ?>> arguments) {
|
||||||
final String alias = VelocityCommands.readAlias(nodes);
|
final String alias = VelocityCommands.readAlias(nodes);
|
||||||
final String[] args = VelocityCommands.readArguments(
|
final String[] args = VelocityCommands.readArguments(
|
||||||
arguments, String[].class, StringArrayArgumentType.EMPTY);
|
arguments, String[].class, StringArrayArgumentType.EMPTY);
|
||||||
return new SimpleCommandInvocation(source, alias, args);
|
return new SimpleCommandInvocation(source, alias, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -49,7 +52,7 @@ public final class SimpleCommandInvocation extends AbstractCommandInvocation<Str
|
|||||||
private final String alias;
|
private final String alias;
|
||||||
|
|
||||||
SimpleCommandInvocation(final CommandSource source, final String alias,
|
SimpleCommandInvocation(final CommandSource source, final String alias,
|
||||||
final String[] arguments) {
|
final String[] arguments) {
|
||||||
super(source, arguments);
|
super(source, arguments);
|
||||||
this.alias = Preconditions.checkNotNull(alias, "alias");
|
this.alias = Preconditions.checkNotNull(alias, "alias");
|
||||||
}
|
}
|
||||||
@ -85,9 +88,9 @@ public final class SimpleCommandInvocation extends AbstractCommandInvocation<Str
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SimpleCommandInvocation{"
|
return "SimpleCommandInvocation{"
|
||||||
+ "source='" + this.source() + '\''
|
+ "source='" + this.source() + '\''
|
||||||
+ ", alias='" + this.alias + '\''
|
+ ", alias='" + this.alias + '\''
|
||||||
+ ", arguments='" + Arrays.toString(this.arguments()) + '\''
|
+ ", arguments='" + Arrays.toString(this.arguments()) + '\''
|
||||||
+ '}';
|
+ '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,9 +53,9 @@ abstract class AbstractCommandRegistrar<T extends Command> implements CommandReg
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void register(final LiteralCommandNode<CommandSource> node,
|
protected void register(final LiteralCommandNode<CommandSource> node,
|
||||||
final String secondaryAlias) {
|
final String secondaryAlias) {
|
||||||
final LiteralCommandNode<CommandSource> copy =
|
final LiteralCommandNode<CommandSource> copy =
|
||||||
VelocityCommands.shallowCopy(node, secondaryAlias);
|
VelocityCommands.shallowCopy(node, secondaryAlias);
|
||||||
this.register(copy);
|
this.register(copy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ import com.velocitypowered.api.command.Command;
|
|||||||
import com.velocitypowered.api.command.CommandMeta;
|
import com.velocitypowered.api.command.CommandMeta;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and registers the {@link LiteralCommandNode} representations of
|
* Creates and registers the {@link LiteralCommandNode} representations of a given {@link Command}
|
||||||
* a given {@link Command} in a {@link RootCommandNode}.
|
* in a {@link RootCommandNode}.
|
||||||
*
|
*
|
||||||
* @param <T> the type of the command to register
|
* @param <T> the type of the command to register
|
||||||
*/
|
*/
|
||||||
@ -33,16 +33,16 @@ public interface CommandRegistrar<T extends Command> {
|
|||||||
/**
|
/**
|
||||||
* Registers the given command.
|
* Registers the given command.
|
||||||
*
|
*
|
||||||
* @param meta the command metadata, including the case-insensitive aliases
|
* @param meta the command metadata, including the case-insensitive aliases
|
||||||
* @param command the command to register
|
* @param command the command to register
|
||||||
* @throws IllegalArgumentException if the given command cannot be registered
|
* @throws IllegalArgumentException if the given command cannot be registered
|
||||||
*/
|
*/
|
||||||
void register(final CommandMeta meta, final T command);
|
void register(final CommandMeta meta, final T command);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the superclass or superinterface of all {@link Command} classes
|
* Returns the superclass or superinterface of all {@link Command} classes compatible with this
|
||||||
* compatible with this registrar. Note that {@link #register(CommandMeta, Command)}
|
* registrar. Note that {@link #register(CommandMeta, Command)} may impose additional restrictions
|
||||||
* may impose additional restrictions on individual {@link Command} instances.
|
* on individual {@link Command} instances.
|
||||||
*
|
*
|
||||||
* @return the superclass of all the classes compatible with this registrar
|
* @return the superclass of all the classes compatible with this registrar
|
||||||
*/
|
*/
|
||||||
|
@ -42,14 +42,14 @@ import java.util.function.Predicate;
|
|||||||
* {@link InvocableCommand} in a root node.
|
* {@link InvocableCommand} in a root node.
|
||||||
*/
|
*/
|
||||||
abstract class InvocableCommandRegistrar<T extends InvocableCommand<I>,
|
abstract class InvocableCommandRegistrar<T extends InvocableCommand<I>,
|
||||||
I extends CommandInvocation<A>, A> extends AbstractCommandRegistrar<T> {
|
I extends CommandInvocation<A>, A> extends AbstractCommandRegistrar<T> {
|
||||||
|
|
||||||
private final CommandInvocationFactory<I> invocationFactory;
|
private final CommandInvocationFactory<I> invocationFactory;
|
||||||
private final ArgumentType<A> argumentsType;
|
private final ArgumentType<A> argumentsType;
|
||||||
|
|
||||||
protected InvocableCommandRegistrar(final RootCommandNode<CommandSource> root, final Lock lock,
|
protected InvocableCommandRegistrar(final RootCommandNode<CommandSource> root, final Lock lock,
|
||||||
final CommandInvocationFactory<I> invocationFactory,
|
final CommandInvocationFactory<I> invocationFactory,
|
||||||
final ArgumentType<A> argumentsType) {
|
final ArgumentType<A> argumentsType) {
|
||||||
super(root, lock);
|
super(root, lock);
|
||||||
this.invocationFactory = Preconditions.checkNotNull(invocationFactory, "invocationFactory");
|
this.invocationFactory = Preconditions.checkNotNull(invocationFactory, "invocationFactory");
|
||||||
this.argumentsType = Preconditions.checkNotNull(argumentsType, "argumentsType");
|
this.argumentsType = Preconditions.checkNotNull(argumentsType, "argumentsType");
|
||||||
@ -61,7 +61,7 @@ abstract class InvocableCommandRegistrar<T extends InvocableCommand<I>,
|
|||||||
|
|
||||||
final String primaryAlias = aliases.next();
|
final String primaryAlias = aliases.next();
|
||||||
final LiteralCommandNode<CommandSource> literal =
|
final LiteralCommandNode<CommandSource> literal =
|
||||||
this.createLiteral(command, meta, primaryAlias);
|
this.createLiteral(command, meta, primaryAlias);
|
||||||
this.register(literal);
|
this.register(literal);
|
||||||
|
|
||||||
while (aliases.hasNext()) {
|
while (aliases.hasNext()) {
|
||||||
@ -71,7 +71,7 @@ abstract class InvocableCommandRegistrar<T extends InvocableCommand<I>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private LiteralCommandNode<CommandSource> createLiteral(final T command, final CommandMeta meta,
|
private LiteralCommandNode<CommandSource> createLiteral(final T command, final CommandMeta meta,
|
||||||
final String alias) {
|
final String alias) {
|
||||||
final Predicate<CommandContextBuilder<CommandSource>> requirement = context -> {
|
final Predicate<CommandContextBuilder<CommandSource>> requirement = context -> {
|
||||||
final I invocation = invocationFactory.create(context);
|
final I invocation = invocationFactory.create(context);
|
||||||
return command.hasPermission(invocation);
|
return command.hasPermission(invocation);
|
||||||
@ -83,35 +83,35 @@ abstract class InvocableCommandRegistrar<T extends InvocableCommand<I>,
|
|||||||
};
|
};
|
||||||
|
|
||||||
final LiteralCommandNode<CommandSource> literal = LiteralArgumentBuilder
|
final LiteralCommandNode<CommandSource> literal = LiteralArgumentBuilder
|
||||||
.<CommandSource>literal(alias)
|
.<CommandSource>literal(alias)
|
||||||
.requiresWithContext((context, reader) -> {
|
.requiresWithContext((context, reader) -> {
|
||||||
if (reader.canRead()) {
|
if (reader.canRead()) {
|
||||||
// InvocableCommands do not follow a tree-like permissions checking structure.
|
// InvocableCommands do not follow a tree-like permissions checking structure.
|
||||||
// Thus, a CommandSource may be able to execute a command with arguments while
|
// Thus, a CommandSource may be able to execute a command with arguments while
|
||||||
// not being able to execute the argument-less variant.
|
// not being able to execute the argument-less variant.
|
||||||
// Only check for permissions once parsing is complete.
|
// Only check for permissions once parsing is complete.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return requirement.test(context);
|
return requirement.test(context);
|
||||||
})
|
})
|
||||||
.executes(callback)
|
.executes(callback)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final ArgumentCommandNode<CommandSource, String> arguments = VelocityArgumentBuilder
|
final ArgumentCommandNode<CommandSource, String> arguments = VelocityArgumentBuilder
|
||||||
.<CommandSource, A>velocityArgument(VelocityCommands.ARGS_NODE_NAME, argumentsType)
|
.<CommandSource, A>velocityArgument(VelocityCommands.ARGS_NODE_NAME, argumentsType)
|
||||||
.requiresWithContext((context, reader) -> requirement.test(context))
|
.requiresWithContext((context, reader) -> requirement.test(context))
|
||||||
.executes(callback)
|
.executes(callback)
|
||||||
.suggests((context, builder) -> {
|
.suggests((context, builder) -> {
|
||||||
final I invocation = invocationFactory.create(context);
|
final I invocation = invocationFactory.create(context);
|
||||||
return command.suggestAsync(invocation).thenApply(suggestions -> {
|
return command.suggestAsync(invocation).thenApply(suggestions -> {
|
||||||
for (String value : suggestions) {
|
for (String value : suggestions) {
|
||||||
Preconditions.checkNotNull(value, "suggestion");
|
Preconditions.checkNotNull(value, "suggestion");
|
||||||
builder.suggest(value);
|
builder.suggest(value);
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
literal.addChild(arguments);
|
literal.addChild(arguments);
|
||||||
|
|
||||||
// Add hinting nodes
|
// Add hinting nodes
|
||||||
|
@ -28,7 +28,7 @@ import java.util.concurrent.locks.Lock;
|
|||||||
* Registers {@link RawCommand}s in a root node.
|
* Registers {@link RawCommand}s in a root node.
|
||||||
*/
|
*/
|
||||||
public final class RawCommandRegistrar
|
public final class RawCommandRegistrar
|
||||||
extends InvocableCommandRegistrar<RawCommand, RawCommand.Invocation, String> {
|
extends InvocableCommandRegistrar<RawCommand, RawCommand.Invocation, String> {
|
||||||
|
|
||||||
public RawCommandRegistrar(final RootCommandNode<CommandSource> root, final Lock lock) {
|
public RawCommandRegistrar(final RootCommandNode<CommandSource> root, final Lock lock) {
|
||||||
super(root, lock, RawCommandInvocation.FACTORY, StringArgumentType.greedyString());
|
super(root, lock, RawCommandInvocation.FACTORY, StringArgumentType.greedyString());
|
||||||
|
@ -28,7 +28,7 @@ import java.util.concurrent.locks.Lock;
|
|||||||
* Registers {@link SimpleCommand}s in a root node.
|
* Registers {@link SimpleCommand}s in a root node.
|
||||||
*/
|
*/
|
||||||
public final class SimpleCommandRegistrar
|
public final class SimpleCommandRegistrar
|
||||||
extends InvocableCommandRegistrar<SimpleCommand, SimpleCommand.Invocation, String[]> {
|
extends InvocableCommandRegistrar<SimpleCommand, SimpleCommand.Invocation, String[]> {
|
||||||
|
|
||||||
public SimpleCommandRegistrar(final RootCommandNode<CommandSource> root, final Lock lock) {
|
public SimpleCommandRegistrar(final RootCommandNode<CommandSource> root, final Lock lock) {
|
||||||
super(root, lock, SimpleCommandInvocation.FACTORY, StringArrayArgumentType.INSTANCE);
|
super(root, lock, SimpleCommandInvocation.FACTORY, StringArrayArgumentType.INSTANCE);
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
package com.velocitypowered.proxy.config;
|
package com.velocitypowered.proxy.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported passthrough modes for ping passthrough.
|
||||||
|
*/
|
||||||
public enum PingPassthroughMode {
|
public enum PingPassthroughMode {
|
||||||
DISABLED,
|
DISABLED,
|
||||||
MODS,
|
MODS,
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
package com.velocitypowered.proxy.config;
|
package com.velocitypowered.proxy.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported player info forwarding methods.
|
||||||
|
*/
|
||||||
public enum PlayerInfoForwarding {
|
public enum PlayerInfoForwarding {
|
||||||
NONE,
|
NONE,
|
||||||
LEGACY,
|
LEGACY,
|
||||||
|
@ -52,29 +52,45 @@ import org.apache.logging.log4j.Logger;
|
|||||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Velocity's configuration.
|
||||||
|
*/
|
||||||
public class VelocityConfiguration implements ProxyConfig {
|
public class VelocityConfiguration implements ProxyConfig {
|
||||||
|
|
||||||
private static final Logger logger = LogManager.getLogger(VelocityConfiguration.class);
|
private static final Logger logger = LogManager.getLogger(VelocityConfiguration.class);
|
||||||
|
|
||||||
@Expose private String bind = "0.0.0.0:25577";
|
@Expose
|
||||||
@Expose private String motd = "&3A Velocity Server";
|
private String bind = "0.0.0.0:25577";
|
||||||
@Expose private int showMaxPlayers = 500;
|
@Expose
|
||||||
@Expose private boolean onlineMode = true;
|
private String motd = "&3A Velocity Server";
|
||||||
@Expose private boolean preventClientProxyConnections = false;
|
@Expose
|
||||||
@Expose private PlayerInfoForwarding playerInfoForwardingMode = PlayerInfoForwarding.NONE;
|
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);
|
private byte[] forwardingSecret = generateRandomString(12).getBytes(StandardCharsets.UTF_8);
|
||||||
@Expose private boolean announceForge = false;
|
@Expose
|
||||||
@Expose private boolean onlineModeKickExistingPlayers = false;
|
private boolean announceForge = false;
|
||||||
@Expose private PingPassthroughMode pingPassthrough = PingPassthroughMode.DISABLED;
|
@Expose
|
||||||
|
private boolean onlineModeKickExistingPlayers = false;
|
||||||
|
@Expose
|
||||||
|
private PingPassthroughMode pingPassthrough = PingPassthroughMode.DISABLED;
|
||||||
private final Servers servers;
|
private final Servers servers;
|
||||||
private final ForcedHosts forcedHosts;
|
private final ForcedHosts forcedHosts;
|
||||||
@Expose private final Advanced advanced;
|
@Expose
|
||||||
@Expose private final Query query;
|
private final Advanced advanced;
|
||||||
|
@Expose
|
||||||
|
private final Query query;
|
||||||
private final Metrics metrics;
|
private final Metrics metrics;
|
||||||
@Expose private boolean enablePlayerAddressLogging = true;
|
@Expose
|
||||||
|
private boolean enablePlayerAddressLogging = true;
|
||||||
private net.kyori.adventure.text.@MonotonicNonNull Component motdAsComponent;
|
private net.kyori.adventure.text.@MonotonicNonNull Component motdAsComponent;
|
||||||
private @Nullable Favicon favicon;
|
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,
|
private VelocityConfiguration(Servers servers, ForcedHosts forcedHosts, Advanced advanced,
|
||||||
Query query, Metrics metrics) {
|
Query query, Metrics metrics) {
|
||||||
@ -112,6 +128,7 @@ public class VelocityConfiguration implements ProxyConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to validate the configuration.
|
* Attempts to validate the configuration.
|
||||||
|
*
|
||||||
* @return {@code true} if the configuration is sound, {@code false} if not
|
* @return {@code true} if the configuration is sound, {@code false} if not
|
||||||
*/
|
*/
|
||||||
public boolean validate() {
|
public boolean validate() {
|
||||||
@ -408,6 +425,7 @@ public class VelocityConfiguration implements ProxyConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads the Velocity configuration from {@code path}.
|
* Reads the Velocity configuration from {@code path}.
|
||||||
|
*
|
||||||
* @param path the path to read from
|
* @param path the path to read from
|
||||||
* @return the deserialized Velocity configuration
|
* @return the deserialized Velocity configuration
|
||||||
* @throws IOException if we could not read from the {@code path}.
|
* @throws IOException if we could not read from the {@code path}.
|
||||||
@ -455,23 +473,25 @@ public class VelocityConfiguration implements ProxyConfig {
|
|||||||
configVersion = 1.0;
|
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;
|
boolean legacyConfig = configVersion < 2.0;
|
||||||
|
|
||||||
String forwardingSecretString;
|
String forwardingSecretString;
|
||||||
byte[] forwardingSecret;
|
byte[] forwardingSecret;
|
||||||
|
|
||||||
// Handle the previous (version 1.0) config
|
// 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
|
// There is duplicate/old code here in effort to make the future commit which abandons legacy
|
||||||
// easier to implement. All that would be required is removing the if statement here and keeping the contents
|
// config handling easier to implement. All that would be required is removing the if statement
|
||||||
// of the else block (with slight tidying).
|
// here and keeping the contents of the else block (with slight tidying).
|
||||||
if (legacyConfig) {
|
if (legacyConfig) {
|
||||||
logger.warn("You are currently using a deprecated configuration version. The \"forwarding-secret\""
|
logger.warn(
|
||||||
+ " parameter has been recognized as a security concern and has been removed in config version 2.0."
|
"You are currently using a deprecated configuration version. The \"forwarding-secret\""
|
||||||
+ " It's recommended you rename your current \"velocity.toml\" to something else to allow Velocity"
|
+ " parameter is a security hazard and was removed in config version 2.0."
|
||||||
+ " to generate a config file of the new version. You may then configure that file as you normally would."
|
+ " You should rename your current \"velocity.toml\" to something else to allow"
|
||||||
+ " The only differences are the config-version and \"forwarding-secret\" has been replaced"
|
+ " Velocity to generate a config file for the new version. You may then configure "
|
||||||
+ " by \"forwarding-secret-file\".");
|
+ " 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
|
// Default legacy handling
|
||||||
forwardingSecretString = System.getenv()
|
forwardingSecretString = System.getenv()
|
||||||
@ -493,7 +513,8 @@ public class VelocityConfiguration implements ProxyConfig {
|
|||||||
if (Files.isRegularFile(secretPath)) {
|
if (Files.isRegularFile(secretPath)) {
|
||||||
forwardingSecretString = String.join("", Files.readAllLines(secretPath));
|
forwardingSecretString = String.join("", Files.readAllLines(secretPath));
|
||||||
} else {
|
} 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 {
|
} else {
|
||||||
throw new RuntimeException("The forwarding-secret-file does not exist.");
|
throw new RuntimeException("The forwarding-secret-file does not exist.");
|
||||||
@ -505,7 +526,7 @@ public class VelocityConfiguration implements ProxyConfig {
|
|||||||
if (configVersion == 1.0 || configVersion == 2.0) {
|
if (configVersion == 1.0 || configVersion == 2.0) {
|
||||||
config.set("force-key-authentication", config.getOrElse("force-key-authentication", true));
|
config.set("force-key-authentication", config.getOrElse("force-key-authentication", true));
|
||||||
config.setComment("force-key-authentication",
|
config.setComment("force-key-authentication",
|
||||||
"Should the proxy enforce the new public key security standard? By default, this is on.");
|
"Should the proxy enforce the new public key security standard? By default, this is on.");
|
||||||
config.set("config-version", configVersion == 2.0 ? "2.5" : "1.5");
|
config.set("config-version", configVersion == 2.0 ? "2.5" : "1.5");
|
||||||
mustResave = true;
|
mustResave = true;
|
||||||
}
|
}
|
||||||
@ -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
|
* TOML requires keys to match a regex of {@code [A-Za-z0-9_-]} unless it is wrapped in quotes;
|
||||||
* quotes; however, the TOML parser returns the key with the quotes so we need to clean the
|
* however, the TOML parser returns the key with the quotes so we need to clean the server name
|
||||||
* server name before we pass it onto server registration to keep proper server name behavior.
|
* before we pass it onto server registration to keep proper server name behavior.
|
||||||
*
|
*
|
||||||
* @param name the server name to clean
|
* @param name the server name to clean
|
||||||
*
|
|
||||||
* @return the cleaned server name
|
* @return the cleaned server name
|
||||||
*/
|
*/
|
||||||
private String cleanServerName(String name) {
|
private String cleanServerName(String name) {
|
||||||
@ -705,19 +725,32 @@ public class VelocityConfiguration implements ProxyConfig {
|
|||||||
|
|
||||||
private static class Advanced {
|
private static class Advanced {
|
||||||
|
|
||||||
@Expose private int compressionThreshold = 256;
|
@Expose
|
||||||
@Expose private int compressionLevel = -1;
|
private int compressionThreshold = 256;
|
||||||
@Expose private int loginRatelimit = 3000;
|
@Expose
|
||||||
@Expose private int connectionTimeout = 5000;
|
private int compressionLevel = -1;
|
||||||
@Expose private int readTimeout = 30000;
|
@Expose
|
||||||
@Expose private boolean proxyProtocol = false;
|
private int loginRatelimit = 3000;
|
||||||
@Expose private boolean tcpFastOpen = false;
|
@Expose
|
||||||
@Expose private boolean bungeePluginMessageChannel = true;
|
private int connectionTimeout = 5000;
|
||||||
@Expose private boolean showPingRequests = false;
|
@Expose
|
||||||
@Expose private boolean failoverOnUnexpectedServerDisconnect = true;
|
private int readTimeout = 30000;
|
||||||
@Expose private boolean announceProxyCommands = true;
|
@Expose
|
||||||
@Expose private boolean logCommandExecutions = false;
|
private boolean proxyProtocol = false;
|
||||||
@Expose private boolean logPlayerConnections = true;
|
@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() {
|
private Advanced() {
|
||||||
}
|
}
|
||||||
@ -819,10 +852,14 @@ public class VelocityConfiguration implements ProxyConfig {
|
|||||||
|
|
||||||
private static class Query {
|
private static class Query {
|
||||||
|
|
||||||
@Expose private boolean queryEnabled = false;
|
@Expose
|
||||||
@Expose private int queryPort = 25577;
|
private boolean queryEnabled = false;
|
||||||
@Expose private String queryMap = "Velocity";
|
@Expose
|
||||||
@Expose private boolean showPlugins = false;
|
private int queryPort = 25577;
|
||||||
|
@Expose
|
||||||
|
private String queryMap = "Velocity";
|
||||||
|
@Expose
|
||||||
|
private boolean showPlugins = false;
|
||||||
|
|
||||||
private Query() {
|
private Query() {
|
||||||
}
|
}
|
||||||
@ -870,7 +907,11 @@ public class VelocityConfiguration implements ProxyConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration for metrics.
|
||||||
|
*/
|
||||||
public static class Metrics {
|
public static class Metrics {
|
||||||
|
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
|
||||||
private Metrics(CommentedConfig toml) {
|
private Metrics(CommentedConfig toml) {
|
||||||
|
@ -42,13 +42,13 @@ public interface ConnectionType {
|
|||||||
BackendConnectionPhase getInitialBackendPhase();
|
BackendConnectionPhase getInitialBackendPhase();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds properties to the {@link GameProfile} if required. If any properties
|
* Adds properties to the {@link GameProfile} if required. If any properties are added, the
|
||||||
* are added, the returned {@link GameProfile} will be a copy.
|
* returned {@link GameProfile} will be a copy.
|
||||||
*
|
*
|
||||||
* @param original The original {@link GameProfile}
|
* @param original The original {@link GameProfile}
|
||||||
* @param forwardingType The Velocity {@link PlayerInfoForwarding}
|
* @param forwardingType The Velocity {@link PlayerInfoForwarding}
|
||||||
* @return The {@link GameProfile} with the properties added in.
|
* @return The {@link GameProfile} with the properties added in.
|
||||||
*/
|
*/
|
||||||
GameProfile addGameProfileTokensIfRequired(GameProfile original,
|
GameProfile addGameProfileTokensIfRequired(GameProfile original,
|
||||||
PlayerInfoForwarding forwardingType);
|
PlayerInfoForwarding forwardingType);
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,8 @@ import com.velocitypowered.proxy.connection.util.ConnectionTypeImpl;
|
|||||||
public final class ConnectionTypes {
|
public final class ConnectionTypes {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that the connection has yet to reach the
|
* Indicates that the connection has yet to reach the point where we have a definitive answer as
|
||||||
* point where we have a definitive answer as to what
|
* to what type of connection we have.
|
||||||
* type of connection we have.
|
|
||||||
*/
|
*/
|
||||||
public static final ConnectionType UNDETERMINED =
|
public static final ConnectionType UNDETERMINED =
|
||||||
new ConnectionTypeImpl(ClientConnectionPhases.VANILLA, BackendConnectionPhases.UNKNOWN);
|
new ConnectionTypeImpl(ClientConnectionPhases.VANILLA, BackendConnectionPhases.UNKNOWN);
|
||||||
@ -46,8 +45,7 @@ public final class ConnectionTypes {
|
|||||||
LegacyForgeHandshakeClientPhase.NOT_STARTED, BackendConnectionPhases.UNKNOWN);
|
LegacyForgeHandshakeClientPhase.NOT_STARTED, BackendConnectionPhases.UNKNOWN);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that the connection is a 1.8-1.12 Forge
|
* Indicates that the connection is a 1.8-1.12 Forge connection.
|
||||||
* connection.
|
|
||||||
*/
|
*/
|
||||||
public static final ConnectionType LEGACY_FORGE = new LegacyForgeConnectionType();
|
public static final ConnectionType LEGACY_FORGE = new LegacyForgeConnectionType();
|
||||||
|
|
||||||
|
@ -87,8 +87,9 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a new {@link MinecraftConnection} instance.
|
* Initializes a new {@link MinecraftConnection} instance.
|
||||||
|
*
|
||||||
* @param channel the channel on the connection
|
* @param channel the channel on the connection
|
||||||
* @param server the Velocity instance
|
* @param server the Velocity instance
|
||||||
*/
|
*/
|
||||||
public MinecraftConnection(Channel channel, VelocityServer server) {
|
public MinecraftConnection(Channel channel, VelocityServer server) {
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
@ -211,6 +212,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes and immediately flushes a message to the connection.
|
* Writes and immediately flushes a message to the connection.
|
||||||
|
*
|
||||||
* @param msg the message to write
|
* @param msg the message to write
|
||||||
*/
|
*/
|
||||||
public void write(Object msg) {
|
public void write(Object msg) {
|
||||||
@ -223,6 +225,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes, but does not flush, a message to the connection.
|
* Writes, but does not flush, a message to the connection.
|
||||||
|
*
|
||||||
* @param msg the message to write
|
* @param msg the message to write
|
||||||
*/
|
*/
|
||||||
public void delayedWrite(Object msg) {
|
public void delayedWrite(Object msg) {
|
||||||
@ -244,6 +247,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the connection after writing the {@code msg}.
|
* Closes the connection after writing the {@code msg}.
|
||||||
|
*
|
||||||
* @param msg the message to write
|
* @param msg the message to write
|
||||||
*/
|
*/
|
||||||
public void closeWith(Object msg) {
|
public void closeWith(Object msg) {
|
||||||
@ -273,6 +277,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Immediately closes the connection.
|
* Immediately closes the connection.
|
||||||
|
*
|
||||||
* @param markKnown whether the disconnection is known
|
* @param markKnown whether the disconnection is known
|
||||||
*/
|
*/
|
||||||
public void close(boolean markKnown) {
|
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.
|
* Determines whether or not the channel should continue reading data automaticaly.
|
||||||
|
*
|
||||||
* @param autoReading whether or not we should read data automatically
|
* @param autoReading whether or not we should read data automatically
|
||||||
*/
|
*/
|
||||||
public void setAutoReading(boolean autoReading) {
|
public void setAutoReading(boolean autoReading) {
|
||||||
@ -337,6 +343,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the state of the Minecraft connection.
|
* Changes the state of the Minecraft connection.
|
||||||
|
*
|
||||||
* @param state the new state
|
* @param state the new state
|
||||||
*/
|
*/
|
||||||
public void setState(StateRegistry state) {
|
public void setState(StateRegistry state) {
|
||||||
@ -353,6 +360,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the new protocol version for the connection.
|
* Sets the new protocol version for the connection.
|
||||||
|
*
|
||||||
* @param protocolVersion the protocol version to use
|
* @param protocolVersion the protocol version to use
|
||||||
*/
|
*/
|
||||||
public void setProtocolVersion(ProtocolVersion protocolVersion) {
|
public void setProtocolVersion(ProtocolVersion protocolVersion) {
|
||||||
@ -380,6 +388,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the session handler for this connection.
|
* Sets the session handler for this connection.
|
||||||
|
*
|
||||||
* @param sessionHandler the handler to use
|
* @param sessionHandler the handler to use
|
||||||
*/
|
*/
|
||||||
public void setSessionHandler(MinecraftSessionHandler sessionHandler) {
|
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
|
* Sets the compression threshold on the connection. You are responsible for sending
|
||||||
* {@link com.velocitypowered.proxy.protocol.packet.SetCompression} beforehand.
|
* {@link com.velocitypowered.proxy.protocol.packet.SetCompression} beforehand.
|
||||||
|
*
|
||||||
* @param threshold the compression threshold to use
|
* @param threshold the compression threshold to use
|
||||||
*/
|
*/
|
||||||
public void setCompressionThreshold(int threshold) {
|
public void setCompressionThreshold(int threshold) {
|
||||||
@ -440,6 +450,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables encryption on the connection.
|
* Enables encryption on the connection.
|
||||||
|
*
|
||||||
* @param secret the secret key negotiated between the client and the server
|
* @param secret the secret key negotiated between the client and the server
|
||||||
* @throws GeneralSecurityException if encryption can't be enabled
|
* @throws GeneralSecurityException if encryption can't be enabled
|
||||||
*/
|
*/
|
||||||
@ -471,6 +482,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the detected {@link ConnectionType}.
|
* Gets the detected {@link ConnectionType}.
|
||||||
|
*
|
||||||
* @return The {@link ConnectionType}
|
* @return The {@link ConnectionType}
|
||||||
*/
|
*/
|
||||||
public ConnectionType getType() {
|
public ConnectionType getType() {
|
||||||
@ -479,6 +491,7 @@ public class MinecraftConnection extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the detected {@link ConnectionType}.
|
* Sets the detected {@link ConnectionType}.
|
||||||
|
*
|
||||||
* @param connectionType The {@link ConnectionType}
|
* @param connectionType The {@link ConnectionType}
|
||||||
*/
|
*/
|
||||||
public void setType(ConnectionType connectionType) {
|
public void setType(ConnectionType connectionType) {
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
package com.velocitypowered.proxy.connection;
|
package com.velocitypowered.proxy.connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marker interface for something that can be associated with a {@link MinecraftConnection}.
|
||||||
|
*/
|
||||||
public interface MinecraftConnectionAssociation {
|
public interface MinecraftConnectionAssociation {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,9 @@ import com.velocitypowered.proxy.protocol.packet.title.TitleTextPacket;
|
|||||||
import com.velocitypowered.proxy.protocol.packet.title.TitleTimesPacket;
|
import com.velocitypowered.proxy.protocol.packet.title.TitleTimesPacket;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for dispatching received Minecraft packets.
|
||||||
|
*/
|
||||||
public interface MinecraftSessionHandler {
|
public interface MinecraftSessionHandler {
|
||||||
|
|
||||||
default boolean beforeHandle() {
|
default boolean beforeHandle() {
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
|
|
||||||
package com.velocitypowered.proxy.connection;
|
package com.velocitypowered.proxy.connection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Various useful constants.
|
||||||
|
*/
|
||||||
public class VelocityConstants {
|
public class VelocityConstants {
|
||||||
|
|
||||||
private VelocityConstants() {
|
private VelocityConstants() {
|
||||||
|
Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden Mehr anzeigen
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren